攻破《数组与指针》相关笔试题(一)

目录

回顾:

数组面试题:

一维数组:

题型一:

题型二:

题型三:

题型四:

二维数组:


回顾:

我们在之前的blog中有涉及到关于数组名和实现冒泡排序的讲解。

我们这里简单的进行回顾一下:

1.sizeof(数组名)---表示的是整个数组的大小

2.&(数组名)---表示的是取出整个数组的地址

3.除以上两种情况外,其余的数组名都表示数组首元素的地址!!!

以上三点我们需要牢记,并且要记住一句话:

“不要在门缝里看指针,把指针看扁了!”

关于数组名的知识点可以参考一下blog:

关于数组名_无双@的博客-CSDN博客

数组面试题:

一维数组:

题型一:

我们可以先尝试自己做一下一下代码,看看自己想的是否与待会讲解内容一致。

int main()
{
	//T1
	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.

printf("%d\n", sizeof(a));    

对于这一行代码我们可以知道,sizeof内部是字母‘a’,那么‘a’是什么呢?

答案显而易见,‘a’是数组名,所以在这里sizeof(a)计算的就是整个数组的大小!

由于该数组的返回值为int,即数组中每个元素都为整形,已知一个整形占4个字节,

所以我们不难算出最后的结果为4 * 4 = 16。

一共是

16字节。

2.

printf("%d\n", sizeof(a + 0));

对于这一行的代码来说呢,我们先判断sizeof内部是什么?

在这里,sizeof内部是“a + 0”,所以它不满足sizeof(数组名)这种例子。

正因如此,这里的“a + 0”表示的就是数组首元素的地址。

既然是地址,那么它的大小

在32位的机器上就是4个字节。

在64位的机器上就是8个字节。

所以该题的答案就是

4或者8字节。

3.

printf("%d\n", sizeof(*a));

对于这道题,第一步就是判断sizeof内部,内部不是只有数组名,所以不满足数组名的个例。

那么*a表示什么呢?

我们其实可以换一种表示方式,即

*a == *(a + 0)== a[0]

a[0]表示的意思就是数组的第一个元素。

那么既然是元素,又因为它是整形变量,所以它占4个字节。

因此结果为

4字节。

6.

	printf("%d\n", sizeof(&a));

对于这道题来说,我们不仅仅要注意sizeof内部的值。

确实,sizeof

内部现在不是仅为数组名a了,是&a,那么肯定会有人觉得&a表示的就是整个数组的地址,所以答案是16字节。

这种想法大错特错!

既然我们已经知道,&数组名表示的是“取出整个数组的地址”,那么既然是地址,

地址肯定仅仅占4或8个字节。

所以这道题的答案为:

4或8字节。

根据以上内容,我们可以了解到“数组的地址”和“数组首元素的地址”,他们的本质区别是类型的区别。

即:

数组名a --- int*

&数组名a --- int(*)[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

	printf("%d\n", strlen(arr));              //8
	printf("%d\n", strlen(arr + 0));          //9
	printf("%d\n", strlen(*arr));             //10
	printf("%d\n", strlen(arr[1]));           //11
	printf("%d\n", strlen(&arr));             //12
	printf("%d\n", strlen(&arr + 1));         //13
	printf("%d\n", strlen(&arr[0] + 1));      //14

2.

	printf("%d\n", sizeof(arr + 0));

对于该题目,先判断sizeof内部是否只有数组名arr。

对于“arr + 0”,

要注意的是,这里表示的是首元素的地址,与指针变量是int*还是char*无关!!!

要记住,

指针变量大小和类型无关!!!

不管什么类型的指针变量,大小都是4或者8个字节。

指针变量是用来存放地址的,

地址存放需要多大空间,指针变量大小就是多少字节!!

既然是地址,那么它都占4字节或者8字节。所以答案为:

4或8字节

8.

printf("%d\n", strlen(arr));

strlen(const char* str) 

对于strlen的题目,我们要时时刻刻注意的是——'\0',作为一个字符串元素个数统计的函数,他的结束标志是当它访问到‘\0’时,就结束遍历并返回统计到的个数。

那么对于该题,arr表示的数组首元素的地址,意思就是说strlen会找到数组首元素的地址,再从首元素往后进行遍历统计,直到访问到‘\0’。

但是该数组不存在'\0',那么strlen就会继续在内存中寻找‘\0’。

由于‘\0’的地址会随着每次编译发生变化,所以每次打印出来的值都不一样,

所以strlen会统计出随机值。

所以该题答案为:

随机值。

10.

printf("%d\n", strlen(*arr));

对于此题目,*arr就是首元素,站在strlen的角度上,strlen会认为传参进去的arr - ‘97’该ASCll码值就是地址,当97作为地址,就相当于strlen对内存直接进行访问,那么就是非法访问,程序会崩掉。

因此程序会崩掉。

11题同理。

补充一下,&arr——char(*)[6]

如果是strlen(&arr)则会报告错误:“简介级别不同”

因此该题型中strlen部分的答案为:

sizeof部分的答案为:

题型三:

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

	printf("%d\n", strlen(arr1));                //8
	printf("%d\n", strlen(arr1 + 0));            //9
	printf("%d\n", strlen(*arr1));               //10
	printf("%d\n", strlen(arr1[1]));             //11
	printf("%d\n", strlen(&arr1));               //12
	printf("%d\n", strlen(&arr1 + 1));           //13
	printf("%d\n", strlen(&arr1[0] + 1));        //14

1.

printf("%d\n", sizeof(arr1)); 

对于该题目来说,先判断sizeof内部,由题可知sizeof(arr1),内部数据为数组名arr1,所以arr1表示去出整个数组的大小,又该数组的返回值为char类型,所以该数组的每个元素为char类型,char类型在内存中占1个字节。

在这里要注意的是,该数组里存放的是一个字符串,因此不可以漏掉‘\0’。

所以答案为 7 * 1

7字节。

13.

对于strlen(&arr1 + 1),画图则会好理解些,图如下:

蓝色箭头所指向的就不是数组中的内容了,所以最后答案就是

随机值。

其它提醒均与上述两种题型相似,在这里不进行过多的赘述。

答案如下:

sizeof部分:

strlen部分为:

题型四:

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

对于这道题,利用画图可以很好的解释以上全部代码。

要注意的是,该题型为常量字符串,利用指针来表示字符串。

sizeof部分答案:

strlen部分答案:

二维数组:

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

对于二维数组,其实二维数组就是一维数组的数组。

我们可以理解为如图排列的:

但是二维数组在内存中实际上是连续排序的:

1.

printf("%d\n", sizeof(b)); 

所以对于第一行代码来说,sizeof内部是数组名b,所以b此时代表的是整个数组,所以b占4 * 4 *4个字节,即答案为:

48字节。

3.

printf("%d\n", sizeof(b[0]));

b[0]是第一行一位数组的数组名,计算的是整个第一行数组的大小。

所以答案为:

4 * 4 = 16字节。

4.

	printf("%zd\n", sizeof(b[0] + 1));

b[0]此时并非单独存放在sizeof内部,因此b[0]表示表示第一行数组首元素的地址,也就是第一行第一个元素的地址,即&b[0][0]

所以当b[0] + 1 <——>&b[0][1]

所以既然是地址,答案就是

4或8个字节。

6.

printf("%d\n", sizeof(b + 1)); 

b作为二维数组的数组名,并没有单独存放在sizeof内部,所以b就是数组首元素的地址,即第一行的地址,所以b的类型为——int(*)[4]

故b + 1是第二行的地址

既然是地址所以答案为:

4或8字节。

8.

printf("%d\n", sizeof(&b[0] + 1));

b[0]是第一行的数组名,&b[0]取出的是数组的地址,取出的是第一行这个一维数组的地址,类型就是int(*)[4],那么&b[0] + 1就是第二行的地址。

既然是地址,所以答案为:

4或8字节。

10.

printf("%d\n", sizeof(*b)); 

b并非单独存放在sizeof内部,b表示首元素的地址,也就是第一行的地址。

*b代表的就是第一行,也就是相当于是第一行的数组名。

*b——>*(b + 0)——>b[0]。

补充:

*(b + 1) == b[1] 即第二行的数组名。

总结:

以上的代码就是笔试面试题中关于数组的命题提醒,下去应当及时复习这一部分,并对其中的题型熟烂于心,在每一次看答案甚至解析之前动手做一做。

记住:

“坐而言不如起而行!”

“Actions speak louder than words!”

点击下面链接,即可访问“攻破《数组与指针》相关面试题(二)”

攻破《数组与指针》相关笔试题(二)_无双@的博客-CSDN博客

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

无双@

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

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

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

打赏作者

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

抵扣说明:

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

余额充值