3.4.数组和指针的关联
2016-06-17 21:16
459 查看
1.从内存和编译器角度来理解数组
1.1内存角度和编译器角度
(1)定义五个变量,普通定义int a,b,c,d,e;和数组定义int a[5];1.都是定义了五个变量,第一种方法定义的变量的内存地址不一定是连续的,第二种方法定义的元素一定是地址连续的。
2.对于编译器来说,定义数组和定义其他变量的本质都是一样的。
1.2来理解一些符号 a,a[0],&a,&a[0]分别和左值右值的关系
分析:1.(1)a做左值。数组名a做左值时表示数组的所有地址,比如:int a[5];数组名a做左值时表示的就是4*5个内存地址。我们在操作数组的时候只能操作其中的一个元素,不能整体操作。比如 a = {1,2,3,4,5};整体操作是不行的。需要注意的是:它和数组定义初始化int a[5]={1,2,3,4,5}是不同的。
(2)a做右值。数组名a做右值时,表示数组首元素的首地址,第一个元素可能占好多地址,在这里只表示第一个字节的地址。其类型是数组元素的类型的指针。而非数组指针。
2.(1)a[0]做左值,表示第一个元素的地址,当a[0] = 1;时,是把1写入到元素a[0]对应的那个内存地址中去。
(2)a[0]做右值时,test = a[0]; 表示把a[0]的值写入test的地址中去。
3.(1)&a不能做左值,a的地址是随机分配的,但是一旦分配之后,在程序执行的时候,a的地址已经确定,所以成了常量,常量不能做左值。
(2)&a做右值,表示,整个数组的首地址。也就是一个指向数组的指针,所以&a做右值时的类型是数组指针。也就是int (*)[]类型。
4.(1)&a[0]不能做左值,道理和&a一样,变成了常量。
(2)&a[0]做右值时,表示数组首元素的首地址。
总结:
(1)a,&a,&a[0]在数值上是相等的,但是类型和含义完全不同。
(2)a和&a做右值的区别。a代表数组首元素的首地址,类型是int* 。&a表示数组的首地址,类型是int(*)[];
(3)a和&a[0]做右值时都是表示数组首元素的首地址。
2.从数组和指针的角度理解数组
1.通过代码看数组和指针的关系#include<stdio.h> void main(void) { int a[5] = {1,2,3,4,5}; int *p = a; //将数组名a的值赋值给指针p //数组名a做左值时表示数组首元素的首地址类型是int* //所以这里 a 和 p 类型一致 //通过数组下标访问元素 printf("通过数组下标方式:第2个元素是 %d\n",a[1]); //通过指针访问数组元素 printf("通过指针方式:第2个元素是 %d\n",*(p+1)); }
分析:
(1)数组名a做右值时表示数组首元素的首地址,当p = a后,p也保存了数组首元素的首地址,当p+1时,p+1就指向了数组的第二个元素的首地址,以此类推。这里注意一点,p只是保留了首地址(一个字节),而第一个元素是int类型,占4个字节,这时候就靠指针p的数据类型的作用了,一看p是int*类型的指针,自动会根据p保留的第一个字节的地址去补齐剩下的那3个字节的地址,当找到4个字节地址后再去读取该值。
(1.1)比如 int a[5];int * p = a;当p自增1时,其实是自增(1+sizeof(指针类型)),举例:当int * p;p实际上是自增4个字节,char * p;p实际上是自增1个字节。
(1.2)指针在进行运算的时候,指针自增多少关键看指针类型。这时候再来看&a和a。&a做右值是数组指针,当&a自增时,实际上是增加了一个数组sizeof(int) * 5= 20个字节。而 a 自增实际上是自增了一个sizeof(int)大小的字节。
(3)看上面的代码,int * p = a; 若是改成int* p=&a;会怎样?一步一步分析:&a做右值时,代表数组的首地址,其数据类型是int (*)[5],这就得出了结果,&a和p类型不符,编译器报错。
(4)再来回顾一下,数组元素地址是连续的。所以指针访问数组才能自增去寻址。
总结
(1)a,a[0],&a,&a[0],做左值和做右值的区别
(2)指针自增的含义
(3)指针类型的含义
(4)数组和指针的相似处
下次说说指针和类型转换的内容
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- Lua和C语言的交互详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- C语言练习题:自由落体的小球简单实例
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- C语言中进制知识汇总
- C语言判断一个数是否是2的幂次方或4的幂次方
- C语言中计算正弦的相关函数总结
- 使用C语言详解霍夫曼树数据结构
- C语言实现选择排序、冒泡排序和快速排序的代码示例