目录
一、一维数组
二、字符数组
三、二维数组
注意:假设本练习题所用的VS编译器是64位平台下的。
首先要明白数组名的意义:
1、sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2、&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3、除此之外所有的数组名都表示首元素的地址。
一、一维数组
int main()
{
int arr[] = { 3,0,8,17,9,54 };
printf("%d\n", sizeof(arr));
//答案是24,这里的数组名表示整个数组,sizeof(arr)计算的是整个数组的大小,即4×6=24
printf("%d\n", sizeof(arr + 0));
//答案是8,这里的arr没有单独存放在sizeof内部,也没有取地址,则表示数组首元素地址,arr+0表示跳过0个int类型的变量,仍然还是首元素地址,是地址大小就为8个字节
printf("%d\n", sizeof(*arr));
//答案是4,arr表示首元素地址,*arr解引用之后就为首元素,大小是4个字节,*arr->*&arr[0]->arr[0]
printf("%d\n", sizeof(arr + 1));
//答案是8,arr+1跳过一个int类型的变量,表示第二个元素的地址,是地址大小就为8个字节
printf("%d\n", sizeof(arr[1]));
//答案是4,arr[1]表示第二个元素,大小是4个字节
printf("%d\n", sizeof(&arr));
//答案是8,&arr这里的arr表示整个数组,取出的是整个数组的大小,&arr即表示整个数组的地址,是地址大小就为8
printf("%d\n", sizeof(*&arr));
//答案是24,&arr表示整个数组的地址,*对其解引用找到的是整个数组,大小是4×6=24个字节,&arr是数组指针,类型是int(*)[6],数组指针解引用找到的是数组
printf("%d\n", sizeof(&arr + 1));
//答案是8,&arr+1表示跳过整个数组的地址,最终结果还是地址,大小是8个字节,&arr+1是从数组arr的地址向后跳过了一个(6个整型元素)数组的大小
printf("%d\n", sizeof(&arr[0]));
//答案是8,&arr[0]表示第一个元素的地址,是地址大小就是8个字节
printf("%d\n", sizeof(&arr[0] + 1));
//答案是8,&arr[0]+1表示第二个元素的地址,大小是8
return 0;
}
运行结果:
二、字符数组
int main()
{
char arr[] = { 'x','y','z','p','q','r','m','n','k'};
printf("%d\n", sizeof(arr));
//答案是9,这里arr表示整个数组,计算的是整个数组的大小,即1×9=9
printf("%d\n", sizeof(arr + 0));
//答案是8,arr表示数组首元素地址,arr+0表示跳过0个char类型的变量,还是首元素地址,是地址大小就是8
printf("%d\n", sizeof(*arr));
//答案是1,*表示解引用,*arr就表示首元素,大小是1,*arr->*(arr+0)->arr[0]
printf("%d\n", sizeof(arr[1]));
//答案是1,arr[1]表示第二个元素,大小是1
printf("%d\n", sizeof(&arr));
//答案是8,&arr表示整个数组的地址,是地址大小就是8
printf("%d\n", sizeof(&arr + 1));
//答案是8,&arr+1是跳过了一个(9个字符型元素)的数组后的地址,大小是8
printf("%d\n", sizeof(&arr[0] + 1));
//答案是8,&arr[0]+1表示跳过一个char型变量的地址,即第二个元素的地址,大小是8
return 0;
}
运行结果:
补充:sizeof是操作符,只关注占用内存空间的大小,不在乎内存中放的是什么
strlen是库函数,只针对字符串,strlen是求字符串长度的,关注的是字符串中的\0,计算的是\0之前出现的字符个数
strlen函数的参数是指针类型的
例如这样的语句就会编译错误,因为strlen的参数不是指针类型。
#include<string.h>
int main()
{
char arr[] = { 'x','y','z','p','q','r','m','n','k' };
printf("%d\n", strlen(arr));
//答案是随机值,arr表示整个数组,strlen(arr)计算的是整个数组的字符串长度,但数组后面不知道什时候才能遇到\0
printf("%d\n", strlen(arr + 0));
//答案是随机值,arr表示首元素地址,arr+0跳过0个char类型的变量,还是首元素地址,但首元素后面不知道什么时候遇到\0
//printf("%d\n", strlen(*arr));
//printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
//答案是随机值,因为不知道后面什么时候遇到\0
printf("%d\n", strlen(&arr + 1));
//答案是上一行语句随机值的情况下-9,同样也是不知道后面什么时候遇到\0
printf("%d\n", strlen(&arr[0] + 1));
//答案是54行语句的随机值-1,因为后面不知道什么时候遇到\0
return 0;
}
运行结果:
int main()
{
char arr[] = "xyz";//这里的字符串中包含了\0,即字符串中的字符元素是x y z \0
printf("%d\n", sizeof(arr));
//答案是4,这里包含有\0,整个数组的大小便是4
printf("%d\n", sizeof(arr + 0));
//答案是8,arr+0仍然是首元素的地址,是地址大小便是8
printf("%d\n", sizeof(*arr));
//答案是1,*arr表示首元素
printf("%d\n", sizeof(arr[1]));
//答案是1
printf("%d\n", sizeof(&arr));
//答案是8
printf("%d\n", sizeof(&arr + 1));
//答案是8
printf("%d\n", sizeof(&arr[0] + 1));
//答案是8,&arr[0]+1表示第二个元素的地址
return 0;
}
运行结果:
#include<string.h>
int main()
{
char arr[] = "xyz";//这里的字符串中包含了\0,即字符串中的字符元素是x y z \0
printf("%d\n", strlen(arr));
//答案是3,\0之前出现了3个字符
printf("%d\n", strlen(arr + 0));
//答案是3,arr+0仍然表示首元素地址
//printf("%d\n", strlen(*arr));
//printf("%d\n", strlen(arr[1]));
//此处的*arr和arr[1]都不是指针类型
printf("%d\n", strlen(&arr));
//答案是3,见图解
printf("%d\n", strlen(&arr + 1));
//答案是随机值,见图解
printf("%d\n", strlen(&arr[0] + 1));
//答案是2,从第二个元素开始到\0读取2个字符串
return 0;
}
102行、104行语句图解:
运行截图:
int main()
{
char* p = "xyz";//这里的p表示首元素的地址
printf("%d\n", sizeof(p));
//答案是8,p表示首元素的地址
printf("%d\n", sizeof(p + 1));
//答案是8,p+1表示第二个元素的地址
printf("%d\n", sizeof(*p));
//答案是1,*p表示第一个元素
printf("%d\n", sizeof(p[0]));
//答案是1
printf("%d\n", sizeof(&p));
//答案是8,&p是二级指针
printf("%d\n", sizeof(&p + 1));
//答案是8
printf("%d\n", sizeof(&p[0] + 1));
//答案是8,&p[0]+1表示y的地址
return 0;
}
运行结果:
int main()
{
char* p = "xyz";//这里的p表示首元素的地址
printf("%d\n", strlen(p));
//答案是3
printf("%d\n", strlen(p + 1));
//答案是2
//printf("%d\n", strlen(*p));
//printf("%d\n", strlen(p[0]));
//编译错误
printf("%d\n", strlen(&p));
//答案是随机值,&p是二级指针,不确定后面什么时候遇到\0
printf("%d\n", strlen(&p + 1));
//答案是随机值-随机值
printf("%d\n", strlen(&p[0] + 1));
//答案是2
return 0;
}
三、二维数组
int main()
{
int arr[5][6] = { 0 };
printf("%d\n", sizeof(arr));
//答案是120,5×6×4=120
printf("%d\n", sizeof(arr[0][0]));
//答案是4
printf("%d\n", sizeof(arr[0]));
//答案是24,arr[0]是第一行这个一维数组的数组名,单独放在sizeof内部,arr[0]表示第一个整个这个一维数组
printf("%d\n", sizeof(arr[0] + 1));
//答案是8,arr[0]并没有单独放在sizeof内部,也没取地址,arr[0]就表示首元素地址,就是第一行这个一维数组的第一个元素的地址,arr[0]+1就是第一行第二个元素的地址
printf("%d\n", sizeof(*(arr[0] + 1)));
//答案是4
printf("%d\n", sizeof(arr + 1));
//答案是8,arr+1表示第二行的地址
printf("%d\n", sizeof(*(arr + 1)));
//答案是24
printf("%d\n", sizeof(&arr[0] + 1));
//答案是8,&arr[0]+1表示第二行的地址
printf("%d\n", sizeof(*(&arr[0] + 1)));
//答案是24
printf("%d\n", sizeof(*arr));
//答案是24
printf("%d\n", sizeof(arr[3]));
//答案是24
return 0;
}
运行结果:
二维数组确实有点打脑壳,你们觉得呢?