1.数组和指针的访问
1.1数组元素的访问
例子:
访问过程:char arr[9]="abcdefgh" ...... c = arr[3];//直接访问
编译符号表具有一个地址9980,也就是数组首地址
运行时步骤1:取地址9983内容(从arr代表的地址开始,前进3步,每步一个字符)
图1 数组的访问
1.2指针的访问
例子:
char *p =arr;//p是一个指针,指向的对象是一个字符 char c = *p;//间接访问
访问过程:
编译器符号表p,它的地址4624
运行时步骤1:取地址4624的内容,就是9980;
运行时步骤2:取地址9980的内容。
图2 指针访问
为了取得这个字符,必须得到p的内容,把它作为字符的地址并从这个地址中取得这个字符,相比数组的访问指针的访问更加灵活,但多了一次额外的提取
1.3定义为指针,以数组方式引用
例子:
访问过程:
char *p = "abcdefgh";//以指针方式定义数组 ... c = p[i];//访问数组元素
编译器符号表具有p,地址为4624;
运行时步骤1:取地址4624的内容,即9980;
运行时步骤2:取得i值,并将它与9980相加;
运行时步骤3:取地址(9980+i)的内容。
图3 对指针进行下标引用
此种情况编译器的做法:
1.取得符号表p的地址,提取存于此处的指针;
2.把下标所表示的偏移量与指针的值相加,产生一个地址;
3.访问上面这个地址,取得字符。
1.4总结
char p[]="abcdefgh";//定义在 F1.c extern char *p;//error,声明指针形式在F2.c extern char p[];//ok,声明数组形式声明在F2.c要使得声明与定义匹配
2.数组和指针的区别
表一 数组和指针区别
2.1字符常量的初始化
数组和指针都可以在它们的定义中用字符常量进行初始话,但它们的底层机制不同
char *ptr = "Happy!";//ok,为指针本身和字符常量分配空间 int *p = 4;//error,仅对字符常量有效在ANSI C中,初始化指针时所创建的字符串常量被定义为只读,如果试图通过指针修改这个字符常量的值,程序会出现未定义的行为。
char str[] = "Hello World!";//ok strncpy(str,"black",5);//ok与指针相反,由字符常量初始化的数组是可以修改的