sizeof一维数组和二维数组
1. sizeof的说明
sizeof在C语言里面属于操作符,不属于函数,和变量的++,--属于同样的操作符。sizeof后面的括号里面,可以放类型名,数组名等内存大小确定的类型,不能计算函数名,可变数组的内存大小等
2. sizeof计算一维数组
首先,看如下代码:
#include<stdio.h>
int main()
{
    int a[]={1,2,3,4};
    /*打印内存地址*/
    printf("0x%x, 0x%x, 0x%x, 0x%x\n",a,&a,a+0,&a[0]);
    /*计算内存大小*/
    printf("%d, %d, %d, %d\n",sizeof(a),sizeof(&a),sizeof(a+0),sizeof(&a[0]));
    return 0;
}
我们知道,a代表数组的起始地址,也就是数组a的0号位元素的内存起始地址,a+0代表指针a偏移0,因此指向的还是数组的起始地址,所以a=&a=a+0=&a[0],虽然他们的数值相等,都表示数组起始地址,但他们的意义不同。
    数组名a代表数组起始地址,如果它参与指针偏移运算,那么它就代表一个指向某一位元素的指针(看本文章最后的总结,数组名参与偏移运算,退化为指针),例如a+0代表指向数组0号位元素的指针,因此它的内存大小为4。数组元素a[0]和*(a+0)表示的意义相同,访
问a[0],就是从数组首地址开始偏移0,然后再访问内存中的数值,所以,&a[0]就是&(*(a+0)),&和*抵消,为a+0,代表指向数组0号位元素的指针,内存大小为4。
    经过上面的分析,就可以理解代码的运行结果,已经在windows XP,vc6.0下编译链接过:
3. sizeof计算二维数组
首先,看如下代码:
#include<stdio.h>
#include<stdlib.h>
int main()
{
    int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
    int n=sizeof(a[0][0]);
   
    printf("a=0x%x,*a=0x%x\n",a,*a);
    printf("a size=%d,*a size=%d\n",sizeof(a),sizeof(*a));
    printf("-------------------------------------------\n");
    printf("a[0]=0x%x,*(a+0)=0x%x\n",a[0],*(a+0));
    printf("a[0] size=%d,*(a+0)=%d\n",sizeof(a[0]),sizeof(*(a+0)));
    printf("-------------------------------------------\n");
    printf("&a[0]=0x%x,&a[0][0]=0x%x\n",&a[0],&a[0][0]);
    printf("&a[0] size=%d,&a[0][0] size=%d\n",sizeof(&a[0]),sizeof(&a[0][0]));
    printf("-------------------------------------------\n");
    printf("a[1]=0x%x,a+1=0x%x\n",a[1],a+1);
    printf("a[1] size=%d,a+1=%d\n",sizeof(a[1]),sizeof(a+1));
    printf("-------------------------------------------\n");
    printf("&a[1][0]=0x%x,*(a+1)+0=0x%x\n",&a[1][0],*(a+1)+0);
    printf("&a[1][0] size=%d,*(a+1)+0 size=%d\n",sizeof(&a[1][0]),sizeof(*(a+1)+0));
    printf("-------------------------------------------\n");
    printf("a[2]=0x%x,*(a+2)=0x%x\n",a[2],*(a+2));
    printf("a[2] size=%d,*(a+2) size=%d\n",sizeof(a[2]),sizeof(*(a+2)));
    printf("-------------------------------------------\n");
    printf("&a[2]=0x%x,a+2=0x%x\n",&a[2],a+2);
    printf("&a[2] size=%d,a+2 size=%d\n",sizeof(&a[2]),sizeof(a+2));
    printf("-------------------------------------------\n");
    printf("a[1][0]=0x%x,*(*(a+1)+0)=0x%x\n",a[1][0],*(*(a+1)+0));
    printf("a[1][0] size=%d,*(*(a+1)+0) size=%d\n",sizeof(a[1][0]),sizeof(*(*(a+1)+0)));
    printf("-------------------------------------------\n");
    return 0;
   
}
以上代码,包含了用sizeof计算各种各样二维数组相关的内存大小,大家不要感到疑惑,读完下面的分析,我们就明白了。
a代表了二维数组的起始地址,&a在内存上和a表示的是同一个地方,还是二维数组的起始
地址,因此用sizeof计算它们的值,就是整个二维数组所占用的内存空间。那么,*a,a[0],a+0,&a[0],&a[0][0],*(a+0),这些都代表什么呢?我们可以用下面这个图来描述二维数组a:
printf("a size=%d,*a size=%d\n",sizeof(a),sizeof(*a));
这句代码中,sizeof(a)表示整个二维数组的大小,*a表示*(a+0),所以,*a表示一维数组{1,3,5,7}的首地址,因此sizeof(*a)是4*sizeof(int)为16。
printf("a[0] size=%d,*(a+0)=%d\n",sizeof(a[0]),sizeof(*(a+0)));
a[0]也就是*(a+0),和*a一样,也是指向一维数组{1,3,5,7}的首地址,因此a[0],*(a+0)用sizeof计算内存大小,就是4*sizeof(int)为16
printf("&a[0] size=%d,&a[0][0] size=%d\n",sizeof(&a[0]),sizeof(&a[0][0]));
&a[0]就是&(*(a+0)),&和*互相抵消,因此相当于a+0,数组名参与了指针偏移运算,因此sizeof(&a[0])的大小为指针的内存大小,是4字节。&a[0][0]就是&(*(*(a+0)+0)),&和*抵消以后,为*(a+0)+0,*(a+0)代表一维数组{1,3,5,7}的首地址,因此*(a+0)+0表示数组首地址参与偏移操作,成为指向数组{1,3,5,7}0号位元素1的指针,sizeof(&a[0][0])的大小为4
剩下的printf的打印相信大家就能理解了,运行结果如下:
我们总结为一句话,不论是一维数组,还是二维数组,如果直接sizeof数组名,那么大小为整个数组所占用的内存空间,如果计算类似a+0,a+1等数组名进行了偏移运算,那么它就代表指向某个元素的指针,sizeof计算的话,其大小为指针的内存大小,如下:sizeof 指针
#include<stdio.h>
int main()
{
    int a[]={1,2,3,4};
    int b[][4]={1,3,5,7,9};
    printf("%d, %d, %d, %d\n",sizeof(a),sizeof(a+1),sizeof(b),sizeof(b+1));
    return 0;
}
运行结果如下:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。