(C语言)指针和数组的经典笔试题(详解)

本文详细解释了C语言中sizeof运算符在处理整型、字符数组和二维数组时的行为,强调了数组名、首元素地址和解引用的概念,以及计算内存占用大小的不同情况。
摘要由CSDN通过智能技术生成

#解析在备注里#

一、数组

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;
}

提示:

1、sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。

2、&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。

3、除此之外所有的数组名都表示首元素的地址。

二、字符数组

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之前出现的字符个数

char* c[] = { "ENTER","NEW","POINT","FIRST" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp = cp;
printf("%s\n", **++cpp);
//"POINT",注意运行结束此时cpp指向cp[1]
printf("%s\n", *--* ++cpp + 3);
//"ER",++优先级高,先执行*--*++cpp,再执行c[0]+3,此时cpp指向cp[2]
printf("%s\n", *cpp[-2] + 3);
//"ST",等效*(*(cpp-2))+3,cpp-2指向cp[0],两次解引用后c[3]+3,注意此时cpp指向并没有改变
printf("%s\n", cpp[-1][-1] + 1);
//"EW",等效*(*(cpp-1)-1)+1,cpp-1指向cp[1],第一次解引用指向c[1],第二次解引用指向"NEW",+1后指向E

三、二维数组

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;
}

提示:arr[]是每行的数组名,arr[][]是每个的数组名

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值