【C生万物】 指针和数组笔试题汇总 (上)

 欢迎来到 Claffic 的博客 💞💞💞                               👉 专栏:《C生万物 | 先来学C》👈

前言:

在学习完初级和进级的指针之后,为了检验掌握程度,这里出一期指针和数组的笔试题,看看你掌握的怎么样吧!


目录

Part1:数组笔试题

1.做题

1.1一维数组

1.2字符数组

1.3二维数组

2.总结


Part1:数组笔试题

1.做题

1.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};
printf("%d\n",sizeof(a));        16 -- 整个数组的大小 4*4 == 16
printf("%d\n",sizeof(a+0));      8  -- + 0这个动作表明是指针 64位下指针大小固定为 8
printf("%d\n",sizeof(*a));       4  -- 首元素地址解引用得到首元素1,一个整型大小为4
printf("%d\n",sizeof(a+1));      8  -- 指针大小
printf("%d\n",sizeof(a[1]));     4  -- 元素2的大小
printf("%d\n",sizeof(&a));       8  -- &a代表指向数组a的指针
printf("%d\n",sizeof(*&a));      16 -- 承上,解引用后表示整个数组
printf("%d\n",sizeof(&a+1));     8  -- 指针+1,表示步长,即指针大小
printf("%d\n",sizeof(&a[0]));    8  -- 首元素地址,指针大小
printf("%d\n",sizeof(&a[0]+1));  8  -- 步长,即指针大小

1.2字符数组

计算大小:

第一部分

char arr[] = { 'a','b','c','d','e','f' }; // 没有\0
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));

答案及解析:

char arr[] = { 'a','b','c','d','e','f' };  // 没有\0
printf("%d\n", sizeof(arr));          6 -- 所有字符的总大小,一个字符一字节,共6字节
printf("%d\n", sizeof(arr + 0));      8 -- 表示指针,8字节
printf("%d\n", sizeof(*arr));         1 -- 首元素地址解引用得到首元素,大小为1
printf("%d\n", sizeof(arr[1]));       1 -- 元素b的大小
printf("%d\n", sizeof(&arr));         8 -- 指向整个数组的指针大小
printf("%d\n", sizeof(&arr + 1));     8 -- 指针步长
printf("%d\n", sizeof(&arr[0] + 1));  8 -- 指向首元素指针的步长

 

第二部分 

char arr[] = { 'a','b','c','d','e','f' };  // 没有\0
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));

答案及解析:

char arr[] = { 'a','b','c','d','e','f' };  // 没有\0
printf("%d\n", strlen(arr));         随机值 -- arr表示首元素地址,但不知道\0在哪,不知道停止
printf("%d\n", strlen(arr + 0));     随机值 -- 同上,表示地址
printf("%d\n", strlen(*arr));        报错 -- ==strlen('a'),非法访问
printf("%d\n", strlen(arr[1]));      报错 -- ==strlen('b'),非法访问
printf("%d\n", strlen(&arr));        随机值 -- 从整个数组开始,向后寻找\0停止
printf("%d\n", strlen(&arr + 1));    随机值 -- 从跳过整个数组开始,向后寻找\0停止
printf("%d\n", strlen(&arr[0] + 1)); 随机值 -- 从'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));

答案及解析: 

char arr[] = "abcdef";  // 末尾有\0
printf("%d\n", sizeof(arr));       7 -- 包含\0在内   
printf("%d\n", sizeof(arr+0));     8 -- 指针大小
printf("%d\n", sizeof(*arr));      1 -- a的大小
printf("%d\n", sizeof(arr[1]));    1 -- b的大小
printf("%d\n", sizeof(&arr));      8 -- 字符串指针的大小
printf("%d\n", sizeof(&arr+1));    8 -- 字符串指针的步长大小
printf("%d\n", sizeof(&arr[0]+1)); 8 -- 首元素指针的步长大小

第四部分 

char arr[] = "abcdef";  // 末尾有\0
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));

答案及解析: 

char arr[] = "abcdef";  // 末尾有\0
printf("%d\n", strlen(arr));       6 -- 计算\0之前的大小
printf("%d\n", strlen(arr+0));     6 -- 同上
printf("%d\n", strlen(*arr));      报错 -- 给strlen传递'a'
printf("%d\n", strlen(arr[1]));    报错 -- 给strlen传递'b'
printf("%d\n", strlen(&arr));      6 -- 取出起始位置的地址
printf("%d\n", strlen(&arr+1));    随机值 -- 跳过整个数组(包含\0)
printf("%d\n", strlen(&arr[0]+1)); 5 -- 从b开机计算大小,到\0之前

第五部分 

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

答案及解析:

char *p = "abcdef";
printf("%d\n", sizeof(p));       8 -- p是指针变量,即指针大小
printf("%d\n", sizeof(p+1));     8 -- p+1是指针变量
printf("%d\n", sizeof(*p));      1 -- 即a的大小
printf("%d\n", sizeof(p[0]));    1 -- 即a的大小
printf("%d\n", sizeof(&p));      8 -- 二级指针大小
printf("%d\n", sizeof(&p+1));    8 -- 指向整个字符串的指针步长
printf("%d\n", sizeof(&p[0]+1)); 8 -- 指向b的指针的大小

第六部分 

char* p = "abcdef";
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* p = "abcdef";                
printf("%d\n", strlen(p));         6 -- 标准求字符串长度
printf("%d\n", strlen(p + 1));     5 -- 从b开始求字符串长度
printf("%d\n", strlen(*p));        报错 -- strlen(a)
printf("%d\n", strlen(p[0]));      报错 -- 同上
printf("%d\n", strlen(&p));        随机值 -- 指向p的指针,另起
printf("%d\n", strlen(&p + 1));    随机值 -- 跳过指向p的指针
printf("%d\n", strlen(&p[0] + 1)); 5 -- 从b开始求字符串长度

 

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

答案及解析:

因为是二维数组,这里画个图会好理解些:

 

注意:可以先这样理解,实际内存中是连续存储的。

int a[3][4] = {0};                 
printf("%d\n",sizeof(a));           48 -- 整个二位数组的大小 3*4*4
printf("%d\n",sizeof(a[0][0]));      4 -- 下标为0,0,即第一个元素的大小
printf("%d\n",sizeof(a[0]));        16 -- a[0]作为第一行的数组名,单独放在sizeof内部,计算的是数组第一行的大小
printf("%d\n",sizeof(a[0]+1));       8 --a[0]作为第一行的数组名,没有单独放在sizeof内部,没有取地址,表示的就是数组首元素的地址,即a[0][0]的地址,再+1就是a[0][1]的地址,是地址就是指针,指针大小
printf("%d\n",sizeof(*(a[0]+1)));    4 -- 第一行第二个元素的大小
printf("%d\n",sizeof(a+1));          8 -- a是二维数组的数组名,数组名表示首元素的地址,就是第一行的地址,a+1就是第二行的地址,是地址就是指针,指针大小
printf("%d\n",sizeof(*(a+1)));       16 -- 第二行的大小
printf("%d\n",sizeof(&a[0]+1));       8 -- &a[0]是第一行的地址,&a[0]+1就是第二行的地址,地址的大小指针大小
printf("%d\n",sizeof(*(&a[0]+1)));   16 -- 第二行的大小
printf("%d\n",sizeof(*a));           16 -- a表示首元素的地址,就是第一行的地址,*a就是第一行,计算的就是第一行的大小
printf("%d\n",sizeof(a[3]));         16 -- 如果数组存在第四行,a[3]就是第四行的数组名,数组名单独放在sizeof内部,计算的是第四行的大小

 

2.总结

数组名的意义:
• sizeof( 数组名 ) ,这里的数组名表示整个数组,计算的是整个数组的大小;
• &数组名,这里的数组名表示整个数组,取出的是整个数组的地址;
• 除此之外所有的数组名都表示首元素的地址。


总结: 

这篇博客带大家做了些关于数组和指针的笔试题,基本上汇总了全部类型,其实到这里还没完,那么下篇再带大家继续指针的练习。

码文不易 

如果你觉得这篇文章还不错并且对你有帮助,不妨支持一波哦  💗💗💗

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Claffic

赏包辣条~

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

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

打赏作者

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

抵扣说明:

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

余额充值