首先要记住,数组名代表数组首元素的地址,数组的地址需要用取地址&才能得到,两者的地址值相同,意义不同,内存大小也不同。
数组名大多数情况下可以看做常量指针,表达式中只能做为右值使用(不能数组名给数组名赋值)。但在有些场合用不能看做常量指针,如数组名做为sizeof的参数时,表示数组的大小,而sizeof指针变量名始终大小为4。取&时,数组名表示整个数组的地址,大小等于数组首元素地址,指针名取&时表示指针变量本身所占用的地址。
C的指针的算术运算只局限于两种形式。
1)指针与整数的运算如int p,p+n;就是(unsignde int)p+nsizeof(*p)。
2)指针与指针的运算只支持减法,参与指针运算的类型必须相同如int *p1;int *p2;p1-p2=((unsignde int)p1-(unsignde int)p2)/sizeof(int)。如果两个指针所指向的不是同一个数组中的元素,那么它们之间相减的结果是未定义的。程序员无从知道两个数组在内存中的相对位置,如果不知道这一点,两个指针之间的距离就毫无意义。
如果是同一个数组中那就是下标差。
关系运算: < <= > >= 不过前提是它们都指向同一个数组中的元素。根据你所使用的操作符,比较表达式将告诉你哪个指针指向数组中更前或更后的元素。标准并未定义如果两个任意的指针进行比较会产生什么结果。
任意两个指针间的比较运算(==、!=)无限制,但前提是必须类型相同。
下标形式与指针形式的转换:
a[n]<->(a+n)<->(n+a)<->n[a]
数组做为函数参数时,编译器将其编译成对应的指针
void f(int a[]);<->void f(int *a);
但是绝对不能理解成数组和指针是相同的,例如
inta[]={1,2,3,4,5};
#include <stdio.h>
int main()
{
extern int* a;
printf("&a = %p\n", &a);
printf("a = %p\n", a);
printf("*a = %d\n", *a);
return 0;
}
上述函数第一个表示变量a的地址,没有问题等于数组地址;
第二个是变量a表示的内容转换成地址输出,a的内容占据4个字节,就是1,转换为地址就是0x1;如果是数组的话a是首元素地址,也就是1所占用的地址;
第三个是取地址0x1的内存内容,就会段错误。如果是数组的话就是数组首元素的值。