当前位置: 首页 > news >正文

【C语言】指针和数组笔试题解析(1)

指针是C语言的灵魂,他的玩法多种多样,这篇文章带来指针的笔试题详解,可以帮助我们更好的理解与巩固指针的知识

目录

  • 预备知识:
  • 题目:
    • 一维数组:
    • 二维数组:

题目比较多,但切记戒骄戒躁,保持空杯心态,相信看完一定会有提升
开始之前要先来一点预备知识:

预备知识:

数组名:

数组名大部分情况下是首元素地址,但有两种情况例外
1.当sizeof(数组名),此时数组名代表整个数组,求出的是整个数组的大小,单位是字节。
2.当&数组名,此时数组名代表整个数组,取出的是整个数组的地址,虽然与首元素地址相同,但含义不一样。

sizeof:

sizeof是一个操作符,可以求变量(类型)所占空间的大小。

strlen:

strlen是一个为库函数,可以获取字符串\0之前的长度

一一一一一一一一一分割线一一一一一一一一一一

题目:

分为两部分,第一部分时一维数组,第二部分是二维数组,逐步攀升难度

假设都在32位机器下进行

一维数组:

第一组:

//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));//1
printf("%d\n",sizeof(a+0));//2
printf("%d\n",sizeof(*a));//3
printf("%d\n",sizeof(a+1));//4
printf("%d\n",sizeof(a[1]));//5
printf("%d\n",sizeof(&a));//6
printf("%d\n",sizeof(*&a));//7
printf("%d\n",sizeof(&a+1));//8
printf("%d\n",sizeof(&a[0]));//9
printf("%d\n",sizeof(&a[0]+1));//10

答案:

1.16
a代表整个数组,每个数组元素是int类型,一共4个元素,故为16字节大小
2.4
a为首元素地址,当地址进行±运算时,与指针类型有关,a的类型为int*,所以+0时,地址会向前跳过0个整形,仍旧是首元素地址
3.4
a为首元素地址,当解引用时,得到的是arr[0],也就是第一个整形元素,大小为4
4.4
a为首元素地址,当地址进行±运算时,与指针类型有关,a的类型为int*,所以+1时,地址会向前跳过1个整形,而数组是连续存放的,故地址会指向第二个数组元素。
5.4
a[1]是一个整形,为数组第二个整形元素,大小是4字节
6.4
&数组名代表的是取出整个元素的地址,但不管是什么地址,在32位下地址都是4个字节大小
7.16

此题有两种解法:
1.*与&结合会相互抵消,数组名在sizeof中就是求出整个数组的大小
2.&数组名取出的是整个数组的地址,当地址进行解引用时,与指针类型有关,解引用一个数组指针类型的内容,就会访问一个大小为此数组的内容,即4个整形变量的数组,大小为16字节

8.4
a代表整个数组,当地址进行±运算时,与指针类型有关,而此数组指针的类型是 int(*)[4], 数组指针+1会跳过一个数组,也就是跳过4个整形的数组,而运算后的结果仍旧是地址,故答案为4
9.4
&a[0]代表的是第一个元素的地址,地址大小为4字节
10.4
&a[0]代表的是第一个元素的地址,当地址进行±运算时,与指针类型有关,整形指针+1会跳过一个整形,即&a[0]+1指向数组第二个元素,为第二个元素的地址,大小为4个字节

一一一一一一一一一分割线一一一一一一一一一一
第二组:

//字符数组
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//1
printf("%d\n", sizeof(arr+0));//2
printf("%d\n", sizeof(*arr));//3
printf("%d\n", sizeof(arr[1]));//4
printf("%d\n", sizeof(&arr));//5
printf("%d\n", sizeof(&arr+1));//6
printf("%d\n", sizeof(&arr[0]+1));//7

答案:
1.6
arr在sizeof中为整个数组,求出的是整个数组的大小,单位是字节,结果为6字节
2.4
arr此时为首元素地址,类型为char*,字符指针+0会跳过0个字符大小,此时仍指向首元素地址,地址大小为4字节
3.1
arr此时为首元素地址,类型为char*,解引用arr会访问一个char大小的内容,为数组第一个元素,大小为1字节
4.1
arr[1]代表数组第二个元素,类型为char,大小为1字节
5.4
arr代表整个数组,取出的是整个数组的地址,地址的大小为4字节
6.4
arr代表整个数组,取出的是整个数组的地址,当地址进行±运算时,与指针类型有关,数组指针的类型为 char (*)[6] ,数组指针+1会跳过一个数组,在这就是跳过6个字符,运算后的结果依然是地址,大小为4
7.4
&arr[0]代表第一个元素的地址,当地址进行±运算时,与指针类型有关,字符指针+1会跳过一个字符,&arr[0]+1代表第二个元素地址,大小为4字节
一一一一一一一一一分割线一一一一一一一一一一
第三组:

char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", strlen(arr));//1
printf("%d\n", strlen(arr+0));//2
printf("%d\n", strlen(*arr));//3
printf("%d\n", strlen(arr[1]));//4
printf("%d\n", strlen(&arr));///5
printf("%d\n", strlen(&arr+1));//6
printf("%d\n", strlen(&arr[0]+1));//7

答案:
1.随机值
arr为首元素地址,但arr数组中没有’\0’,故结果为随机值
2.随机值
arr为首元素地址,当地址进行±运算时,与指针类型有关,字符指针+0会向前跳过0个字符,地址不变,而arr数组中没有’\0’,故结果为随机值
3.err
arr为首元素地址,*arr为第一个元素’a’,传入strlen中会把a的ASCII码值当做地址,而此地址为野指针,会报错。
4.err
arr[1]为数组第二个元素’b’,传入strlen中会把b的ASCII码值当做地址,而此地址为野指针,会报错。
5.随机值
arr为整个数组地址,首先要知道strlen的参数为在这里插入图片描述
传入strlen后数组指针会被强转为char *类型,而他们两的值是一样的,故结果为随机值
6.随机值
arr为整个数组地址,当地址进行±运算时,与指针类型有关,数组指针+1会向前跳过一个数组,故此时地址为跳过一个数组的地址,由于不清楚什么时候遇到’\0’,故为随机值
7.随机值
&arr[0]为首元素地址,当地址进行±运算时,与指针类型有关,字符指针+1会向前跳过一个字符,故此时地址为跳过一个字符的地址,由于不清楚什么时候遇到’\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));

答案:
1.7
arr代表整个数组,在sizeof中会求出整个数组的大小,为7字节,因为写成字符串形式自带’\0’
2.4
arr为首元素地址,当地址进行±运算时,与指针类型有关,字符指针+1会向前跳过1个字符,故此时地址为跳过一个字符的地址,则结果为4
3.1
arr为首元素地址,类型为char* ,解引用时会访问一个字节,为’a’,字符a的大小为1的字节
4.1
arr[1]为数组中第二个元素的地址,为char类型,大小为1字节
5.4
arr为整个数组地址,&arr为整个元素的地址,是地址就是4个字节
6.4
arr为整个数组地址,&arr为整个元素的地址,类型为char(*)[7],数组指针+1会跳过1个数组,&arr+1为跳过一个数组后的地址,是地址大小就是4字节
7.4
&arr[0]为首元素地址,当地址进行±运算时,与指针类型有关,字符指针+1会向前跳过1个字符,故此时地址为跳过一个字符的地址,则结果为4
一一一一一一一一一分割线一一一一一一一一一一
第五组:

char arr[] = "abcdef";
printf("%d\n", strlen(arr));//1
printf("%d\n", strlen(arr+0));//2
printf("%d\n", strlen(*arr));//3
printf("%d\n", strlen(arr[1]));//4
printf("%d\n", strlen(&arr));//5
printf("%d\n", strlen(&arr+1));//6
printf("%d\n", strlen(&arr[0]+1));//7

答案:
1.6
arr为首元素地址,因为字符串自带\0,故传入首元素地址后会得到\0之前的字符串个数,也就是6
2.6
arr为首元素地址,当地址进行±运算时,与指针类型有关,字符指针+0会向前跳过0个字节,故传入首元素地址后会得到\0之前的字符串个数,也就是6
3.err
arr为首元素地址,解引用后得到字符a,会将字符a的ASCII码值当做地址传入strlen,由于此地址为野指针,故会error
4.err
arr[1]为字符b,会将字符b的ASCII码值当做地址传入strlen,由于此地址为野指针,故会error
5.6
arr为整个数组地址,&arr为整个元素的地址,传入strlen后数组指针会被强转为char *类型,而他们两的值是一样的,故结果为6

6.随机值
arr为整个数组地址,&arr为整个元素的地址,类型为char(*)[7],数组指针+1会跳过1个数组,&arr+1为跳过一个数组后的地址,传入strlen后数组指针会被强转为字符指针类型
7.5
arr[0]为数组首元素,&arr[0]为首元素地址,当地址进行±运算时,与指针类型有关,字符指针+1会向前跳过1个字符,故得到的结果为5
一一一一一一一一一分割线一一一一一一一一一一
第六组:

char *p = "abcdef";
printf("%d\n", sizeof(p));//1
printf("%d\n", sizeof(p+1));//2
printf("%d\n", sizeof(*p));//3
printf("%d\n", sizeof(p[0]));//4
printf("%d\n", sizeof(&p));//5
printf("%d\n", sizeof(&p+1));//6
printf("%d\n", sizeof(&p[0]+1));//7

答案:
1.4
p为字符指针,是指针大小就为4字节
2.4
p+1指向数组第二个元素,但仍旧是地址,是地址就是4字节
3.1
p为字符首元素地址,解引用得到首元素,类型是char,故大小为1字节
4.1
p[0]可以写成*(p+0),也就是数组第一个元素,类型是char,大小是1字节
5.4
&p是字符指针的地址,是地址大小就为4字节
6.4
&p是地址的地址,当地址进行±运算时,与指针类型有关,&p的类型为char**,+1会跳过一个char*类型的,但仍旧是地址,为4字节
7.4
&p[0]为首元素地址,类型是字符指针,+1会跳过一个字节,但仍旧是地址,为4字节
一一一一一一一一一分割线一一一一一一一一一一
第七组:

char *p = "abcdef";
printf("%d\n", strlen(p));//1
printf("%d\n", strlen(p+1));//2
printf("%d\n", strlen(*p));//3
printf("%d\n", strlen(p[0]));//4
printf("%d\n", strlen(&p));//5
printf("%d\n", strlen(&p+1));//6
printf("%d\n", strlen(&p[0]+1));//7

答案:
1.6
p为字符串的首元素地址,传入strlen中得到6
2.5
p为字符串首元素地址,当地址进行±运算时,与指针类型有关,字符指针会跳过一个字节指向b,将b的地址传入strlen中得到5
3.err
p为字符首元素地址,解引用得到首元素,会将字符a的ASCII码值当做地址传入strlen,由于此地址为野指针,故会error
4.err
p[0]为字符a,会将字符a的ASCII码值当做地址传入strlen,由于此地址为野指针,故会error
5.随机值
&p得到的是字符指针的地址,由于不知道何时出现\0,故为随机值
6.随机值
&p是地址的地址,当地址进行±运算时,与指针类型有关,&p的类型为char**,+1会跳过一个char*类型的,由于不知道何时出现\0,故为随机值
7.5
&p[0]为首元素地址,类型是字符指针,+1会跳过一个字节,故得到5

二维数组:

int a[3][4] = {0};
printf("%d\n",sizeof(a));//1
printf("%d\n",sizeof(a[0][0]));//2
printf("%d\n",sizeof(a[0]));//3
printf("%d\n",sizeof(a[0]+1));///4
printf("%d\n",sizeof(*(a[0]+1)));//5
printf("%d\n",sizeof(a+1));//6
printf("%d\n",sizeof(*(a+1)));//7
printf("%d\n",sizeof(&a[0]+1));//8
printf("%d\n",sizeof(*(&a[0]+1)));//9
printf("%d\n",sizeof(*a));//10
printf("%d\n",sizeof(a[3]));//11

开始之前要明确几个概念:
二维数组是数组的数组
每一行的数组名是a[0],a[1],a[2]
在这里插入图片描述

答案:
1.48
a是二维数组的数组名,在sizeof中表示整个数组,那么得到的结果就是整个数组的大小,为48字节
2.4
a[0][0]为第一个元素,类型是int,故大小为4字节
3.16
a[0]是第一行的数组名,数组名放在sizeof中就代表第一行整个数组,为16字节
4.4
a[0]是第一行数组名,他不在sizeof中,也没有取地址,故为第一行首元素地址,当地址进行±运算时,与指针类型有关,+1后指向第一行第二个元素,但依旧为地址,那就是4字节
5.4
a[0]+1为第一行第二个元素地址,解引用后成为int类型的元素,故为4字节
6.4
a不在sizeof中,也没有取地址,故为首元素地址,二维数组的首元素地址为第一行数组的地址,类型为int(*)[4],+1跳过一个4字节的数组,指向第二行数组,但依旧是地址,故为4字节大小
7.16

此题有两种方法:
1.a+1为第二行数组的地址,解引用后就是整个第二行数组,则sizeof后就是第二行整个数组的大小,为16字节
2.*(a+1)就是a[1],a[1]就是第二行的数组名,放在sizeof中就是求第二行整个数组的大小,为16字节

8.4
&a[0]是第一行数组的地址,+1后就是第二行数组的地址,是地址的话就是4字节
9.16
解引用第二行数组地址找到的就是第二行整个数组,sizeof后就是16字节
10.16
a不在sizeof中,也没有取地址,故为首元素地址,即为第一行数组地址,解引用就是整个第一行数组,大小为16字节
11.16
sizeof是操作符,不会执行,故也不会越界,在编译时就会算出结果

欢迎讨论与纠错,下篇也是笔试题,但是不是关于sizeof与strlen,而是会更灵活的运用

http://www.lryc.cn/news/168608.html

相关文章:

  • Vue中组件的三种注册方式
  • docker 和k8s 入门
  • 基于Yolov8的交通标志牌(TT100K)识别检测系统
  • 使用Python编写一个多线程的12306抢票程序
  • DT Paint Effects工具(三)
  • SpringBoot整合Mybatis
  • Java后端使用POST请求向mysql中插入Json数据的问题
  • 豆瓣图书评分数据的可视化分析
  • SpringBoot整合Easy-ES操作演示文档
  • IDEA控制台取消悬浮全局配置SpringBoot配置https
  • MySQL8--my.cnf配置文件的设置
  • Qt基于paintEvent自定义CharView
  • Mac FoneLab for Mac:轻松恢复iOS数据,专业工具助力生活
  • 代码随想录二刷day30
  • 工业检测 ocr
  • LVS负载均衡群集
  • 安卓截屏;前台服务
  • C++ PrimerPlus 复习 第八章 函数探幽
  • JavaScript-Ajax-axios-Xhr
  • 怎样查看kafka写数据送到topic是否成功
  • 腾讯mini项目-【指标监控服务重构】2023-08-16
  • PTA:7-3 两个递增链表的差集
  • 智能合约漏洞案例,DEI 漏洞复现
  • Attention is all you need 论文笔记
  • Hdoop伪分布式集群搭建
  • java临时文件
  • C++中的<string>头文件 和 <cstring>头文件简介
  • 安装MySQL
  • 输入学生成绩,函数返回最大元素的数组下标,求最高分学生成绩(输入负数表示输入结束)
  • 常用音频接口:TDM,PDM,I2S,PCM