数组与指针 1.数组和指针的访问 1.1数组元素的访问 1.4总结 2.数组和指针的区别

数组与指针
1.数组和指针的访问
1.1数组元素的访问
1.4总结
2.数组和指针的区别

1.1数组元素的访问

例子:
char arr[9]="abcdefgh"
  ......
c = arr[3];//直接访问
访问过程:

       编译符号表具有一个地址9980,也就是数组首地址

       运行时步骤1:取地址9983内容(从arr代表的地址开始,前进3步,每步一个字符)

数组与指针
1.数组和指针的访问
1.1数组元素的访问
1.4总结
2.数组和指针的区别
                                       图1 数组的访问

1.2指针的访问

例子:
char *p =arr;//p是一个指针,指向的对象是一个字符
char c = *p;//间接访问

访问过程:

       编译器符号表p,它的地址4624   

       运行时步骤1:取地址4624的内容,就是9980;

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

数组与指针
1.数组和指针的访问
1.1数组元素的访问
1.4总结
2.数组和指针的区别

                                                                                        图2 指针访问

为了取得这个字符,必须得到p的内容,把它作为字符的地址并从这个地址中取得这个字符,相比数组的访问指针的访问更加灵活,但多了一次额外的提取

1.3定义为指针,以数组方式引用

例子:

char *p = "abcdefgh";//以指针方式定义数组
 ...
c = p[i];//访问数组元素

访问过程:

编译器符号表具有p,地址为4624;

运行时步骤1:取地址4624的内容,即9980;

        运行时步骤2:取得i值,并将它与9980相加;

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

数组与指针
1.数组和指针的访问
1.1数组元素的访问
1.4总结
2.数组和指针的区别

图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.数组和指针的区别

                                                                    表一      数组和指针区别

数组与指针
1.数组和指针的访问
1.1数组元素的访问
1.4总结
2.数组和指针的区别

2.1字符常量的初始化

       数组和指针都可以在它们的定义中用字符常量进行初始话,但它们的底层机制不同

char *ptr = "Happy!";//ok,为指针本身和字符常量分配空间

int *p = 4;//error,仅对字符常量有效

在ANSI C中,初始化指针时所创建的字符串常量被定义为只读,如果试图通过指针修改这个字符常量的值,程序会出现未定义的行为。

char str[] = "Hello World!";//ok

strncpy(str,"black",5);//ok
与指针相反,由字符常量初始化的数组是可以修改的