《C专家编程》笔记(四)——数组和指针并不相同

1. 区别定义和声明

定义:只能出现在一个地方。确定对象的类型并分配内存,用于创建新的对象。例如int my_array[100];

声明:可以多次出现。描述对象的类型,用于指代其他地方定义的对象(例如在其他文件里)。例如:extern int my_array[];

2. 指针和数组的访问机制

数组:

char a[9] = "abcdefgh";

c = a[i];

编译器符号表具有一个地址9980。(可以认为在程序编译的时候,所有a的相关操作都被替换为地址9980相关的操作。

运行时步骤1:取i的值,将它与9980相加。

运行时步骤2:取地址(9980+i)的内容。

指针:

char *p;

...

c = *p;

编译器符号表有一个符号p,它的地址为4624。

运行时步骤1:取地址4624的内容,就是‘5081’。

运行时步骤2:取地址5081的内容。

3. 定义为指针,但以数组方式引用,会发生什么

char *p = "abcdefgh";

c = p[i];

1. 编译器遇到P[i]这句话,查找符号表,将符号p解释为指针,所以先去取符号p的地址(例如4624)对应的内容(例如‘5081’),也就是取就是存储在p的指针。

2. 编译器遇到[i],则取i的值,将i的值与5801相加。

3. 取地址(5081+i)的内容。

4. 定义为数组,但以指针方式引用,会发生什么

// 别处定义char a[] = "abcdefgh";

extern char *a;

c = a[i];// 等同于操作c = *(a + i);

1. 编译器遇到符号a,根据a的声明,将a解释成一个指针(其实a是数组)。则按照指针的步骤,先去取符号a的地址对应的内容,但是a的地址对应的内容是字符,例如'a''b''c''d'(这里指针看成32位)。

2. 编译器遇到[i],则取i的值,将i的值与'a''b''c''d'的二进制值相加。

3. 取上述地址的值,显然是错误的。

 

posted @ 2014-11-26 23:28  nipan  阅读(235)  评论(0编辑  收藏  举报