数组和指针经典笔试题讲解

目录

创作不易,如对您有帮助,还望一键三连,谢谢!!!

1.sizeof和strlen的对比

1.1sizeof

1.2strlen

1.3sizeof和strlen对比

2.数组笔试题讲解

数组名的理解

2.1一维数组

2.2字符数组

题目一:

题目二:

题目三:

2.3二维数组


创作不易,如对您有帮助,还望一键三连,谢谢!!!

今天我们来讲一些数组和指针经典的笔试题。而在讲解这些题目之前,我们得先来回忆一下sizeof和strlen。

1.sizeof和strlen的对比

1.1sizeof

在学习操作符的时候,我们学习了 sizeof , sizeof 计算变量所占内存内存空间大小的,单位是
字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的大小。

注意:sizeof只关注占用内存的大小,并不关注内存中存放的是什么数据。

我们来看下面这段代码:

这段代码运行结果如下:

这个结果验证了上面我们所说的sizeof只关注占用内存空间的大小,并不关注内存中存放的是什么数据。

1.2strlen

strlen是库函数,使用它要包含string.h头文件。函数原型如下:

size_t(const char*str);

 strlen统计的是所传参数str这个地址开始向后,\0 之前字符串中字符的个数。strlen 函数会⼀直向后找 \0 字符,直到找到为止,所以可能存在越界查找。

这些我们之前都讲过,不在赘述。

1.3sizeof和strlen对比

以上表格总结出来了二者之间的差别,希望大家能熟练掌握。

了解了上面的知识的话,接下来我们先来讲解数组的一些笔试题目

2.数组笔试题讲解

在讲解之前,我们再来回忆一下我们之前所讲的一个知识:

数组名的理解

1. sizeof(数组名),这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩。
2. &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表⽰⾸元素的地址。

不在赘述,我们直接看题。

2.1一维数组

这段代码运行结果是什么呢?

我们一个一个来看:

sizeof(数组名),表示整个数组,计算的是整个数组的大小,故答案为16.

这个也是16吗?不是,我们上面讲的是sizeof(数组名)表示整个数组,前提是括号里面单独跟数组名,但是这个却是a+0,有人会说:这有什么区别呢?根据数学的角度来说这俩完全一样嘛。在数学上,这俩完全一样,

但在这里结果却大不相同:这里没有单独跟数组名,所以此时a表示数组首元素的地址,是个指针,类型是int*类型,a+0还是表示数组首元素的大小,但此时sieof内部是个指针,故sizeof会计算该指针的大小,为4\8.

首先看是否满足单独跟数组名,没有

所以此时a表示数组首元素的地址,是个指针,类型是int*类型,对其解引用得到数组首元素,类型为int,故结果为4\8.

同理,a表示数组首元素地址,是个指针,类型是int*类型,a+1表示数组第二个元素的地址,仍是个指针,所以大小为4\8.

a[1]表示数组第二个元素,类型为int,故答案是4,比较简单。

&a,取出的是整个数组的地址,是个地址,大小仍然为4\8.这里千万不要带着有色眼镜去看,认为整个数组的地址和一个元素的地址不一样!两个都是地址,怎么会不一样呢?只要是地址,大小就是4\8个字节。

这里有两种理解思路:

1.*和&相互抵消掉,所以单独剩下a,表示sizeof(数组名),所以表示整个数组,计算的是整个数组的大小,故答案为16.

2.&a,取出的是整个数组的地址,类型是int(*)[4],是个数组指针,表示指向一个含有 4 个 int 元素的数组的指针。*(&a)对指针解引用,得到整个数组,所以结果是16.

&a,取出了整个数组的地址,&a+1是跳过整个数组后的那个位置的地址,是地址就是4/8个字节,

示意图如下:

 

a[0]表示数组第一个元素,&a[0]得到第一个元素的地址,是个地址,是地址就是4/8个字节。

至此,我们完成了第一道题目,那么接下来我们来看一下字符数组。

2.2字符数组

题目一

我们来一 一讲解。

sizeof(数组名),表示整个数组,计算的是整个数组的大小,故结果是6个字节。比较简单。

与上面我们讲的一维数组的第三个一模一样,arr+0是个地址,是地址大小就是4\8个字节

没有满足sizeof(数组名)和&数组名,所以此时arr表示数组首元素的地址,类型为char*,对其解引用访问到数组第一个元素,大小为1个字节

计算数组第二个元素大小,为1个字节

&arr取出的是整个数组的地址,但是还是个地址,是地址大小就是4\8个字节

&arr+1, 跳过整个数组,指向了数组后边的空间,4/8个字节

第二个元素的地址,是地址就是4/8字节

题目二:

这段代码运行结果又是如何呢?首先看到这段代码,我们就应该看到:arr数组这种初始化方式,数组末尾没有\0,有可能会引发strlen的越界访问。

答案和讲解如下图所示:

题目三:

答案直接给出,和我们上面讲解的题目非常相似,这里就不在赘述。

相对于题目二来说,这个arr数组的初始化方式,会在数组末尾总添加一个\0,题目解析如下图所示:

这里唯一需要注意的是:

&arr得到的是整个数组的地址,类型为char(*)[6],加一跳过整个数组。

接下来,我们来看最后一道题目,有关二维数组的题目。

2.3二维数组

这道题目还是有一定难度的,是我们今天学习的最难的一道题目,我们来一个一个讲解:

sizeof(数组名),表示整个数组,计算的是整个二维数组的大小,结果为48个字节

a[0][0]表示数组第一个元素,大小为4个字节,没什么好讲的。

仔细看这个题目,a[0]表示的是什么呢?a[0]是数组名吗?

我们来回忆一下二维数组:

对于一个二维数组int a[3][4],它的类型是int[3][4],sizeof(数组名)和&数组名表示整个二维数组,而sizeof(a[0])和&a[0]表示的是第0行的整行数组,也就是说a[0]也相当于数组名,只不过它是第0行的数组名。

所以在这里sizeof(a[0])表示的是第一行数组,计算的是数组第一行的大小,结果为16个字节。

此时sizeof没单独跟a[0],a[0]表示数组首元素的地址,a[0]+1表示数组第二个元素的地址,结果为4\8个字节

此时sizeof没单独跟a[0],a[0]表示数组首元素,a[0]+1表示数组第二个元素,在对其解引用得到第二个元素,结果是4个字节。

来看这一组,此时a不是上面所说的两种情况,表示的是二维数组首元素的地址,也就是二维数组第一行的地址(这里要能和a[0]+1作区分),a+1表示第二行的地址,是个地址,结果为4\8个字节;而8对其进行了解引用,得到了数组第二行的元素,故结果为16个字节。

这一组,&a[0]就是&加上第一行的数组名,得到的是第一行的地址,加一跳过一行,得到第二行的地址,是个地址结果为4\8个字节

10对&a[0]+1进行了解引用操作,得到了第二行的元素,故结果为16个字节。

a作为数组名并没有单独放在sizeof内部,a表示数组首元素的地址,是二维数组首元素的地址,也就是第一行的地址,*a就是第一行,计算的就是第一行的大小,16字节

a[3]细心的小伙伴一看,a数组不是只有三行,最多也就是a[2]吗?a[3]是什么鬼。

确实是这样,a[3]不属于数组a,但a[3]无需真实存在

我们上面讲sizeof时就说过sizeof只关心所占内存大小,不关心里面所放数据,sizeof仅仅通过类型的推断就能算出长度a[3]是第四行的数组名,单独放在sizeof内部,计算的是第四行的大小,16个字节。

这与sizeof(int)和sizeof(3+4)结果都是4个字节是一个道理。

至此,我们讲完了数组一些经典的笔试题目,相信大家学完后肯定会对数组有更加深刻的理解。

至于指针的笔试题讲解,我们放到下篇来讲。

  • 43
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 29
    评论
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值