C语言入门Day_24 函数与指针
目录
前言:
1.指针和数组
2.函数和指针
3.易错点
4.思维导图
前言:
我们知道数组是用来存储多个数据的,以及我们可以用指针来指向一个变量。那么我们可以用指针来指向一个数组中的数据么?
指针除了可以像指向一个变量一样指向一个数组的元素以外,还可以有更灵活的使用方法。
1.指针和数组
1.1
我们先来看看指针如何指向一个数组中的元素
int num_list[5] = {0, 1, 2, 3, 4};
int *p1;
p1 = &num_list[2];
printf("%d\n", *p1);
*p1 = 20;
printf("%d\n", *p1);
1.定义一个有五个整型元素的数组num_list,以及一个整型指针p1
int num_list[5] = {0, 1, 2, 3, 4};
int *p1;
2.把指针指向数组的第三个元素num_list[2],然后打印这个指针指向的数据,输出2
p1 = &num_list[2];
printf("%d\n", *p1);
3.修改这个指针指向的数据,重新赋值20,然后打印这个指针指向的数据,输出20
*p1 = 20;
printf("%d\n", *p1);
1.2
可以看到,把指针指向一个数组的特定元素的使用方式,和把指针指向一个变量的使用方式,是一样的。
都是在用指针指向它们的时候:
第一,需要使用取地址符号&来完成给这个指针变量赋值一个内存地址的过程。
第二,需要保证指针的类型和它所指向的数组的类型,是一致的。
1.3
我们把指针数组的第一个元素的地址赋给指针,然后重新给它赋值,并且打印它。
int num_list2[4] = {11, 22, 33, 44};
int *p1;
p1 = &num_list2[0];
*p1 = 111;
printf("%d\n", num_list2[0]);
1.首先初始化一个整型指针p1:
int *p1;
2.把数组第一个元素的内存地址num_list2[0]赋值给指针p1:
p1=&num_list2[0];
1.4
除了把指针指向一个具体的数组元素,我们还可以把指针指向一整个数组!
int num_list[5] = {10, 20, 30, 40, 50};
int *p1;
p1 = num_list;
printf("%d\n", *p1);
printf("%d\n", *(p1+1));
1.定义一个有五个元素的整型数组num_list,和一个整型指针p1
int num_list[5] = {10, 20, 30, 40, 50};
int *p1;
2.把指针指向数组num_list
p1 = num_list;
3.打印指针指向的值,这时候默认打印数组的第一个值num_list[0]
printf("%d\n", *p1);
4.打印指针*(p1+1),这是打印数组的第二个值
printf("%d\n", *(p1+1));
1.5
printf("%d\n",*p1);
printf("%d\n",*(p1+1));
我们注意到,当用指针指向一个数组的时候,*p
就是数组的第一个元素,*(p+1)
就是数组的第二个元素,同理*(p+2)
是数组的第三个元素。
为了方便记忆,可以记忆为*(p+0)
是数组的第一个元素,*(p+1)
是数组的第二个元素,*(p+2)
是数组的第三个元素;
指针后面加的数字,等同于数组的下标。
1.6
同时,细致的你可能也注意到了指针指向数组的时候,我们是没有使用取地址符&
的
int num_list[5] = {10, 20, 30, 40, 50};
int *p1;
p1 = &num_list[1];
printf("%d\n", *p1);
p1 = num_list;
printf("%d\n", *p1);
1.数组名num_list
int num_list[5] = {10, 20, 30, 40, 50};
2.指针指向单个数组元素的时候有取地址符&
p1 = &num_list[1];
3.指针指向整个数组的时候没有取地址符&
p1 = num_list;
1.6
这是因为,数组本质上就是一种指针,这也就是说数组名存储的就是一个内存地址,因此把指针指向数组名的过程,也就是把数组名的内存地址赋值给一个指针的过程。
已经是内存地址了,当然就不需要再用取地址符。
现在再看*(p+0)
是数组的第一个元素,*(p+1)
是数组的第二个元素是不是更清楚了,其实我们也可以写成*(num_list+0)
和*(num_list+1)
由于数组名num_list和指针p都存储的是一个内存地址,所以这两者是等价的。
1.7
以及指针和数组都需要注意的事也类似,就是数组是有边界的,不能越界访问。
比如数组的长度是10,*(p1+20)
和num_list[20]
都是会报错的。
我们学过函数,函数通过参数来接收外界(调用函数的地方)的输入;
通过返回值来向外界(调用函数的地方)输出。
当指针作为函数参数的时候,给函数的这种输入输出机制增加了一个例外。
2.函数和指针
2.1
由于指针指向的一个数据的实际存储的内存地址,因此在函数中对指针指向的数据的修改,是会直接修改到函数外部的变量数据。
也就是说,指针作为函数参数的时候,即使是在函数内部对指针的数据进行修改,也会穿透到函数外部。
如果说一般函数参数的数据改变,是在函数内部的暂时的改变;
那么指针函数参数的数据改变,就是一种“永久的改变”。
2.2
我们来看看指针作为函数参数时候的使用:
void AddThree(int *p1){*p1 = *p1 + 3;
}
int main(){int number_1 = 10;int *p;p = &number_1;AddThree(p);printf("%d\n", *p);
}
1.定义一个无返回值的函数,且这个函数的参数是一个指针
void AddThree(int *p1){
*p1 = *p1 + 3;
}
2.这是用指针做参数时候的语法
void AddThree(int *p1){ *
3.在main函数中调用这个函数
AddThree(p);
4.需要特别注意的是,传入的是指针(内存地址),而不是指针指向的数据(*p)
AddThree(p);
5.输出计算以后的结果13
printf("%d\n", *p);
2.3
可以看到,虽然函数AddThree()
并没有返回值,但是变量number_1
的值永久的改变了,这是为什么呢,答案还要回到内存地址上面。
一般的函数参数,只是把一个数据的复制品传入了函数,就像我抄写了一份数据交给你(函数),原始数据还在我(函数外部)这里。
你在函数内部对数据的修改,作用于这个数据的复制品,原始数据是不会改变的。
但是指针作为函数参数的时候,传递给函数的是一个内存地址,你修改了这个内存地址上面的数据,那就是永久的修改。
相当于我把原始数据给你了,而不是给你一个数据的复制品,你在函数内部的操作是直接作用于原始数据的。
2.4
我们再来看看这张图片,是不是理解会深一点,我们用指针就是在用内存地址,通过对这个内存地址里存储的数据的改变,会永久的修改这个数据;因为它就是原始数据存储的地方。
现在我们可能能够更能体会为什么说指针是C语言中很灵活很底层的机制了。
因为有些机制是基于指针的,比如数组和数组名。
有些机制在使用指针的时候,会方便快捷,甚至打破规则的操作原始数据,比如函数的指针参数。
3.易错点
数组本质上也是一个指针;
当指针指向整个数组时,不需要到取地址运算符&
;
但是指针指向数组的某个具体元素时,要用到取地址运算符&
。
对于一个指向数组的指针p,*(p+0)
是数组的第一个元素,*(p+1)
是数组的第二个元素,*(p+2)
是数组的第三个元素;但是*p+1
是先取出数组第一个元素的值再加1。
4.思维导图
最后我想说的是:
在撰写这篇文章时,我参考了《白纸编程》这个app的观点和思想,我要感谢他们对我的启发和帮助。
相关文章:
C语言入门Day_24 函数与指针
目录 前言: 1.指针和数组 2.函数和指针 3.易错点 4.思维导图 前言: 我们知道数组是用来存储多个数据的,以及我们可以用指针来指向一个变量。那么我们可以用指针来指向一个数组中的数据么? 指针除了可以像指向一个变量一样指…...
9月21日,每日信息差
今天是2023年9月21日,以下是为您准备的14条信息差 第一、谷歌高管已经广泛讨论了在2027年之前将博通作为人工智能芯片供应商的可能性 第二、清华系团队宣布研发出千亿参数“制药版ChatGPT”,覆盖药物立项、临床前研究、临床试验的各阶段,作…...
【FAQ】安防监控系统/视频云存储/监控平台EasyCVR服务器解释器出现变更该如何修改?
安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…...
Python手写人脸识别
Python手写人脸识别 引言 人脸识别是一种通过计算机视觉和模式识别技术来识别和验证人脸的技术。Python是一种广泛使用的编程语言,它提供了许多强大的库和工具来实现人脸识别。 在Python中,可以使用多种方法来实现人脸识别,包括基于特征提取的方法、基于深度学习的方法等…...
我的Qt作品(19)使用Qt写一个轻量级的视觉框架---第2章,仿海康VM实现思维导图拖拽方式的算法流程图
上次写的第1章介绍了主界面的设计。 https://blog.csdn.net/libaineu2004/article/details/130277151 本次是第2章,主要介绍流程图的运行。 目前市面上视觉框架很多,主要有列表图方式和流程图方式。海康VM的流程图方式比较受用户的喜爱和欢迎…...
仿写Timi记账
项目仿照Timi记账,本 APP 仅用作学习,如有侵权联系删除,项目地址:Timi记账 TIMI记账项目 简单功能对于tableview向上延伸部分采用了insertSubview形式:添加特殊字体添加.ttf文件获取plist文件数据 计算器功能说明简单逻…...
Java语言实现 比较两个Date日期的先后
在 Java 中,可以使用 Date 类的 compareTo() 方法或 before()、after() 方法来比较两个 Date 类型的日期的先后顺序。 使用 compareTo() 方法: Date date1 ...; // 第一个日期 Date date2 ...; // 第二个日期int result date1.compareTo(date2); if (…...
el-table 指定层级展开
先来看看页面默认全部展开时页面的显示效果:所有节点被展开,一眼望去杂乱无章! 那么如何实现只展开指定的节点呢?最终效果如下:一眼看去很舒爽。 干货上代码: <el-table border v-if"refreshTabl…...
3288S Android11 适配红外遥控功能(超详细)
目录 一、rk3288平台红外遥控介绍二、原理图分析三、配置设备树并使能红外遥控功能四、打开红外打印功能,查看红外遥控的用户码和键值五、将查看到的红外遥控用户码和键值添加到设备树和.kl文件六、Android红外遥控.kl文件映射知识和使用添加新的.kl文件七、补充&am…...
Linux高性能服务器编程 学习笔记 第三章 TCP协议详解
与IP协议相比,TCP协议更靠近应用层,因此在应用程序中有更强的可操作性。一些重要的socket选项都和TCP协议相关。 本章从以下方面讨论TCP协议: 1.TCP头部信息。TCP头部信息出现在每个TCP报文段中,用于指定通信的源端端口号、目的端…...
【云原生】Kubernetes学习笔记
部署 在部署前强调几点 不要使用IPv6, 很多组件都不支持IPv6不要使用最新版本, 最新版本非常不稳定, 甚至可能存在无法运行的bug不要版本更新, 安装后就将版本固定下来, 新的版本可能会引入新功能, 或移除旧功能, 导致Kubernetes无法运行 Kubeadm介绍 K8s是由多个模块构成的…...
[Machine Learning][Part 2]监督学习的实现
目录 线性模型实现: cost function :代价函数或者损失函数——衡量模型优劣的一个指标 理论: 代码实现: 梯度下降——自动寻找最小的cost function 代价函数 梯度的概念: 梯度下降公式: 实现一个简单的监督学习…...
【计算机毕业设计】基于SpringBoot+Vue大学生心理健康管理系统的开发与实现
博主主页:一季春秋博主简介:专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发,远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容:毕业设计(Java项目、小程序等)、简历模板、学习资料、面试题…...
下载水果FLStudio21.2软件安装更新教程
编曲是一种对音乐创作过程中涉及的元素和步骤进行组织和安排的艺术形式。对于想要学习编曲的人来说,以下是一些有用的建议: 1. 学习基础知识 在开始学习编曲之前,你需要掌握一些基础知识,例如音乐理论、乐器演奏和数字音乐制作技…...
人工智能机器学习-飞桨神经网络与深度学习
飞桨神经网络与深度学习-机器学习 目录 飞桨神经网络与深度学习-机器学习 1.机器学习概述 2.机器学习实践五要素 2.1.数据 2.2.模型 2.3.学习准则 2.4.优化算法 2.5.评估标准 3.实现简单的线性回归模型 3.1.数据集构建 3.2.模型构建 3.3.损失函数 3.4.模型优化 3…...
linux部署页面内容
/bin:该目录包含了常用的二进制可执行文件,如ls、cp、mv、rm等等。 /boot:该目录包含了启动Linux系统所需的文件,如内核文件和引导加载程序。 /dev:该目录包含了所有设备文件,如硬盘、光驱、鼠标、键盘等等…...
若依框架集成WebSocket带用户信息认证
一、WebSocket 基础知识 我们平时前后台请求用的最多的就是 HTTP/1.1协议,它有一个缺陷, 通信只能由客户端发起,如果想要不断获取服务器信息就要不断轮询发出请求,那么如果我们需要服务器状态变化的时候能够主动通知客户端就需要用…...
0基础学习VR全景平台篇 第101篇:企业版功能-子账号分配管理
大家好,欢迎观看蛙色VR官方系列——后台使用课程! 本期为大家带来蛙色VR平台,企业版教程-子账号分配管理功能! 功能位置示意 一、本功能将用在哪里? 子账号分配管理功能,主要用于企业版用户为自己服务的终…...
adb 命令集
adb 查看app启动时间 1.清除时间 adb shell am start -S com.android.systemui/.SystemUIService2.启动应用并记录 adb shell am start -W <PACKAGE_NAME>/.<ACTIVITY_NAME>TotalTime: 491 adb 查看分辨率、dpi 分辨率 adb shell wm sizePhysical size: 1080…...
分享78个Python源代码总有一个是你想要的
分享78个Python源代码总有一个是你想要的 源码下载链接:https://pan.baidu.com/s/1ZhXDsVuYsZpOUQIUjHU2ww?pwd8888 提取码:8888 下面是文件的名字。 12个python项目源码 Apache Superset数据探查与可视化平台v2.0.1 API Star工具箱v0.7.2 Archery…...
springcloud3 指定nacos的服务名称和配置文件的group,名称空间
一 指定读取微服务的配置文件 1.1 工程结构 1.2 nacos的配置 1.配置文件 2.内容 1.3 微服务的配置文件 1.bootstrap.yml内容 2.application.yml文件内容 1.4 验证访问 控制台: 1.5 nacos服务空间名称和groupid配置 1.配置文件配置 2.nacos的查看...
go-redis简单使用
目录 一:官方文档和安装方式二:简单案例使用 一:官方文档和安装方式 官方中文文档:https://redis.uptrace.dev/zh/guide/go-redis.html安装:go get github.com/redis/go-redis/v9 二:简单案例使用 简单的…...
33. 搜索旋转排序数组-二重二分查找
33. 搜索旋转排序数组-二分查找 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, n…...
mysql自动删除过期的binlog
一、binlog_expire_logs_seconds 配置项 mysql 8.0使用配置项 binlog_expire_logs_seconds 设置binlog过期时间,单位为秒。 mysql旧版本使用配置项 expire_logs_days 设置binlog过期时间,单位为天,不方便测试。 在 8.0 使用 expire_logs_d…...
Java面向对象(1)
static静态变量 public class Student {static String name;private double score;public Student(){};public Student(double score) {this.score score;}public double getScore() {return score;}public void setScore(double score) {this.score score;} }public class t…...
【计算机毕业设计】基于SpringBoot+Vue金融产品销售系统的设计与实现
博主主页:一季春秋博主简介:专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发,远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容:毕业设计(Java项目、小程序、安卓等)、简历模板、学习资料、…...
【面试题精讲】Mysql如何实现乐观锁
❝ 有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top ❞ 首发博客地址 文章更新计划 系列文章地址 在 MySQL 中,可以通过使用乐观锁来实现并发控制,以避免数据冲突和并发更新问…...
从零开始搭建java web springboot Eclipse MyBatis jsp mysql开发环境
文章目录 1 第一步软件安装1.1 下载并安装Eclipse1.2 下载并安装Java1.3 下载并安装Apache Maven1.4 下载并安装MySQL 2 创建所需要的表和数据3 创建Maven 工程、修改jdk4 通过pom.xml获取所需要的jar包5 安装Eclipse的MyBatis插件6 创建文件夹以及jsp文件7 创建下面各种java类…...
【VsCode】整理代码
在VsCode中,你可以使用插件"Beautify"来格式化你的HTML代码,使其更加整齐清晰。而对于JSON代码,你可以使用"vscode-json"插件来格式化为易读的树状结构,方便查看和编辑。这些插件可以帮助你更加高效地整理HTM…...
盘点总结汇总植物病虫害、人体疾病识别相关的项目实践
在前面的很多项目中做了许多有关于植物病虫害比如:苹果病虫害、番茄病虫害、小麦病虫害、辣椒病虫害、白菜病虫害、木薯病虫害、葡萄病虫害、柑橘病虫害等等,还有一些是有关于人体疾病识别相关的,比如:病理细胞识别、癌症识别、皮…...
北大青鸟网站建设课程/网络营销广告策划
今年上半年,我通过又拍云搭建了一个独立博客,不久之后就遇到了很多实际问题:网上看到图片想收藏到空间,YouTube上的MV想放到自己的博客,想对一段音视频进行在线预览和编辑……当时我查了下,必须要通过API接…...
济南百姓网免费发布信息网/惠州seo建站
2019独角兽企业重金招聘Python工程师标准>>> 公司的boss项目,我已经在上面搭建了一个quartz,通过查询数据库的定时任务。目前是能满足需求,但是随着功能的增多,这个会慢慢满足不了需求,虽然可以通过集群的方…...
厦门正规网站建设公司/百度官网优化
在WEB项目用GridReport报表的时候,有时候会出现这个问题: 检索 COM 类工厂中 CLSID 为 {13C28AD0-F195-4319-B7D7-A1BDAA329FB8} 的组件失败,原因是出现以下错误: 80040154 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))…...
湖南网站服务/百度搜索关键词优化方法
愿你我相遇,皆有所获! 欢迎关注微信公众号:【伤心的辣条】 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!首先我就来回答一下标题提出的问题:单元测试除了是一种测试手段外&am…...
公司网站不续费/南京seo排名扣费
https://projectlombok.org/ lombok官网 简单介绍 可以直接在java实体类上使用注解,来帮助自动生成getter(),setter方法(最常用),目的就是减少没必要的代码,简化冗余的javabean 当然也有其他功能,比如自动…...
可视化的做网站的app/2023年6月疫情情况
查看是否安装apache[rootwxb ~]# rpm -qa | grep httpd查看正在跑的进程并杀掉[rootwxb ~]# ps -ef | grep dhcp[rootwxb ~]# kill -9 1775搜索与httpd有关[rootwxb ~]# yum search httpd安装apache软件包:(由apache http server看到apache的安装包为htt…...