指针和数组笔试题解析

目录

1.一维数组

2.字符数组

2.1    char arr[] = {'a','b','c','d','e','f'}

 2.2    char arr[] = "abcdef"

2.3    char *p = "abcdef"

3.二维数组


全面分析指针和数组笔试题,带你加深了解数组和指针,努力学习,加油!

1.一维数组


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

 

int a[] = {1,2,3,4};      一维数组四个元素,每个元素是int 类型(四个字节)

  1. int数组sizeof(数组名)计算整个数组的大小,答案为16
  2. int数组sizeof(数组名+其他)此处数组名并未单独放在sizeof内部,为数组首元素地址,答案为4或8
  3. 数组名为数组首元素地址,解引用后指向数组第一个元素  ‘1’  ,答案为4
  4. int型指针+1跳过四个字节,地址(指针)加1或者-1仍然是地址(指针),答案为4或8
  5. 数组第二个元素的大小,答案为4
  6. &a意义是整个数组的地址,但是整个数组的地址仍然是个指针,因此指针大小还是4或8
  7. 此处可以理解为&符号和*符号相互抵消,等价于sizeof(数组名),为整个数组的大小,答案为16
  8. &a+1跳过整个数组,但是仍然是地址,地址取决于编译环境,答案为4或8
  9. 数组首元素的地址,答案为4或8
  10. 数组首元素地址+1,跳过四个字节指向第二个元素,但仍然是地址,答案为4或8

2.字符数组

2.1    char arr[] = {'a','b','c','d','e','f'}

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

解析如下:

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main()
{

	char arr[] = { 'a','b','c','d','e','f' };
	printf("%zd\n", sizeof(arr));//字符数组,数组名为首元素地址,但是单独放在sizeof()内部为整个数组大小,打印6
	printf("%zd\n", sizeof(arr + 0));//数组名为首元素地址,并未&并且并未单独放在sizeof内部,地址的大小,4或者8
	printf("%zd\n", sizeof(*arr));//数组名为首元素地址  *arr为数组第一个元素'a',打印第一个元素大小,打印1
	printf("%zd\n", sizeof(arr[1]));//打印数组第二个元素的大小,为1
	printf("%zd\n", sizeof(&arr));//地址的大小,为4或者8
	printf("%zd\n", sizeof(&arr + 1));//地址的大小。为4或者8
	printf("%zd\n", sizeof(&arr[0] + 1));//地址的大小,为4或者8


	printf("%zd\n", strlen(arr));//计算字符串长度,从数组首元素开始计算,但是字符串中并未有结束符“ \0 ”,因此为随机值
	printf("%zd\n", strlen(arr + 0));//计算字符串长度,从数组首元素开始计算,但是字符串中并未有结束符“ \0 ”,因此为随机值
	printf("%zd\n", strlen(*arr));//站在strlen角度认为    将字符'a'---97当作字符串起始地址,非法地址,访问错误
	printf("%zd\n", strlen(arr[1]));//站在strlen角度认为  将字符'b'---98当作字符串起始地址,非法地址,访问错误
	printf("%zd\n", strlen(&arr));//&arr类型为 char (*)[6]  传入strlen会进行转化为const char*,因此还是从数组首元素开始计算长度,为随机值
	printf("%zd\n", strlen(&arr + 1));//&arr+1跳过一个数组后往后数,仍然为随机值,
	printf("%zd\n", strlen(&arr[0] + 1));//&arr[0]+1跳过一个字符后往后数,但仍然为随机值

	return 0;
}

 2.2    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));

解析如下:

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "abcdef";
	//arr数组中实际有"abcdef\0"
	printf("%d\n", sizeof(arr));//sizeof(数组名)计算整个数组大小,包括了\0,答案为7
	printf("%d\n", sizeof(arr + 0));//sizeof(首元素地址+0),计算第一个元素的地址大小,4或者8
	printf("%d\n", sizeof(*arr));//第一个元素大小,答案为1
	printf("%d\n", sizeof(arr[1]));//第一个元素大小,答案为1
	printf("%d\n", sizeof(&arr));//计算指针大小。4或者8
	printf("%d\n", sizeof(&arr + 1));///计算指针大小。4或者8
	printf("%d\n", sizeof(&arr[0] + 1));///计算指针大小。4或者8


	printf("%d\n", strlen(arr));//计算\0之前的字符个数,为6
	printf("%d\n", strlen(arr + 0));//答案为6
	printf("%d\n", strlen(*arr));//strlen认为字符'a'---97为字符起始地址,非法访问,错误
	printf("%d\n", strlen(arr[1]));//strlen认为字符'b'---98为字符起始地址,非法访问,错误
	printf("%d\n", strlen(&arr));//&arr类型为--char (*)[6] 传入strlen函数会被转化为const char *,因此从首元素位置开始向后计数。为6
	printf("%d\n", strlen(&arr + 1));//&arr类型为---char (*)[6]  +1 后跳过一个数组大小,为随机值
	printf("%d\n", strlen(&arr[0] + 1));//&arr[0]类型为---char * +1跳过一个字符指针大小,答案为5


	return 0;
}

2.3    char *p = "abcdef"

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


解析如下:

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	char* p = "abcdef";//字符指针,将字符串首位置字符'a'的地址传给 p

	printf("%zd\n", sizeof(p));//计算字符指针p的大小,4或者8
	printf("%zd\n", sizeof(p + 1));//计算指针的大小,4或者8
	printf("%zd\n", sizeof(*p));//计算字符'a'的大小,为1
	printf("%zd\n", sizeof(p[0]));//计算字符'a'的大小,为1,可以理解为p[0]--> *(p+0)
	printf("%zd\n", sizeof(&p));//计算指针的大小,4或者8
	printf("%zd\n", sizeof(&p + 1));//计算指针的大小,4或者8
	printf("%zd\n", sizeof(&p[0] + 1));//计算指针的大小,4或者8


	printf("%d\n", strlen(p));//计算字符个数,为6
	printf("%d\n", strlen(p + 1));//计算字符个数,为5
	printf("%d\n", strlen(*p));//*p指向a,将字符'a'---97看作起始地址,非法访问,错误
	printf("%d\n", strlen(p[0]));//同样是将字符'a'---97看作起始地址,非法访问,错误
	printf("%d\n", strlen(&p));//&p为二级指针,该地址中的字符未知,所以是随机值
	printf("%d\n", strlen(&p + 1));//跳过了该数组,后续未知,所以为随机值
	printf("%d\n", strlen(&p[0] + 1));//字符串首元素地址+1后指向字符'b',计算长度为5

	return 0;
}

3.二维数组

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]));

解析如下:

我们可以将二维数组存储看作如下图:

但是二维数组在内存中真实情况是连续存放的

 

 

 二维数组可以理解为一维数组的数组,a[0]相当于第一行数组的数组名

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
	int a[3][4] = { 0 };
	//
	printf("%d\n", sizeof(a));//二维数组 a 也是数组名,数组名单独放在sizeof内部,表示整个数组,计算整个数组的大小,为3*4*4 =48
	printf("%d\n", sizeof(a[0][0]));//计算a[0][0]元素大小,为4
	printf("%d\n", sizeof(a[0]));//,二维数组可以理解为一维数组的数组,a[0]相当于第一行数组的数组名,单独放在sizeof内部,计算的是整个第一行数组的大小,为4*4 =16
	printf("%d\n", sizeof(a[0] + 1));//a[0]并没有单独放在sizeof内部,也没有&,所以代表第一行第一个元素的地址,相当于a[0]-->&a[0][0],计算的是第一行第二个元素的地址的大小为4或者8
	printf("%d\n", sizeof(*(a[0] + 1)));//代表计算第一行第二个元素的大小,int类型大小为4
	printf("%d\n", sizeof(a + 1));//地址的大小,4或者8,a作为二维数组数组名并没有单独放在siezof内部,也没有&,所以a表示数组首元素地址,也就是第一行的地址,第一行的地址+1为第二行的地址
	printf("%d\n", sizeof(*(a + 1)));//解引用第二行数组的地址拿到整个第二行数组,大小为16
	printf("%d\n", sizeof(&a[0] + 1));//计算第一行第二个元素的地址,4或者8
	printf("%d\n", sizeof(*(&a[0] + 1)));//a[0]是第一行的数组名,&a[0]取出的是第一行的一维数组的地址,+1后为第二行的地址,解引用访问第二行,大小为16
	printf("%d\n", sizeof(*a));//a表示数组首元素地址,也就是第一行的地址,*a对第一行解引用,计算第一行数组大小为16
	printf("%d\n", sizeof(a[3]));//虽然不存在a[3],但不会越界,因为sizeof运算并不会真的在内存中去访问该数组,所以仍然能计算出大小为16,相当于编译器已经确定了类型a[0]--int [4] a[3]--int [4]
	//表达式有两个属性,一个是值属性,一个是类型属性
	return 0;
}

谢谢大家的支持与鼓励!下次再见!

  • 24
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 33
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jamo@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值