首页 > 代码库 > 【C语言学习】指针再学习(二)之数组的指针

【C语言学习】指针再学习(二)之数组的指针

★一维数组

 一个整型数据为4个字节。4个字节就是32位,即可以表示2^32个数字

 

在程序中定义一个数组a[5] = {1,2,3,4,5};

那么a[0]的地址就是0x00000000,数组名a是数组首元素的地址a的地址也是0x00000000a+1则表示的地址是0x00000004,而不是0x00000001。因为1这个值,根据前面的指针a所指向的类型的长度来调整自己的长度。也就是说如果a是指向整型的指针,那么后面加的1也表示4个字节,如果a是指向字符型的指针,那么后面加的1表示1个字节。

★数组的指针

定义一个二维数组a[3][5] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

那么的类型是“指向包含5个整型元素的数组的指针”,也就是指向上面数组的第一行,,那么表达式a + 1,它的类型也是“指向包含5个整型元素的数组的指针”,它指向的是第二行,这就是因为1,它就是根据前面a的类型的长度来调整。可以将二维数组看做一维数组,只有三个元素,分别是:a[0]、a[1]、a[2]。只不过,这三个元素不是一个值,而是一个数组。数组名a指向的是a[0](即指向的是一个包含5个元素数组)a+1指向的是a[1]。又因为*(a + 0)等价于a[0](找了好多本书一直没有弄明白为什么。谭浩强书上这样解释:*(a + 0)并不是a+0单元的内容,因为a+0并不是一个变量的存储单元。*(a+0)就是a[0],而a[0]是一维数组名,所以也是地址,指向a[0][0]),a[0]是一维数组(a[0]中包含的5个元素)的首元素的地址,就是a[0][0]的地址。因此a[0]+1就是a[0][1]的地址,*(a[0] +1)就是a[0][1]。所以将a[0][1]展开就是*(*(a + 0)+1)。

a表示的就是一个指向整型数组的指针,它的声明: int *p[5];这表示的就是p是一个指针,它指向一个整型元素个数为5的数组。

★int *ptr=(int *)(&a+1)问题

在网上有这样一道面试题目

main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
它的结果是2,5

对于第一个输出应该很简单,基本上没有什么疑问,关键就是第二个输出,它为什么会输出5呢?这里面的难点就是对&a的理解。

这里面就涉及到数组的指针问题。a是一维数组的首元素的地址,&a的含义(*(a+0)<==> a[0]):就相当于上面二维数组中对a[0]取地址,得到的是二维数组的a,就是一个指向有5个元素的数组的指针。那么&a+1,指向的是下一个5个元素的数组,那么指针ptr指向的就是a[4]后面的内存单元,而ptr-1就是指向的是a[4],*(ptr-1)就是a[4]的值。