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


    目录

    回顾:

    数组面试题:

    一维数组:

    题型一:

    题型二:

    题型三:

    题型四:

    二维数组:


    回顾:

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

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

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

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

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

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

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

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

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

    数组面试题

    一维数组:

    题型一:

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

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

    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]

    前者表示整形指针变量。

    后者表示数组指针变量

    剩下的内容可以参考上述讲解,

    答案即输出内容如下:

    题型二:

    1. char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
    2. printf("%d\n", sizeof(arr)); //1
    3. printf("%d\n", sizeof(arr + 0)); //2
    4. printf("%d\n", sizeof(*arr)); //3
    5. printf("%d\n", sizeof(arr[1])); //4
    6. printf("%d\n", sizeof(&arr)); //5
    7. printf("%d\n", sizeof(arr + 1)); //6
    8. printf("%d\n", sizeof(&arr[0] + 1)); //7
    9. printf("%d\n", strlen(arr)); //8
    10. printf("%d\n", strlen(arr + 0)); //9
    11. printf("%d\n", strlen(*arr)); //10
    12. printf("%d\n", strlen(arr[1])); //11
    13. printf("%d\n", strlen(&arr)); //12
    14. printf("%d\n", strlen(&arr + 1)); //13
    15. 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部分的答案为:

    题型三:

    1. char arr1[] = "abcdef";
    2. printf("%d\n", sizeof(arr1)); //1
    3. printf("%d\n", sizeof(arr1 + 0)); //2
    4. printf("%d\n", sizeof(*arr1)); //3
    5. printf("%d\n", sizeof(arr1[1])); //4
    6. printf("%d\n", sizeof(&arr1)); //5
    7. printf("%d\n", sizeof(&arr1 + 1)); //6
    8. printf("%d\n", sizeof(&arr1[0] + 1)); //7
    9. printf("%d\n", strlen(arr1)); //8
    10. printf("%d\n", strlen(arr1 + 0)); //9
    11. printf("%d\n", strlen(*arr1)); //10
    12. printf("%d\n", strlen(arr1[1])); //11
    13. printf("%d\n", strlen(&arr1)); //12
    14. printf("%d\n", strlen(&arr1 + 1)); //13
    15. 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部分为:

    题型四:

    1. char* p = "abcdef";
    2. printf("%d\n", sizeof(p));
    3. printf("%d\n", sizeof(p + 1));
    4. printf("%d\n", sizeof(*p));
    5. printf("%d\n", sizeof(p[0]));
    6. printf("%d\n", sizeof(&p));
    7. printf("%d\n", sizeof(&p + 1));
    8. printf("%d\n", sizeof(&p[0] + 1));
    9. printf("%d\n", strlen(p));
    10. printf("%d\n", strlen(p + 1));
    11. printf("%d\n", strlen(*p));
    12. printf("%d\n", strlen(p[0]));
    13. printf("%d\n", strlen(&p));
    14. printf("%d\n", strlen(&p + 1));
    15. printf("%d\n", strlen(&p[0] + 1));

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

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

    sizeof部分答案:

    strlen部分答案:

    二维数组

    1. int b[3][4] = { 0 };
    2. printf("%d\n", sizeof(b)); //1
    3. printf("%d\n", sizeof(b[0][0])); //2
    4. printf("%d\n", sizeof(b[0])); //3
    5. printf("%zd\n", sizeof(b[0] + 1)); //4
    6. printf("%d\n", sizeof(*(b[0] + 1))); //5
    7. printf("%d\n", sizeof(b + 1)); //6
    8. printf("%d\n", sizeof(*(b+1))); //7
    9. printf("%d\n", sizeof(&b[0] + 1)); //8
    10. printf("%d\n", sizeof(*(&b[0] + 1))); //9
    11. printf("%d\n", sizeof(*b)); //10
    12. 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博客

  • 相关阅读:
    ai智能写作软件哪个好-AI智能写作软件的类型标准
    启动jar时指定nacos配置
    什么是无人机倾斜摄影?无人机倾斜摄影测量测绘中的应用有哪些?
    .[nicetomeetyou@onionmail.org].faust深入剖析勒索病毒及防范策略
    Linux 任务计划管理
    计算机毕业设计之java+springboot基于vue的游戏分享网站
    C++征途 --- deque容器
    问题:关于醋酸钠的结构,下列说法错误的是() #媒体#媒体
    ss-2.子项目互相访问(order80 -> payment8001)
    mobaXterm使用pycharm
  • 原文地址:https://blog.csdn.net/weixin_72917087/article/details/132952767