Bootstrap

不使用sizeof求得数组长度

在c语言中,经常使用sizeof取得数组的长度。

int len=sizeof(arr)/sizeof(arr[0])

其实还有一个技巧取得数组的长度。再次之前,我们还是先了解一下两个地址(或者指针)相减是一个什么样的状况吧。

先定义一个int类型数组和两指向相邻指针:

int a[5]={0};
int* p1=&a[1];
int* p2=&a[2];

那么&a[2]-&a[1]即p2-p1等于多少呢?也许你一眼就能看出来p2-p1=1,的确。可是把p1和p2的值输出出来,也许你就会感到困惑:

printf("%p,%p\n",p1,p2);//%p用于输出地址格式

output:

0028fe9c  0028fea0

也就是说p1的值为0028fe9c,p2的值为0028fea0,p1和p2相差4个字节。可为什么p2-p1=1呢?这不是矛盾了嘛~~~

其实没有什么矛盾的,4是你自己算出来的地址差值,1是计算机计算出来的指针差值。指针差值是这样算出来的:

首先,计算机跟人类一样,算出地址差值4.

然后,根据指针类型确定元素所占内存大小,这里int占4byte

那么,p2-p1=4/4=1.

==============================================================================================

现在可以说说怎么不用sizeof求出数组的长度了。

首先,取一个指针a,我们知道数组的名字就是一个指针。

再取一个指针的指针&a,&a指向a,a又指向数组a[5],所以&a所指元素占内存大小20(4*5),所以,&a+1与&a的地址差值为20.

这时,&a的值和a的值是一样的,都是a[0]的地址。可以用下面两行代码验证一下:

printf("%p,%p\n",&a,a);

也就是说&a+1与a的地址差值就是20.将&a+1换成与a同级指针就是*(&a+1),然后就可以相减了:

*(&a+1)-a=20/4=5,哈哈,数组的长度。

验证:

printf("len=%d",*(&a+1)-a);

所以,求一个数组的长度除了使用sizeof之外,我们还可选择这个方法。

这只是另外一个技巧而已,并不代表我推荐使用这个方法。不过我们也能看出C语言之能力,是其他高级语言所不及的。



;