对于一维数组我们知道取地址是取首元素的地址,二维数组呢,地址是取第一行的地址,sizeof(数组名)这里计算的就是整个数组的大小,&数组名 表示整个数组,取出的是整个数组的地址,显示的是数组的首元素
记住这些前提后,我们看一下下面的题目会多少呢?
一维数组计算大小题目
第一组题目
#include <stdio.h>
int main()
{int a[] = { 1,2,3,4 };printf("%d\n", sizeof(a)); printf("%d\n", sizeof(a + 0));printf("%d\n", sizeof(*a));printf("%d\n", sizeof(a + 1));printf("%d\n", sizeof(a[1]));printf("%d\n", sizeof(&a));printf("%d\n", sizeof(*&a));printf("%d\n", sizeof(&a + 1));printf("%d\n", sizeof(&a[0]));printf("%d\n", sizeof(&a[0] + 1));
}
1、sizeof(a)是整个数组名所以为整个数组的大小,为4*4=16
2、sizeof(a+0)为首元素地址加0的元素地址既为1的地址,为4/8
3、sizeof(*a)是a的地址解码,是第一个元素1,大小为4
4、a+1是第二个元素的地址,同理也为4/8
5、a[1]也为第二个元素,大小为4
6、&a是去整个数组的地址,对于32地址线内存取4,对于64地址线内存取8
7、*&是取整个数组的地址再解码,因此sizeof里面就一剩一个数组名,大小为16
8、&a+1是区第二个元素的地址也为4/8
9、%a[0]是取第一个元素的地址,因此也为4/8
10、&a[0]+1是取第二个元素的地址,也为4/8
第一组题目完成了,我们来看看
第二组题目
#include <stdio.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%d\n", sizeof(arr));printf("%d\n", sizeof(arr + 0));printf("%d\n", sizeof(*arr));printf("%d\n", sizeof(arr[1]));printf("%d\n", sizeof(&arr));printf("%d\n", sizeof(&arr + 1));printf("%d\n", sizeof(&arr[0] + 1));printf("%d\n", strlen(arr));printf("%d\n", strlen(arr + 0));printf("%d\n", strlen(*arr));Cprintf("%d\n", strlen(arr[1]));printf("%d\n", strlen(&arr));printf("%d\n", strlen(&arr + 1));printf("%d\n", strlen(&arr[0] + 1));
}
1、arr为一个数组名,所以未整个数组的大小为6
2、arr+0代表了数组第一个元素地址,为4/8
3、*arr为数组第一个元素的值的大小为1
4、arr[1]也为数组第一个元素的值的大小为1
5、&arr是取数组arr的地址,大小为4/8
6、&arr+1是跳过了整个数组取下个地址的大小,既然是地址的大小输出的结果为4/8
7、&arr[0]+1为第二个元素的地址大小为4/8
8、strlen(arr)代表了求这个数组的字符长度,要看到'\0'strlen程序才会结束,而这个数组并没有'\0'所以其大小应为随机值
9、strlen(arr+0)也为和8一样的随机值
10、*arr是取数组地址的元素,strlen内部只能为地址,而其为元素,所以这个会显示错误
11、同10也会显示错误
12、&arr是取整个数组的地址,也是数组第一个元素的地址,和8、9一样是一样的随机值
13、&arr+1是跳过了整个数组后的第一个地址,取8、9不同是这个随机值比他们小6
14、地址是从第二个元素开始,所以输出的结果是比8、9小1
我们来看看这个程序运行结果是不是如此呢?
可以看到与我们预测的一样
第三组题目
#include <stdio.h>
int main()
{char arr[] = "abcdef";printf("%d\n", sizeof(arr));printf("%d\n", sizeof(arr + 0));printf("%d\n", sizeof(*arr));printf("%d\n", sizeof(arr[1]));printf("%d\n", sizeof(&arr));printf("%d\n", sizeof(&arr + 1));printf("%d\n", sizeof(&arr[0] + 1));printf("%d\n", strlen(arr));printf("%d\n", strlen(arr + 0));printf("%d\n", strlen(*arr));printf("%d\n", strlen(arr[1]));printf("%d\n", strlen(&arr));printf("%d\n", strlen(&arr + 1));printf("%d\n", strlen(&arr[0] + 1));
}
1、arr一样是整个数组的大小,但是这里记住以字符串命名会多一个'/0'所以这里的大小为7
2、sizeof(arr+0)代表了首元素的地址所以结果为4/8
3、*arr是指的首元素的值,大小为1
4、arr[1]是第二个元素的值大小为1
5、&arr是整个数组的地址,既然是地址大小就为4/8
6、&arr+1为跳过整个数组后的第一个元素的地址大小为4/8
7、&arr[0]+1为第二个元素的地址大小为4/8
8、strlen(arr)为数组的长度,这里有'\0'所以大小为6
9、strlen(arr+0)也是从首地址开始起算,所以大小也为6
10、11、这里都是取的元素,并不是地址,所以这里的值显示错误
12、&arr是整个元素的起始地址,大小也为6
13、&arr+1是整个数组后的第一个元素地址,这里计算字符串长度大小为随机值
14、&arr[0]+1是第二个元素的地址这里的大小为5
第四组题目
#include <stdio.h>
int main()
{char* p = "abcdef";printf("%d\n", sizeof(p));printf("%d\n", sizeof(p + 1));printf("%d\n", sizeof(*p));printf("%d\n", sizeof(p[0]));printf("%d\n", sizeof(&p));printf("%d\n", sizeof(&p + 1));printf("%d\n", sizeof(&p[0] + 1));printf("%d\n", strlen(p));printf("%d\n", strlen(p + 1));printf("%d\n", strlen(*p));printf("%d\n", strlen(p[0]));printf("%d\n", strlen(&p));printf("%d\n", strlen(&p + 1));printf("%d\n", strlen(&p[0] + 1));
}
这里注意命名的是char*命名,取得是后面字符串首元素地址
1、sizeof(p)为首元素地址的大小为4/8
2、是第二个元素地址的大小也为4/8
3、为首元素大小为1
4、为首元素大小为1
5、&p为首元素的地址大小为4/8
6、&p+1为第二个元素地址大小为4/8
7、&p[0]+1为第二个元素地址大小也为4/8
8、strlen(p)为首元素后找到'\0'为止的大小为6
9、为第二个元素后找到'\0'为止的大小为5
10、11、均为char类型的并不适用strlen所以会报错
12、&p是取得指针p的地址,这里计算出来的是随机值,这里并不是取p内指向的地址!
13、也为随机值,但不一定是随机值减1因为&p地址内存放的字符不一定
14、相当于取p[0]的地址再加1即为p[1]的地址大小为5,可以这么理解&(*p)+1
二维数组计算大小
#include <stdio.h>
int main()
{int a[3][4] = { 0 };printf("%d\n", sizeof(a));printf("%d\n", sizeof(a[0][0]));printf("%d\n", sizeof(a[0]));printf("%d\n", sizeof(a[0] + 1));printf("%d\n", sizeof(*(a[0] + 1)));printf("%d\n", sizeof(a + 1));printf("%d\n", sizeof(*(a + 1)));printf("%d\n", sizeof(&a[0] + 1));printf("%d\n", sizeof(*(&a[0] + 1)));printf("%d\n", sizeof(*a));printf("%d\n", sizeof(a[3]));return 0;
}
我们知道二维数组的地址取的是第一行的地址,我们来看看这几个大小是多少
1、sizeof(a)里面是个数组名既计算整个数组的大小为3*4*4=48
2、sizeof(a[0][0])为第一行第一列元素大小为4
3、a[0]为第一行,里面只有一个数组名既为第一行的大小为1*4*4=16
4、a[0]+1为第一行首元素地址加1为第一行第二个元素地址的大小为4/8
5、*(a[0]+1)为第一行第二个元素地址的解引用为其整型的大小为4
6、a+1为第二行地址,地址的大小为4/8
7、*(a+1)为第二行地址的解引用即为第二行数组的大小a[1]大小为16
8、&a[0]+1为第一行的地址加1的大小为第二行的地址大小为4/8
9、为8第二行地址的存储数据大小为16
10、*a代表了第一行元素相当于a[0]大小为16
11、a[3]为第四行元素,注意这里的系统并未访问到第四行元素,sizeof里面的值不参与运算,但是系统会认为此数组存在第四行元素所以还是显示其大小为16