深入学习指针5,与数组和指针相关的笔试题1(C语言)

news2024/11/24 20:40:24

前言

Hello,亲爱的小伙伴们,我又来了,,今天呢我们一起来学习一下C语言关于数组和指针的部分经典题目。如果觉得不错的话不要忘了点赞,收藏、关注,你的支持就是我更新的最大动力!!

好,废话不多说,开始我们今天的正题!! 

1.sizeof和strlen的对比

1.1 sizeof 

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

sizeof只关注内存空间的大小,不在乎内存中存了什么。

 比如:

 #inculde <stdio.h>
 int main()
 {
 int a = 10;
 printf("%d\n", sizeof(a));
 printf("%d\n", sizeof a);
 printf("%d\n", sizeof(int));
 return 0;
 }

1.2 strlen 

strlen是C语言的库函数,功能是求字符串的长度。原型是:

 size_t strlen ( const char * str );

统计的是聪strlen函数的参数str中的这个地址向后,\0之前的字符串中的字符个数。

strlen会一直计数,知道找到  \0   ,可以越界查找!!

也就是说,strlen函数会关注str所指向的字符串的内容!! 

由此,我们比较可得:

2.数组和指针笔试题的讲解 

然后有了上面的知识基础,我们就能来看看这些题了

2.1 一维数组

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

我们可以更具之前学过的知识来判断,这些语句的运行结果分别是是什么呢?

1.我们可知,a为一个一维数组,直接的a在大多数的情况 表示首元素的地址,但有例外,就像第一条语句一样,在操作符sizeof中,a就指代整个数组,计算的是整个数组的大小,单位为字节,所以:

 第一条语句的运行结果为:16

2.第二个语句显然不是单独的数组名出现在sizeof中,所以a+0指代的是数组首元素的地址

地址的所占内存空间大小因平台而异,在VS2022中大致就两种情况 :

     4 or 8

    运行结果为:4 / 8

3.第三条语句 *a指代的就是整个数组的首元素,所以:

结果为 :4

4.  printf("%d\n",sizeof(a+1));

这里a + 1指代的就是第二个元素的地址,故情况与第二条一致!!

     4 or 8


5.  printf("%d\n",sizeof(a[1]));

a[1] ---->*(a + 1),即为一维数组的第二个元素

     4


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

由于&a为整个数组的地址,所以:

4 / 8


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

在这里 解引用+取地址可以相互抵消,就相当于计算整个数组内存占用的大小:
    16
 

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

这三条本质上都是计算的地址的所占空间大小:

   4 / 8

好有了上面的基础,大家能不能试着计算,下面语句的运算结果呢?

 char arr[] = {'a','b','c','d','e','f'};
 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));

好,这些题大家都做对了几道呢 ,这些语句的分析方法与上面的题相似,这里就不再赘述,有问题的小伙伴可以在品论区友好交流哟。

接下来我们再看下面的代码:

char arr[] = {'a','b','c','d','e','f'};
 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函数在访问计数字符串时,只有遇到 ‘\0'时,才会停止,否则会出现越界访问的问题 

现在我们可以先来看看运行后的结果:

 

咦,为什么会这样呢?

在上面的字符数组中没有存放,‘\0' 

哦,我们现在知道了,在发生越界访问时,要遇到了’/0‘,strlen函数就会停止计数,那什么时候strlen函数会停下来呢,这个我们就不知道了,看因为在内存中,可能会有存储在某些位置的'\0'

使strlen函数停下来,故此时返回的随机值!!

那为什么到第三条语句的时候就出现了问题,无法运行出结果呢?

这个我们就可以从strlen函数的功能结构入手了:

 

看到这里我们可以了解到,strlen函数是通过访问地址来往后读取·字符串的,而第三条语句使将数组的首元素给了strlen函数,函数会将传给他的内容当作地址去访问, 而 a 这个字符作为地址是无效的,于是就不能得到结果!!  第三条与第四条语句都是一样的原理!!

那后面的三条语句又是怎么回事呢?

 

上面我们也知道了,&arr在这里就指代整个数组的地址,得到这个地址后strlen函数会逐字节访问,故效果和传给strlen函数arr数组的首地址相同。

倒数第二条语句 &arr + 1,则就相当&arr跳过了整个arr数组的大小个字节,因为arr有6个元素,故可以得到答案。 

最后一条语句就十分简单了,传给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))

怎么样大加能够看出答案吗,其实这些语句与上面的代码分析逻辑基本相符,但是“” 包住的字符串在末尾会自动为字符串添加上 ' \0'因此就不会再出现上面的越界问题。

那大家就自己练习一下吧。

那我就先去喝口茶~~

大家做出来了吗?作者菌就先将大安放到这了,有问题的话,欢迎uu们到评论区友好讨论哟!!

 

好,今天的学习就先到这里,感兴趣的小伙伴不要忘了点一个三连啊,你的支持就是我更新的动力,咱们下期再见。拜拜!! 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1672831.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是页分裂、页合并?

数据组织方式 在InnoDB存储引擎中&#xff0c;表数据都是根据主键顺序组织存放的&#xff0c;这种存储方式的表称为索引组织表(index organized table IOT)。 行数据&#xff0c;都是存储在聚集索引的叶子节点上的。而我们之前也讲解过InnoDB的逻辑结构图&#xff1a; 在I…

华为设备display查看命令

display version //查看版本信息 display current-configuration //查看配置详情 display this //查看当前视图有效配置 display ip routing-table //查看路由表 display ip routing-table 192.168.3.1 //查看去往3.1的路由 display ip interface brief //查看接口下ip信息 dis…

sudo apt-get update失败,怎么解决

本篇文章主要是从我的解决方案出发&#xff0c;因为个体差异性&#xff0c;对大家的帮助可能有限&#xff0c;不过大家也可以作为参考之一。 输入sudo apt-get update&#xff0c;结果一直显示&#xff1a; W: 无法下载 http://mirrors.aliyun.com/ubuntu/dists/jammy-securi…

利用一段代码轻松绕过PHP授权系统

第一步&#xff1a;首先你需要改名全局文件 比如说全局文件 common.php&#xff0c;那么 你将他改为core.php 第二步&#xff1a;创建文件 创建一个文件&#xff0c;和改名前的全局文件名称一样&#xff0c;然后把以下代码复制进去就OK了 代码如下&#xff1a; <?php…

20240513,常用算法(查找,排序,拷贝替换)

做着一些和考试无关的事情 常用查找算法——续 FIND_IF find_if //按条件查找元素&#xff0c;返回迭代器POS / END()find_if(beg,end,_Fred) _Fred函数或谓词&#xff08;返回BOOL类型的仿函数&#xff09; #include<iostream> #include<string> #includ…

【逆天OP懒狗的JAVA自学笔记--5.判断和循环】第二阶段始篇

文章目录 前言一、流程控制语句1.顺序结构&#xff08;最简单&#xff09;2.分支结构2.1 if 语句2.1.1 if语句的三种格式2.1.2 if 的注意事项 2.2 switch 语句2.2.1switch 的扩展知识 3.循环结构3.1 for 循环 扩展小点&#xff1a;//1.求和的变量不能定义在循环的里面&#xff…

韵搜坊(全栈)-- 前后端初始化

文章目录 前端初始化后端初始化 前端初始化 使用ant design of vue 组件库 官网快速上手&#xff1a;https://www.antdv.com/docs/vue/getting-started-cn 安装脚手架工具 进入cmd $ npm install -g vue/cli # OR $ yarn global add vue/cli创建一个项目 $ vue create ant…

WPF使用ItemsControl显示Object的所有属性值

对于上位机开发&#xff0c;我们有时候有这样的需求&#xff1a;如何显示所有的IO点位&#xff1f;比如有10个IO点位&#xff0c;那我们要写10个TextBlock去绑定这10个点位的属性&#xff08;本文暂时不考虑显示的样式&#xff0c;当然也可以考虑&#xff09;&#xff0c;当点位…

OBS插件--图片或视频源随着声音动态缩放

音效动态调整 应用此插件的源可以根据音效声音的高低进行动态的缩放。在本例中&#xff0c;我们在当前的场景里面添加了一个小喇叭的图片源&#xff0c;在这个图片源上引用这款滤镜插件&#xff0c;然后将VLC视频源的音效用于此插件的音效。设置完成后&#xff0c;场景中的小喇…

blender导出gltf模型混乱

最近用户给了几个blender文件&#xff0c;在blender打开是这样的&#xff1a; 我导出成gltf候&#xff0c;在本地打开时&#xff0c;底部发生了改变&#xff1a; 可以看出来&#xff0c;底部由原来的类型box变为了两个平面&#xff0c;后来我查了下blender里的属性设置&#xf…

三更草堂前后端分离个人博客项目的开发笔记

文章目录 项目实战-前后端分离博客系统1.课程介绍2.创建工程3.博客前台3.0 准备工作3.1 SpringBoot和MybatisPuls整合配置测试 3.1 热门文章列表3.1.0 文章表分析3.1.1 需求3.1.2 接口设计3.1.3 基础版本代码实现3.1.4 使用VO优化3.1.5 字面值处理 3.2 Bean拷贝工具类封装3.2 查…

flink优化案例

文章目录 一、flink join维表案例二、flink 双流join案例三、总结 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考(适用于flink1.13) 一、flink join维表案例 背景:flink sql join 维表。job业务不复杂&#xff0c;job写入性能比较差。维表数据大约每天…

【ubuntu20.04运行python文件时,报错No module named ‘rospkg’】

**问题原因&#xff1a;**一般来说&#xff0c;并不是真的缺少rospkg&#xff0c;而是系统中存在多个python版本导致的混乱 检查python版本 Ubuntu20.04 —— pyhon3.8 sudo apt-get install python3.8最新版本&#xff0c;如下图所示 查看python3.8的位置 whereis python…

C++ | Leetcode C++题解之第88题合并两个有序数组

题目&#xff1a; 题解&#xff1a; class Solution { public:void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {int p1 m - 1, p2 n - 1;int tail m n - 1;int cur;while (p1 > 0 || p2 > 0) {if (p1 -1) {cur nums2[p2-…

让创意在幻觉中肆虐: 认识Illusion Diffusion AI

人工智能新境界 在不断发展的人工智能领域,一款非凡的新工具应运而生,它能将普通照片转化为绚丽的艺术品。敬请关注Illusion Diffusion,这是一个将现实与想象力完美融合的AI驱动平台,可创造出迷人的视错觉和超现实意境。 AI算法的魔力所在 Illusion Diffusion 的核心是借助先进…

每日OJ题_贪心算法四⑧_力扣767. 重构字符串

目录 力扣767. 重构字符串 解析代码 力扣767. 重构字符串 767. 重构字符串 难度 中等 给定一个字符串 s &#xff0c;检查是否能重新排布其中的字母&#xff0c;使得两相邻的字符不同。 返回 s 的任意可能的重新排列。若不可行&#xff0c;返回空字符串 "" 。 …

测试页打印失败。是否要参阅打印疑难解答以获得帮助?服务器打印后台处理程序服务没有运行。请重新启动服务器上的打印后台处理程序或重新启动服务器计算机。

问题&#xff1f; 测试页打印失败。是否要参阅打印疑难解答以获得帮助? 解决办法&#xff1a; 方法1、 请重新启动服务器上的打印后台处理程序或重新启动服务器计算机。 方法2、 找到services服务找到print spooler停止运行&#xff0c; C:\Windows\System32\spool -------…

回炉重造java----JVM

为什么要使用JVM ①一次编写&#xff0c;到处运行&#xff0c;jvm屏蔽字节码与底层的操作差异 ②自动内存管理&#xff0c;垃圾回收功能 ③数组下边越界检查 ④多态 JDK&#xff0c;JRE&#xff0c;JVM的关系 JVM组成部分 JVM的内存结构 《一》程序计数器(PC Register) 作用…

记录MySQL数据库查询不等于xxx时的坑

目录 一、背景 二、需求 三、方法 四、示例 一、背景 在使用MySQL数据库查询数据时&#xff0c;需要查询字段name不等于xxx的记录&#xff0c;通过where name ! xxx查询出来的记录不符合预期&#xff0c;通过检查发现少了name字段为null的记录&#xff0c;后经查询得知在My…

Python | Leetcode Python题解之第88题合并两个有序数组

题目&#xff1a; 题解&#xff1a; class Solution:def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:"""Do not return anything, modify nums1 in-place instead."""p1, p2 m - 1, n - 1tail m n - 1whi…