1.声明
注意下列声明的区别:
extern int *x;
extern int y[ ];
第一条语句声明x是个int型的指针;第二条语句声明y是个int型的数组,长度尚未确定,其存储在别处定义。
因为定义和声明是有区别的,C中的定义是指给对象分配存储空间,而声明只是描述其他地方定义的对象(主要是描述类型和名字)。
2.数组与指针的区别
2.1.数组和指针是如何访问的
数组:
char a[9]=”abcdefgh”;
c=a[i];
在符号表中数组a具有一个地址,假设为9980,;
运行时步骤1:取i的值,将它与9980相加。
运行时步骤2:取地址(9980+i)的内容。
指针:
char *p=”abcdefgh”;
c=p[i];
在符号表中指针p有一个地址,假设为4624
运行时步骤1:取地址4624的内容,假设为5081。
运行时步骤2:取得i的值,乘以sizeof(char),并将它与5081相加。
运行时步骤3:取地址5081+i*sizeof(char)的内容。
从以上的比较就可以看出,数组名表示地址而指针表示地址的地址!!所以如果出现以下情况:
文件1:
char a[9];
文件2:
extern char *a;
此时如果操作a[i],就会按指针来处理,取a中的元素为地址,让后取地址int(‘a’)的值为偏移起始地址,此时程序将会崩溃!!崩溃还是好的,不崩溃麻烦就更大了。
2.2.关于字符串常量
定义指针时,编译器并不为指针所指向的对象分配空间,它只是分配指针本身的空间,除非在定义时同时赋给指针一个字符串常量进行初始化。如下:
char *p = “Hello World!”;
注意只有对字符串常量才如此,其他类型不可以。
float *p = 3.14; //错误!无法通过编译
在ANSI C中,初始化指针时所创建的字符串常量被定义为只读。不可以试图通过指针修改这个字符串的值。
数组也可以用字符串常量进行初始化,但是这时候数组是存储在栈上的,所以数组中的字符串常量是可以修改的。
3.什么时候指针和数组是相同的
规则1:“表达式中的数组名”就是指针
当然这个前提是如果声明为一个指针,那么这个指针存储的必须是数组的地址。
规则2:C语言把数组下标作为指针的偏移量
数组下标是定义在指针基础上的,所以优化器常常可以把它转化为一个更有效率的指针表达式,并生成相同的机器指令。
规则3:作为函数的参数的时候,数组名自动退化为指针。