【C语言进阶篇】 数组常考笔试题万字解析(下)

简介: 【C语言进阶篇】 数组常考笔试题万字解析(下)

📋 前言

  🌈hello! 各位宝子们大家好啊,数组和指针系列我们全部讲解完毕了,那么今天就来看一下数组的笔试题!

  ⛳️面试题下章就进阶一些的知识了,会用到字符指针和二维指针嗷,俗话说有难度才有进步呢!大家加油嗷!

  📚本期文章收录在《C语言进阶篇》,大家有兴趣可以看看呐

  ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!

🔥 注:上一章链接在这里《数组笔试题万字解析(上)》

💬 数组笔试题解析

在做数组笔试题之前我们需要明白这俩个点就可以了 数组名的意义:

  1. sizeof (数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. & 数组名 ,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。

💭 字符数组笔试题

诶这里我们就对上次的题目做了改变不在使用单个字符赋值了,而是直接使用字符串进行赋值。

  • 而字符数组使用字符串赋值会在结尾自动补上 \0
  • 这样字符数组的长度就会加 1 ,所以数组的长度就是7
  • 知道了这一点我们下面的题目就变得简单起来了

这里我们使用vs2022 调试看一下:

  • 是不是真的和我们想的是一样存储的
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));

✅ 字符数组笔试题解析

printf(“%d\n”, sizeof(arr));

这里计算的是整个数组的大小,而我们字符数组的有 7个字符类型的元素!

  • 所以printf(“%d\n”, sizeof(arr));
  • 的结果为 7

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

这里arr明显不是整个数组的大小,而arr数组名又是首元素的地址。+0 等于没加吗计算的就还是地址!

  • 既然是地址,那么大小就是 4/8
  • printf(“%d\n”, sizeof(arr+0));
  • 结果为 4/8

printf(“%d\n”, sizeof(*arr));

arr是数组首元素的地址,那么在进行解引用不就是找到数组的第一个元素嘛?而数组的第一个元素是 char 类型的!

  • 所以:printf(“printf(”%d\n", sizeof(*arr));
  • 结果为 1

printf(“%d\n”, sizeof(arr[1]));

这里计算的是 arr 字符数组第二个元素的地址所以:

  • printf(“%d\n”, sizeof(arr[1]));
  • 结果为 1

printf(“%d\n”, sizeof(&arr));

这里取出的肯定是整个数组的地址,而整个数组的地址也是地址

  • 既然是地址,那么大小就是 4/8
  • printf(“%d\n”, sizeof(&arr));
  • 结果为 4/8

printf(“%d\n”, sizeof(&arr+1));

这里取整个数组的地址进行加 1,那么就是指向数组的下一个空间的地址。而下一个空间的地址也是地址。

  • 既然是地址,那么大小就是 4/8
  • printf(“%d\n”, sizeof(&arr+1));
  • 结果为 4/8

printf(“%d\n”, sizeof(&arr[0]+1));

这里取出数组第一个元素的地址,然后加一指向的就是数组的第二个元素的地址,而数组第二个元素的地址也是地址!

  • 既然是地址,那么大小就是 4/8
  • printf(“%d\n”, sizeof(&arr[0]+1));
  • 结果为 4/8

💭 字符数组笔试题解析 (strlen)

char arr[] = "abcdef";
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));

✅ 字符数组(strlen)笔试题解析

在做这些面试题之前需要知道 strlen 是干嘛的?strlen 是用来计算字符串长度的

  • 从我们给定地址一直计算到 \0 的位置
  • 找不到 \0 就会一直往后计算字符长度只到找到 \0

printf(“%d\n”, strlen(arr));

这个地方数组是首元素的地址,strlen 是从我们所给定的地址计算一直到 \0, 的长度。这这个字符数组占7个大小,最后一位是 \0

  • 所以:printf(“%d\n”, strlen(arr));
  • 结果为 6

printf(“%d\n”, strlen(arr+0));

这里 arr 还是数组首元素的地址,而加零等于没加,所以传过去的还是指针的首元素地址!

  • 所以:printf(“%d\n”, strlen(arr+0));
  • 结果为 6

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

哦豁这里 arr 是首元素地址,而对地址进行解引用。找到到就是字符数组第一个元素的值,strlen需要的是地址我们怎么能给它传值呢?

  • 所以这里程序就崩溃

printf(“%d\n”, strlen(arr[1]));

这里也是一样我们传过去的是,字符数组第二哥元素的值!strlen需要的是地址我们怎么能给它传值呢?

  • 所以程序还是会崩溃

printf(“%d\n”, strlen(&arr));

这里arr是首元素的地址,等价于&arr。所以我们传过去的还是首元素地址!

  • 所以:printf(“%d\n”, strlen(&arr));
  • 结果为 6

printf(“%d\n”, strlen(&arr+1));

这里arr是元素的地址,首元素的地址 +1 。那么传过去的不就是数组第二个元素的地址。

  • 所以:printf(“%d\n”, strlen(&arr+1));
  • 结果为 5

printf(“%d\n”, strlen(&arr[0]+1));

&arr[0]也是数组第一个元素的地址,加一那么传过去的不就是数组第二个元素的地址。

  • 所以:printf(“%d\n”, strlen(&arr[0]+1));
  • 结果为 5

💭 字符指针笔试题

这里考察就是我们对字符指针的理解了,不知道大家还记得字符指针里面存放的是什么嘛?

  • 字符指针里面存放的是 【 a b c d e f \0】。
  • 这个常量字符串的首地址 a

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”, sizeof( p ));

这里p是个指针变量所以指针大小的字节为 结果为 4/8

  • printf(“%d\n”, sizeof( p ));
  • 结果为 4/8

printf(“%d\n”, sizeof(p+1));

这里指针变量 p 存放的是字符串常量首元素的地址。加一传过去的就是字符串常量,第二个元素的地址。

  • 既然是地址,那么大小就是 4/8
  • printf(“%d\n”, sizeof(p+1));
  • 结果为 4/8

printf(“%d\n”, sizeof(*p));

指针变量 p 是字符串常量首元素的地址,那么解引用也就是 字符 a

  • 所以:printf(“%d\n”, sizeof(*p));
  • 结果为 1

printf(“%d\n”, sizeof(p[0]));

p[0] == *(p+0) ==*p,所以跟上题一样要计算的是字符的大小

  • 所以:printf(“%d\n”, sizeof(p[0]));
  • 结果为 1

printf(“%d\n”, sizeof(&p));

取地址 p 取出来依旧是个地址,没有什么不同的!

  • 既然是地址,那么大小就是 4/8
  • printf(“%d\n”, sizeof(&p));
  • 结果为 4/8

printf(“%d\n”, sizeof(&p+1));

取地址 &p 加一,只是跳到p指向的空间,的下一个地址。所以 (&p+1) 传过去的还是地址

  • 既然是地址,那么大小就是 4/8
  • printf(“%d\n”, sizeof(&p+1));
  • 结果为 4/8

printf(“%d\n”, sizeof(&p[0]+1));

取字符串常量的第一个地址 + 1,传过去的是字符串常量的第二个元素 b 的地址

  • 既然是地址,那么大小就是 4/8
  • printf(“%d\n”, sizeof(&p[0]+1));
  • 结果为 4/8

💭 字符指针(strlen)笔试题

char *p = "abcdef";
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));

✅ 字符指针笔试题解析

printf(“%d\n”, strlen§);

有了开头讲的关于字符指针的描述那就简单多了,字符指针 p 里存放的是字符串常量的首地址。所以传给 strlen 的也是字符串常量的首地址。

  • 所以:printf(“%d\n”, strlen( p ));
  • 结果为 6

printf(“%d\n”, strlen(p+1));

指针p加一就指向了,第二个元素的地址那么计算字符串长度就是从第二个元素开始计算的!

  • 所以:printf(“%d\n”, strlen( p ));
  • 结果为 5

printf(“%d\n”, strlen(*p));

这里还是和前面一样的错误如果对 指针变量进行解引用 那么传过去的就是 指针变量所指向的值 a

  • 所以这里程序会发生崩溃!

printf(“%d\n”, strlen(p[0]));

这里还是和前面一样的问题对指针进行下标访问,就会导致传给 strlen() 的是指针p 所指向空间的值!

  • 所以这里程序会发生崩溃!

printf(“%d\n”, strlen(&p));

这里取出的指针变量的地址,可是指针变量的地址在哪里我们并不会知道所以这里strlen计算的就是随机值!

  • 所以:printf(“%d\n”, strlen(&p));
  • 结果为 随机值

printf(“%d\n”, strlen(&p+1));

取指针变量p 地址,加一那么传过去的指针变量下一个内存单元里面的地址,而这个地址在哪里我们并不知道!

  • 所以:printf(“%d\n”, strlen(&p+1));
  • 结果为 随机值

printf(“%d\n”, strlen(&p[0]+1));

哦豁!这里就要注意了, [ ] 的优先级比 &取地址操作符优先级高。所以我们p[0]先找到常量字符串 a 这个元素在进行取地址,然后加一找到的是第二个元素的地址。

  • 所以:printf(“%d\n”, strlen(&p[0]+1));
  • 结果为 5

💭 二维数组笔试题

int a[3][4] = {0};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a[0][0]));
printf("%d\n",sizeof(a[0]));
printf("%d\n",sizeof(a[0]+1));
printf("%d\n",sizeof(*(a[0]+1)));

✅二维数组笔试题解析

printf(“%d\n”,sizeof(a));

做这种题,我们都做出经验了。只需要先判断 a的类型是什么。他是数组名,又在sizeof()里面单独存在那么 ,sizeof计算的就是整个数组的大小!

  • printf(“%d\n”,sizeof(a));
  • 结果为 3*4*4 = 48

printf(“%d\n”,sizeof(a[0][0]));

这里二维数组 a[0][0] 是第一排第一列的元素值,而这个二维数组又是整形的:

  • 所以:printf(“%d\n”,sizeof(a[0][0]));
  • 结果为 4

printf(“%d\n”,sizeof(a[0]));

这里 a[0]这里是第一排数组的的数组名,又是单独出现在sizeof 里面的。而数组名单独出现在sizeof里面计算的就是整个数组的大小!

  • 所以:printf(“%d\n”,sizeof(a[0]));
  • 结果为 4*4=16

printf(“%d\n”,sizeof(a[0]+1));

a[0] 作为第一行的数组名,没有单独放在sizeof 内部,没有 &a[0] 表示数组首元素的地址,也就是 a[0][0] 的地址所以 a[0]+1 是第一行第二个元素的地址,是地址就是4/8个字节.

  • printf(“%d\n”,sizeof(*(a[0]+1)));

而这里可以这样理解 *() == [ ] 所以(*(a[0]+1)) == a[0][1] 而这指向的就是二维数组的第一行第二个元素!

  • 而这个二位数组又是整形的
  • 所以:printf(“%d\n”,sizeof(a[0]+1));
  • 结果为 4 个字节

💬 指针练习题

好了给大家讲解了这么多的数组常考面试题,关看着博主写可没有用啊!俗话说:光听不练假把式 。那么接下来就给大家留点练习题自己练习检验检验把!

📚 代码演示:

#include <stdio.h>
int main()
{
  int a[3][4] = { 0 };
  printf("%d\n", sizeof(a + 1));
  printf("%d\n", sizeof(*(a + 1)));
  printf("%d\n", sizeof(&a[0] + 1));
  printf("%d\n", sizeof(*(&a[0] + 1)));
  printf("%d\n", sizeof(*a));
  printf("%d\n", sizeof(a[3]));
  return 0;
}

📝全篇总结

✅ 归纳:

☁️ 好了以上就是关于数组类型笔试题要考察的点全部讲解了,不知道大家对数组和数组名是不是有了新的理解呢?

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注

💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖

拜托拜托这个真的很重要!

你们的点赞就是博主更新最大的动力!

有问题可以评论或者私信呢秒回哦。

目录
相关文章
|
9月前
|
存储 人工智能 程序员
一文彻底搞明白C语言的数组
本文详细介绍了C语言中的数组,包括定义、初始化(静态与动态)、存储方式、访问方法及常用操作,如遍历、修改元素和作为函数参数传递。数组是C语言中最基本的数据结构之一,掌握它对编程至关重要。下篇将介绍二维数组,敬请期待!
497 0
一文彻底搞明白C语言的数组
|
11月前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
900 14
|
11月前
|
存储 编译器 C语言
【C语言】数据类型全解析:编程效率提升的秘诀
在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
533 8
|
11月前
|
存储 算法 C语言
【C语言】深入浅出:C语言链表的全面解析
链表是一种重要的基础数据结构,适用于频繁的插入和删除操作。通过本篇详细讲解了单链表、双向链表和循环链表的概念和实现,以及各类常用操作的示例代码。掌握链表的使用对于理解更复杂的数据结构和算法具有重要意义。
3358 6
|
11月前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
862 6
|
11月前
|
存储 网络协议 算法
【C语言】进制转换无难事:二进制、十进制、八进制与十六进制的全解析与实例
进制转换是计算机编程中常见的操作。在C语言中,了解如何在不同进制之间转换数据对于处理和显示数据非常重要。本文将详细介绍如何在二进制、十进制、八进制和十六进制之间进行转换。
1827 5
|
11月前
|
C语言 开发者
【C语言】断言函数 -《深入解析C语言调试利器 !》
断言(assert)是一种调试工具,用于在程序运行时检查某些条件是否成立。如果条件不成立,断言会触发错误,并通常会终止程序的执行。断言有助于在开发和测试阶段捕捉逻辑错误。
293 5
|
8月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
827 29
|
8月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
330 4
|
8月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~