栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

指针笔试题解析(非编程题)上篇

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

指针笔试题解析(非编程题)上篇

目录

题目组一:一维整型数组

题目组二:一维字符型型数组(sizeof)

题目组三:一维字符型数组(strlen)

题目组四:字符串(sizeof)

题目组五:字符串(strlen)

题目组六:指针指向字符串

 题目组七:整型二维数组(sizeof)


引言

指针的相关内容我在前面已经铺垫了很多了,从初阶到进阶,有兴趣的可以去看一下我之前的博客:认识初阶指针_SAKURAjinx的博客-CSDN博客     全站最细的C语言指针进阶_SAKURAjinx的博客-CSDN博客

今天我们来看一下指针笔试相关的面试题(非编程类)。

在进行解析之前我们再简单梳理一下相关的知识:

一、sizeof是计算变量和类型的大小,它是操作符不是函数;strlen是计算字符串的长度,遇到 ' ' 结束,它是函数且只能用于字符串的计算。

二、数组名代表数组首元素地址,但有两个例外:

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

2、&数组名,这里也是代表整个数组

题目组一:一维整型数组
int main()
{
	int a[] = { 1,2,3,4 };
	printf("%dn", sizeof(a));
	printf("%dn", sizeof(a+0));
	printf("%dn", sizeof(*a));
	printf("%dn", sizeof(a+1));
	printf("%dn", sizeof(a[1]));
	printf("%dn", sizeof(&a));
	printf("%dn", sizeof(*&a));
	printf("%dn", sizeof(&a+1));
	printf("%dn", sizeof(&a[0]));
	printf("%dn", sizeof(&a[0]+1));

	return 0;
}

第一个:sizeof(a),如上文所述,sizeof(数组名)计算的是整个数组的大小,所以是4*4=16

第二个:sizeof(a+0),数组名不是单独放在sizeof里面,所以代表的是首元素地址,地址也就是指针,只要是指针,不管什么类型在32位平台下就是4,在64位平台下就是8。 ( 以下皆默认32位平台下)

第三个:sizeof(*a), arr是首元素地址,*解引用取出数组a的地址,拿到的就是第0个元素,也就是a[0],数组是整型数组,每个元素是整型int,所以是4.

第四个:sizeof(a+1),首元素地址+1,跳过一个元素,即第1个元素的地址,a[1]的地址,为4。

第五个:sizeof(a[1]), 是第一个元素,类型为int,大小为4.

第六个:sizeof(&a),之前说&a是整个数组的地址,那是不是16呢?答案不是16,是4,虽然取出的是整个数组的地址,但是只要是地址,32位平台下就是4.

第七个:sizeof(*&a),先取出整个数组的地址,再对其解引用,就是整个数组,所以答案是16.

也可以这么理解:&后再*,这两个就抵消了,所以直接等于sizeof(a)。

第八个:sizeof(&a+1),取出整个数组的地址后+1,跳过整个数组长度,也就是4个整型元素,

指向的是a[4]的地址,所以大小是4.

第九个:sizeof(&a[0]),第0个元素取地址,取出的是地址,大小是4.

第十个:sizeof(&a[0]+1),即第1个元素的地址,也就是&a[1],大小是4.

整型一维数组相对简单,下面来看字符数组。

题目组二:一维字符型型数组(sizeof)
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%dn", sizeof(arr));
	printf("%dn", sizeof(arr + 0));
	printf("%dn", sizeof(*arr));
	printf("%dn", sizeof(arr[1]));
	printf("%dn", sizeof(&arr));
	printf("%dn", sizeof(&arr + 1));
	printf("%dn", sizeof(&arr[0] + 1));

第一个:sizeof(arr), 计算整个数组的大小,字符数组一个元素大小是1,所以结果是6.

第二个:sizeof(arr+0),首元素地址,不管是char还是int,大小都是4.

第三个:sizeof(*arr),即arr[0],大小是1.

第四个:sizeof(arr[1]),大小是1。

第五个:sizeof(&arr),取出整个数组的地址,大小是4.

第六个:sizeof(&arr+1),跳过的整个数组,指向arr[6]的地址,大小是4.

第七个:sizeof(&arr[0]+1),将数组第0个元素地址取出,往后跳一位,即&arr[1],大小是4.

题目组三:一维字符型数组(strlen)
	printf("%dn", strlen(arr));
	printf("%dn", strlen(arr + 0));
	printf("%dn", strlen(*arr));
	printf("%dn", strlen(arr[1]));
	printf("%dn", strlen(&arr));
	printf("%dn", strlen(&arr + 1));
	printf("%dn", strlen(&arr[0] + 1));

注意strlen是遇到 ' ' 后结束。

第一个:这里不是在sizeof里面,所以arr代表数组首元素,strlen计算从首元素开始数起,字符串的长度,但是不知道哪里碰到 ' ',所以值是未知的随机值。

第二个:和第一个一样,是数组首元素地址,所以也是随机值,且和第一个随机值一样大。

第三个:对arr解引用,即arr[0],注意:这里arr[0]和上面两个不一样,上面是从arr[0]的地址处往后数,碰到 ''结束,这里只是一个元素,一个元素不能用strlen计算,因为strlen是计算字符串的大小,所以这里会报错。

第四个:和上面一个如出一辙,也会报错。也可以这么理解,给的arr[1]实际值是98,也就是给strlen的地址是'98'处的,这是个野指针,不知道指向哪里,所以不能这么用,会报错。

第五个:取出整个数组的地址,也是从首元素地址处开始往后数,所以也是随机值。或者这么理解:&arr的类型是char(*)[ ]  虽然类型和sizeof(arr)的char 不一样,但是传给strlen的时候都被转化成strlen的默认参数类型const char*了,所以是一样的。

第六个:跳过了一个数组大小,指向了arr[6]处的地址,所以是随机值,比第一个随机值小6.

第七个:从第1个元素的地址,所以是随机值,且比第一个随机值小1.

题目组四:字符串(sizeof)
	char arr[] = "abcdef";
	printf("%dn", sizeof(arr));
	printf("%dn", sizeof(arr + 0));
	printf("%dn", sizeof(*arr));
	printf("%dn", sizeof(arr[1]));
	printf("%dn", sizeof(&arr));
	printf("%dn", sizeof(&arr + 1));
	printf("%dn", sizeof(&arr[0] + 1));

换汤不换药,我们来看一下:

第一个:字符串末尾默认有个 '',所以其实存了7个字符,sizeof(arr)代表整个数组大小,也就是7.

第二个:首元素地址大小为4.

第三个:第0个元素arr[0],大小是1.

第四个:第一个元素大小是1.

第五个:大小是4.

第六个:跳过一整个数组,指向arr[7]的地址,大小是4.

第七个:第一个元素的地址,大小是4.

题目组五:字符串(strlen)
	printf("%dn", strlen(arr));
	printf("%dn", strlen(arr + 0));
	printf("%dn", strlen(*arr));
	printf("%dn", strlen(arr[1]));
	printf("%dn", strlen(&arr));
	printf("%dn", strlen(&arr + 1));
	printf("%dn", strlen(&arr[0] + 1));

第一个:这里有 ' '了,从首元素地址开始数,字符串长度为6.

第二个:和上面一样,6.

第三个:会报错,题目三讲了。

第四个:报错。

第五个:和题目三中一样,值为6.

第六个:跳过字符串(包括 ' '),所以是随机值。

第七个:arr[1]处的地址,长度是6-1=5.

题目组六:指针指向字符串
	char* p = "abcdef";
	printf("%dn", sizeof(p));
	printf("%dn", sizeof(p + 0));
	printf("%dn", sizeof(*p));
	printf("%dn", sizeof(p[1]));
	printf("%dn", sizeof(&p));
	printf("%dn", sizeof(&p + 1));
	printf("%dn", sizeof(&p[0] + 1));

	printf("%dn", strlen(p));
	printf("%dn", strlen(p + 0));
	printf("%dn", strlen(*p));
	printf("%dn", strlen(p[1]));
	printf("%dn", strlen(&p));
	printf("%dn", strlen(&p + 1));
	printf("%dn", strlen(&p[0] + 1));

这里不是将"abcdef"传给指针变量p,而是将字符串的首元素地址传给p。

sizeof :

第一个:指针变量p是字符串首元素地址,sizeof(p)就是4.

第二个:和第一个一样,首元素地址,大小为4.

第三个:对p解引用,拿到的是第0个元素,' a ' ,大小是1。

第四个:即字符串第1个元素' b ',大小是1.

第五个:对地址取地址,可以理解为二级指针,大小是4.

第六个:取p的地址,+1跳过p,还是个地址,大小是4.

 第七个:p[0]是第0个字符,&p[0]是第0个字符的地址,+1就是第一个字符的地址,大小是4.

strlen:

第一个:从字符串首元素地址开始数,字符串长度为6.

第二个:和第一个一样,字符串长度为6.

第三个:第0个元素,即'a',报错。

第四个:第一个元素,'b',报错。

第五个:取地址的地址,拿到的是变量p的地址,变量p里存的是字符串的地址,这里拿到的新的地址和字符串就没有关系了,是新的内存空间,完全不知道什么时候会碰到 '' ,所以字符串长度是随机值。可以借助上图理解

第六个:跳过p的地址空间,即从新的地址空间往后一位开始数碰到 ''为止,也是随机值。但是注意,这里的随机值和上面一个没有关系,不是&p+1就比&p大6,因为我们不知道&p+1什么时候碰到 ''

 有可能第一个就碰到了,也有可能后面才碰到,这片新空间是未知的。

第七个:第一个元素的地址,字符串长度是6-1=5.

 题目组七:整型二维数组(sizeof)

 二维数组要相对复杂一些,但本质还是一样的。

第一个:sizeof(数组名),整个数组的大小,4*12=48.

第二个:首元素的大小,为4.

第三个:数组第0行的大小,就是4*4=16,或者可以站在一维数组的角度理解:

二维数组第0行可以这么表示:a[0][i], i : 0~3 ,同样的,第1行,第2行也可以这么表示,

a[1][i],a[2][i] ,所以a[0]就是二维数组第0行的数组名,数组名单独放在sizeof里计算的是数组的大小,就是a[0]数组的大小,4*4=16.

第四个:a[0]+1不是数组名单独放在sizeof内部,代表的是数组首元素的地址,也就是&a[0][0],+1就是第0行第1个元素的地址,大小是4.

第五个:对上面的地址解引用,就是第0行第1个元素的大小,为4.

第六个:a是二维数组的数组名,不是单独放在sizeof内部,所以是第0行的地址,+1表示第1行的地址,大小为4。

第七个:对第1行的地址解引用,拿到的是整个第1行,大小是4*4=16 。换种理解方式:*(a+1)可以写成a[1],和上面第三个的理解方式一样,计算的是第1行的大小。

第八个:a[0]可以理解成一维数组的数组名,&a[0]就是第0行的地址,+1就是第1行的地址,大小是4,和sizeof(a+1)表示的一样,写法不同,注意要和a[0]+1区别开,容易搞混。

第九个:对上面的接引用,和第七个一样,表示第1行的大小,结果是16.

第十个:对二维数组数组名解引用,也就是对二维数组第0行解引用,拿到的是第0行,计算大小为16.

第十一个:有人可能会说超出数组的范围越界了,其实这里sizeof没有访问第3行的元素,他只是拿了第3行的地址,判断了一下它的类型。sizeof不管你里面是什么,他只关注你的类型, 像       int a=10;  sizeof(int)和sizeof(a)都可以计算,是因为sizeof会自己判断类型,所以很容易判断这里a[3]和上面是一样的类型的,所以得出和a[0]一样的结论是16.

指针的非编程类题目就讲到这里,下一次我们来看笔试的编程题吧!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1000675.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号