原创文章,转载请注明出处,谢谢!
作者:清林,博客名:飞空静渡
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
在C++ 中会经常使用数组和指针,并且有时会把指针当数组使用或者反过来把数组当指针用,但有些人并不知道数组和指针有哪些相同点和不同点,今天就简略说一下。
下面我们看一下一个函数的代码:
void fun()
{
int i=2;
int *pI = &i;
int a[5];
int * const pA = a;
}
首先,我们看下数组a ,其实数组a 实际上是一个指针,它引用的是数组中的第一个元素。
那么数组和指针有哪些差异呢?
第一个差异就是大家都知道的大小问题。即sizeof(a) 和sizeof (pA) 。sizeof(a) 是整个数组的大小,而sizeof(pA) 是指针的大小。
另一个区别是很多人都没有意识到的一个区别,那就是数组和指针的地址的问题。
我们先看指针,我们都知道,指针是有地址的,它的这个地址里的内容是一个地址,而这个地址是某个区域的内容。
数组呢,它和指针不同,它没有地址,或者说,它的地址就是数组的这块区域的首地址。
这里说的有些坳口,我们看下图吧,图片说明问题直接一些。
我们看下pI 指针:
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
我们看上图,指针pI 是有地址的,它的地址是0x00000014 ,这个地址里面的内容是一个地址0x00000010 ,而0x00000010 这个地址是变量i 的地址,它里面的内容是整数值2 。
下面我们看下数组a 的情况:
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
我们看上图,数组a 的这个名字表示的就是数组的这块区域的地址0x00000018 。
我们再和pA 指针对比一下:
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
pA 是有地址的,它的地址是 0x00000027 ,它里面的内容是0x00000018 ,0x00000018 是数组a 的首地址。
我们对比一下pA 和a 我们就可以知道,pA 是有地址的,而a 是没有地址的,说a 有地址是说a 代表的是数组这块区域,是数组的首地址。
a 的长度的计算是这样的:
const int aLen = sizeof(a)/sizeof(a[0]); // aLen = 5
那么既然a 代表的是a 数组的第一个元素的指针,那么&a 又是什么呢? 我们看下下面的表达式:
int (*pAA)[5] = &a;
&a 表示的是整个数组的地址,而不是第一个元素的地址,虽然它们的值是一样的。
最后,我们看下多维数组的情况。
int aa[5][6];
那么aa 的长度是多少,aa 的长度计算可以是这样:
const int aaLen = sizeof(aa)/sizeof(aa[0]); // aaLen = 5
那么我们怎么看待多维数组?
我们可以记住这一条:多维数组的第一个元素的类型是数组,而不是基本类型。
我们看到aa 的意思是指向包含6 个整形数的数组的第一个元素的指针,而不是指向整形数的指针。
最后,我们以一个程序来说明以上的问题:
#include <stdio.h> int main(int argc, char *argv[]) { int i = 2; int *pI = &i; int a[5] = { 3, 2, 5, 120, 60}; int *pA = a; int (*ppA)[5] = &a; printf("a = %p/n", a); printf("&a = %p/n", &a); printf("pA = %p/n", pA); printf("ppA = %p/n", ppA); printf("sizeof(ppA) = %d/n", sizeof(ppA)); printf("++pA = %p/n", ++pA); printf("++ppA = %p/n", ++ppA); pA=a+1; printf("a+1 = %p/n", pA); printf("sizeof(a) = %d/n", sizeof(a)); int aa[5][6]; int (*paa)[6] = aa; int (*ppaa)[5][6] = &aa; printf("sizeof(aa) = %d/n", sizeof(aa)); printf("aa = %p/n", aa); printf("&aa = %p/n", &aa); printf("++paa = %p/n", ++paa); paa = aa + 1; printf("aa+1 = %p/n", paa); printf("ppaa = %p/n", ppaa); printf("++ppaa = %p/n", ++ppaa); return 0; }
<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } -->
编译:g++ -g -Wall main.cpp
运行:./a.out
输出:
a = 0xbf9820a4 // a的地址和&a的地址是一样的 &a = 0xbf9820a4 pA = 0xbf9820a4 ppA = 0xbf9820a4 sizeof(ppA) = 4 ++pA = 0xbf9820a8 // 只是指针增加一个位置即加4 ++ppA = 0xbf9820b8 // 这里增加了整个数组的长度20 a+1 = 0xbf9820a8 // 数组的第一个元素增加只是指向到数组第二个元素 sizeof(a) = 20 sizeof(aa) = 120 aa = 0xbf98202c // aa的地址和&aa的地址是一样的 &aa = 0xbf98202c ++paa = 0xbf982044 // paa增加的是数组第一个元素的长度,0x2c + 24 = 0x44 aa+1 = 0xbf982044 ppaa = 0xbf98202c ++ppaa = 0xbf9820a4 // ppaa一次增加整个aa数组的长度 0x2c + 120 = 0xa4
最后这篇文章的pdf下载:
C++之数组与指针的异同.pdf