一维数组
sizeof(数组名) - 数组名表示整个数组的-计算的是整个数组的大小 &数组名 - 数组名表示整个数组,取出的是整个数组的地址
除此之外,所有的数组名都是数组首元素的地址
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 数组有四个元素 每个元素四个字节 所以计算的结果是16
2 a+0是第一个元素的地址 ,sizeof(a +0 ) 计算的是地址的大小, 所以结果是4/8 【32位平台是4 ,64位平台是8】
3 *a 是数组第一个元素 ,sizeof(*a)计算的是第一个元素的大小,第一个元素的类型是int ,所以结果是4
4 a +1 是第二个元素的地址 ,sizeof(a+1)计算的是地址的大小 ,所以结果是4/8
5 a[1] 计算的是第一个元素的大小 ,第一个元素的类型是int ,所以结果是 4
6 &a 虽然是数组的地址 ,但是也是地址 ,sizeof(&a) 计算的是地址的大小 所以结果是4/8
7 sizeof (* &a) 计算的是数组的大小 ,其实就是int(*p)[4] = &a 但是这里需要一个能够指向数组的指针 ,存放数组的地址 。 将整个数组解引用, 得到的是整个数组的内容 。数组每个元素类型是int ,所以结果是16 —
8 &a+1 数组后面空间的地址。 &a 取出整个数组的地址 ,放在数组指针中(int(*p)[4] = &a)。+1 跳过一个数组指针
9 &a[0] 取出的是第一个元素的地址 ,所以结果是4/8
10 &a[0] + 1 ,取出的是第二个元素的地址 ,所以结果是4/8
字符数组
sizeof 是操作符 ,‘\0’参与计算长度 strlen是函数 以’\0’ 作为结束标志 ,但是’ \0 '不参与计算长度
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));
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 sizeof(arr)计算整个数组的大小 ,数组每个元素类型是char 所以结果是6
2 size(arr+0) 数组名表示首元素地址 ,地址的大小是4/8
3 sizeof(*arr) 数组名表示首元素地址 ,对 'a’进行解引用 ,找到a元素 ,a的类型是char 所以结果就是1
4 arr[0] 找到a元素 ,a的类型是char 所以结果就是1
5 sizeof(&arr) ,字符数组的地址也是地址 ,地址的大小是4/8
6 sizeof(&arr +1 ) ,&arr取出的是整个字符数组的地址 ,+1 跳过整个字符数组
7 sizeof(arr[0] +1) , 取出的第一个元素的地址 , 它的类型本质上是char * , +1 跳过一个元素 ,指向b , 所以结果是4/8
8 数组名表示首元素地址 ,strlen 会一直往下读 ,直到找到’ \0’为止 , 但是我们并不知道’\0’在内存中什么位置 , 所以结果就是随机值
9 数组名表示首元素地址 ,arr+0还是指向a的地址 ,所以结果是随机值
10 找到a的地址,解引用找到a元素 ,把字符a的ASCII值97当成地址,以ASCII值97为地址去找字符串 , 是找不到的 所以这个代码是错误的
11 arr[1]表示字符’b’,b的ASCII值是98 , 98作为地址也有问题 ,所以这个代码是错误的
12 strlen (&ar) 取出字符数组的地址 ,放到一个字符数组指针, char (*p)[6]=&arr 这里发生了类型转换,值没有变化, 地址传给str时,类型发生了变化 从char (*p)[6] 变为char * 即使是传过来的是数组的地址 ,站在strlen角度上 ,仍然认为是字符串首字符的地址 ,strlen 向后找’\0’ , 所以结果是随机值
13 strlen (&arr+1) , char (*p)[6]=&arr ,把字符数组的地址放在数组指针中 , 所以+1跳过一个字符数组 , strlen并不知道’\0’在内存中的位置 ,所以结果是随机值
14 &b的地址 向后找’\0’ ,结果是随机值
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 sizeof(arr) 计算整个数组 数组7个元素 ,每个元素类型是int 所以结果是7
2 sizeof(arr+0) 表示a的地址 , 所以结果是4/8
3 sizeof(*arr) 表示a元素 , a元素的类型是char,所以结果是1
4 sizeof (arr[1] ) 表示 第二个元素 b ,b元素的类型是char,所以结果是1
5 sizeof (&arr) ,取出整个数组的地址 , char (*p) [7] =&arr ,但是整个数组的地址也是地址,所以是4/8
6 sizeof(&arr+1) ,char (*p) [7] =&arr ,+1 跳过7个字符的数组,所以是4/8
7 sizeof(&arr[0] +1) 表示第二个元素的地址,所以是4/8
8 strlen (arr) 以’\0’ 作为结束标志 , ‘\0’ 前面有6个字符 ,所以结果是6
9 strlen(arr) 数组名表示首元素地址 , 所以结果是6
10 strlen(*arr) 表示a元素 , 把a的ASCII值传过去 ,这是错误的代码
11 表示b元素的 , 把b的ASCII值传过去 ,这是错误的代码
12 strlen(&arr) 取出整个数组的地址 , char (*p) [7] =&arr , 向后找’\0’ ,所以结果是6
13 strlen(&arr+1) &arr取出整个数组的地址 , char (*p) [7] =&arr ,+1 跳过整个数组,但是后面有没有’\0’ ,strlen并不知道 .所以是随机值
14 strlen(&arr[0]+1) ,所以结果是5
字符指针
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));
1 p指向的是a的地址 ,sizeof§,计算的是一个指针变量的大小 ,虽然是字符指针,也是指针 ,指针的大小是4/8
2 sizeof(p+1) p+1 指向b的地址 ,b的地址也是地址 ,所以是4/8
3 sizeof(*p) ,p指向a的地址, *p 拿到的是a元素
4 p[0] 等价于*( p+0) ,找到的就是a元素
5 &p ,取出p的地址 ,p的地址也是地址 , 所以结果是4/8
6 &p +1 ,跳过一个p ,所以结果是4/8
7 &p[0]+1 p[0] 是a元素 , &p[0] 就是取出a的地址 ,+1 指向b的地址,b的地址也是地址 , 所以结果是4/8
8 p指向a的地址 ,strlen 向后寻找\0 才会停止 ,所以结果是6
9 p指向a的地址 ,p+1 就指向b的地址 ,所以结果是5
10 *p 找到的是a ,代码错误
11 p[0] 就等价于*(p+0) ,找到a元素 ,代码错误
12 &p ,取出p指针的地址 ,但是里面是否有\0 , strlen 并不清楚 ,所以是随机值
13 &p+1 结果是随机值
14 &p[0]+1 ,指向b的地址 ,所以结果是5
二位数组
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]));
1 sizeof(a) 计算整个数组 ,数组有12个元素 ,每个元素的类型是int ,所以结果是48
2 a[0][0]是第一行第一个元素 ,sizeof计算第一行第一个元素所占空间的大小 ,类型是int ,所以结果是4
3 a [0] 可以理解为第一行的数组名 ,此时是数组a[0]单独放在sizeof内部 , a[0] 表示整个的第一行 ,sizeof(a[0])计算的就是第一行的大小 所以结果是16
4 a[0]作为数组名并没有单独放在sizeof内部,也没取地址, 所以a[0]就是第一行第一个算的地址 a[0]+1,就是第一行第二个元素的地址 ,所以结果是4/8
5 拿到第一行第二个元素 ,第一行第二个元素的类型是int ,所以结果就是4
6 数组名表示首元素地址,二维数组的首元素地址是第一行 ,a+1表示第二行的地址 ,所以结果就是4/8
7 a+1是第二行的地址,所以*(a+1)表示第二行 所以计算的就是第2行的大小 ,每个元素类型是Int ,所以结果是16
8 a[0]是第一行的数组名,&a[0]取出的就是第一行的地址,&a[0]+1 就是第二行的地址 所以结果是4/8
9&a[0]+1 就是第二行的地址,*(&a[0]+1) 就是第二行,每个元素类型是int 所以结果是16
10 a就是首元素的地址,即第一行的地址,所以*a就是第一行,计算的是第一行的大小 所以结果是16
11 a[3]其实是第四行的数组名(如果有的话),所以其实不存在,也能通过类型计算大小的 所以结果是16
如果你觉得这篇文章对你有帮助,不妨动动手指给点赞收藏加转发,给鄃鳕一个大大的关注 你们的每一次支持都将转化为我前进的动力!!!
|