深⼊理解指针

1. 内存和地址

1.1 内存

在讲内存和地址之前,我们想有个⽣活中的案例: 假设有⼀栋宿舍楼,把你放在楼⾥,楼上有100个房间,但是房间没有编号,你的⼀个朋友来找你玩, 如果想找到你,就得挨个房⼦去找,这样效率很低,但是我们如果根据楼层和楼层的房间的情况,给 每个房间编上号,如:

1.⼀楼:101,102,103... 

2.⼆楼:201,202,203....

3....

 有了房间号,如果你的朋友得到房间号,就可以快速的找房间,找到你。⽣活中,每个房间有了房间号,就能提⾼效率,能快速的找到房间。 如果把上⾯的例⼦对照到计算中,⼜是怎么样呢? 我们知道计算上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数 据也会放回内存中,那我们买电脑的时候,电脑上内存是8GB/16GB/32GB等,那这些内存空间如何⾼ 效的管理呢? 其实也是把内存划分为⼀个个的内存单元,每个内存单元的⼤⼩取1个字节。 计算机中常⻅的单位(补充): ⼀个⽐特位可以存储⼀个2进制的位1或者0

 通过上面的数据可以发现除了第一个:byte和bit的换算是8倍其他全都是2^10

回归正题 

当我们在编写C语言程序时,指针是一个非常重要的概念。指针可以让我们直接访问内存中的数据,实现高效的数据操作。本文将详细介绍指针的概念、用法和示例,包括数组指针、指针数组、函数指针、野指针、void指针等,让读者能够更容易地理解和掌握指针的知识。

1.指针的概念

 

指针是一个变量,其值为另一个变量的地址。通过指针,我们可以直接操作内存中的数据,而不需要将数据复制到新的变量中。这样可以节省内存空间并提高程序的效率。

在C语言中,我们可以通过以下方式定义一个指针变量:

int *ptr;  // 定义一个指向整数的指针变量

在上面的例子中,int *ptr表示定义了一个指向整数的指针变量ptr。*表示这是一个指针变量,int表示指针指向的数据类型。

2.指针的用法

 指针的用法非常灵活,我们可以通过指针来访问和修改变量的值,也可以通过指针来访问数组中的元素。下面是一些指针的常见用法示例:

2.1 访问变量的地址和值

int num = 10;
int *ptr = #  // 将num的地址赋给指针ptr
printf("变量num的地址:%p\n", &num);  // 打印变量num的地址
printf("指针ptr的值:%d\n", *ptr);  // 通过指针ptr访问变量num的值

 2.2 通过指针修改变量的值

int num = 10;
int *ptr = #
*ptr = 20;  // 通过指针ptr修改变量num的值
printf("变量num的值:%d\n", num);  // 打印变量num的新值

 2.3 使用指针访问数组元素

 

int arr[] = {1, 2, 3, 4, 5};
int *ptr = arr;  // 将数组arr的首地址赋给指针ptr
for (int i = 0; i < 5; i++) {
    printf("数组arr的第%d个元素:%d\n", i, *(ptr + i));  // 通过指针ptr访问数组arr的元素
}

3.数组指针

 数组指针是一个指向数组的指针变量。我们可以通过数组指针来访问数组中的元素,也可以通过数组指针来修改数组中的元素。下面是一个数组指针的示例:

int arr[] = {1, 2, 3, 4, 5};
int (*ptr)[5] = &arr;  // 定义一个指向数组arr的指针变量ptr
for (int i = 0; i < 5; i++) {
    printf("数组arr的第%d个元素:%d\n", i, (*ptr)[i]);  // 通过数组指针ptr访问数组arr的元素
}

在上面的例子中,int (*ptr)[5]表示定义了一个指向整数数组的指针变量ptr。*表示这是一个指针变量,[5]表示指针指向的是一个包含5个整数的数组。 

 

4.指针数组

指针数组是一个包含指针的数组。我们可以通过指针数组来存储多个指针,也可以通过指针数组来访问和修改指针指向的数据。下面是一个指针数组的示例:

int num1 = 10, num2 = 20, num3 = 30;
int *arr[] = {&num1, &num2, &num3};  // 定义一个包含指针的数组arr
for (int i = 0; i < 3; i++) {
    printf("指针arr[%d]指向的值:%d\n", i, *arr[i]);  // 通过指针数组arr访问指针指向的值
}

 在上面的例子中,int *arr[]表示定义了一个包含指针的数组arr。数组中的每个元素都是一个指向整数的指针变量。

5.函数指针

 函数指针是一个指向函数的指针变量。我们可以通过函数指针来调用函数,也可以将函数指针作为参数传递给其他函数。下面是一个函数指针的示例:

int add(int a, int b) {
    return a + b;
}
int (*ptr)(int, int) = &add;  // 定义一个指向函数add的指针变量ptr
int result = (*ptr)(10, 20);  // 通过函数指针ptr调用函数add
printf("函数add的结果:%d\n", result);

在上面的例子中,int (*ptr)(int, int)表示定义了一个指向函数的指针变量ptr。*表示这是一个指针变量,(int, int)表示函数的参数类型。

 6.野指针

野指针是指一个没有被初始化或被赋值为NULL的指针变量。野指针可能会指向一个随机的内存地址,这样就会导致程序崩溃或产生不可预测的结果。因此,在使用指针时,我们应该始终将指针初始化或赋值为NULL,以避免野指针的出现。 

7.void指针

void指针是一个通用的指针类型,可以指向任何类型的数据。我们可以通过void指针来实现数据的通用访问和传递。下面是一个void指针的示例:

int num = 10;
float fnum = 3.14;
void *ptr;
ptr = &num;  // 将整数num的地址赋给void指针ptr
printf("变量num的值:%d\n", *(int *)ptr);  // 通过void指针ptr访问整数num的值
ptr = &fnum;  // 将浮点数fnum的地址赋给void指针ptr
printf("变量fnum的值:%f\n", *(float *)ptr);  // 通过void指针ptr访问浮点数fnum的值

 

在上面的例子中,void *ptr表示定义了一个void指针变量ptr。我们可以将任何类型的数据的地址赋给void指针ptr,并通过强制类型转换将void指针转换为特定类型的指针来访问数据。

总之,指针是C语言中非常重要的概念,掌握好指针的用法可以让我们的程序更加高效和灵活。本文介绍了指针的概念、用法和示例,包括数组指针、指针数组、函数指针、野指针、void指针等。希望本文的介绍和示例能够帮助读者更容易地理解和掌握指针的知

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式中的基本定时器

学习目标 理解基本定时器的作用掌握定时器开发流程掌握基本定时器中断处理的操作流程掌握AHB和APB时钟查询方式理解周期,分频系数,周期计数,分频计数。掌握调试策略学习内容 基本定时器 只能用于定时计时操作,没有输出引脚通道的定时器,在GD32中, TIMER5和TIMER6为基本…

Ubuntu 常用命令之 reboot 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 reboot命令在Ubuntu系统中用于重新启动系统。这个命令通常需要管理员权限才能执行。 reboot命令的参数如下 -f 或 --force&#xff1a;强制重启&#xff0c;不调用shutdown -r进行友好重启。-p 或 --poweroff&#xff1a;在重启…

百度地图添加查询框

<div style"display:inline;float:left;margin: 10px"><el-input style"width: 400px" placeholder"输入地点" v-model"area" class"input-with-select"keyup.enter.native"searchMap"><el-button…

随机问卷调查数据的处理(uniapp)

需求&#xff1a;问卷调查 1.返回的数据中包含单选、多选、多项文本框、单文本框、图片上传 2.需要对必填的选项进行校验 3.非必填的多项文本框内容 如果不填写 不提交 表单数据格式 res{"code": 0,"msg": null,"data": [{"executeDay&…

lamda表达式(史上最全)

一、函数式接口 在jdk8中什么是函数式接口&#xff1a; 被FunctionalInterface注解修饰的。接口里边只有一个非default的方法。 满足以上2个条件的即为函数式接口&#xff0c;ps&#xff1a;即使一个接口没有FunctionalInterface修饰&#xff0c;但是满足2&#xff0c;那么这…

国产低成本Wi-Fi SoC解决方案芯片ESP8266与ESP8285对比差异

目录 ESP8266与ESP8285对比差异微信号&#xff1a;dnsj5343ESP8285简介ESP8285 主要特性Wi-Fi特性射频模块CPU特性硬件软件 ES8285 8266通用开发板 ESP8266与ESP8285对比差异 ESP8285相当于在ESP8266基础上多加了1/2MB Flash&#xff0c; ESP8285与ESP8266同用一套SDK&#xf…

异方差与多重共线性对回归问题的影响

异方差的检验 1.异方差的画图观察 2.异方差的假设检验&#xff0c;假设检验有两种&#xff0c;一般用怀特检验使用方法在ppt中&#xff0c;课程中也有实验&#xff0c;是一段代码。 异方差的解决办法 多重共线性 多重共线性可能带来的影响&#xff1a; 多重共线性的检验 多重…

德思特方案 | 德思特毫米波RIS研究测试方案:一站式助力工程师探索高频通信未来

来源&#xff1a;德思特测试测量 德思特方案 | 德思特毫米波RIS研究测试方案&#xff1a;一站式助力工程师探索高频通信未来 原文链接&#xff1a;德思特方案 | 德思特毫米波RIS研究测试方案&#xff1a;一站式助力工程师探索高频通信未来 欢迎关注虹科&#xff0c;为您提供最…

KubeSphere应用【五】发布镜像至Harbor

一、IDEA发布镜像至Docker 1.1IDEA安装Docker插件 1.2配置Docker服务器地址 1.3编写POM.XML文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/20…

Java学习常用实用类2

1 StringTokenizer类 字符串分析器&#xff0c;能够从一个字符串中根据指定的分隔符拆分出若干单词 StringTokenizer(String s) 使用默认分隔符集合&#xff0c;即&#xff1a;空格符、换行符、回车符、Tab符、进纸符 StringTokenizer(String s, String delim) 指定分…

cilium原理之ebpf尾调用与trace

背景 在深入剖析cilium原理之前&#xff0c;有两个关于epbf的基础内容需要先详细介绍一下&#xff1a; 1. ebpf尾调用 尾调用类似于程序之间的相互跳转&#xff0c;但它的功能更加强大。 2. trace 虽然之前使用trace_printk输出日志&#xff0c;但这个函数不能多用&#x…

数据仓库-数据治理小厂实践

一、简介 数据治理贯穿数仓中数据的整个生命周期&#xff0c;从数据的产生、加载、清洗、计算&#xff0c;再到数据展示、应用&#xff0c;每个阶段都需要对数据进行治理&#xff0c;像有些比较大的企业都是有自己的数据治理平台或者会开发一些便捷的平台&#xff0c;对于没有平…

从DevOps状态报告看技术团队的文化建设

本文源自一次内部分享&#xff0c;借由此机会又把历年的DevOps状态报告翻看了一遍&#xff0c;其实大多数时候我们对于DevOps的理解都在于流程&#xff0c;工具&#xff0c;实践这些看得见摸得着的东西&#xff0c;但就像文末的几点思考所说的那样&#xff0c;我们一直相信技术…

轴承故障诊断分类模型全家桶-最全教程

Python轴承故障诊断 (一)短时傅里叶变换STFT-CSDN博客 Python轴承故障诊断 (二)连续小波变换CWT-CSDN博客 Python轴承故障诊断 (三)经验模态分解EMD-CSDN博客 Pytorch-LSTM轴承故障一维信号分类(一)-CSDN博客 Pytorch-CNN轴承故障一维信号分类(二)-CSDN博客 Pytorch-Trans…

VM Group

在复杂方案中模块过多可能造成查看或修改方案时存在视觉混乱&#xff0c;不够直观。此时可利用Group模块进行模块整合&#xff0c;同时Group模式也兼容循环的功能&#xff0c;如下图所示。 双击Group模块可进入Group内部&#xff0c;如下图所示。 在Group模块单击 可设置输入、…

Spring Cloud+SpringBoot b2b2c:Java商城实现一件代发设置及多商家直播带货商城 免 费 搭 建

【saas云平台】打造全行业全渠道全场景的saas产品&#xff0c;为经营场景提供一体化解决方案&#xff1b;门店经营区域化、网店经营一体化&#xff0c;本地化、全方位、一站式服务&#xff0c;为多门店提供统一运营解决方案&#xff1b;提供丰富多样的营销玩法覆盖所有经营场景…

北斗卫星时钟同步服务器对电力系统有多重要?

随着计算机和网络通信技术的飞速发展&#xff0c;火电厂热工自动化系统数字化、网络化的时代已经到来。一方面它为控制和信息系统之间的数据交换、分析和应用提供了更好的平台&#xff0c;另一方面对各种实时和历史数据时间标签的准确性提出了更高的要求。 通过卫星时钟来统一全…

Tomcat报404问题解决方案大全(包括tomcat可以正常运行但是报404)

文章目录 Tomcat报404问题解决方案大全(包括tomcat可以正常运行但是报404)1、正确的运行页面2、报错404问题分类解决2.1、Tomcat未配置环境变量2.2、IIs访问权限问题2.3、端口占用问题2.4、文件缺少问题解决办法&#xff1a; Tomcat报404问题解决方案大全(包括tomcat可以正常运…

uniapp如何原生app-云打包

首先第一步&#xff0c;需要大家在HBuilder X中找到一个项目&#xff0c;然后呢在找到上面的发行选项 发行->原生App-云打包 选择完该选中的直接大包就ok。 大包完毕后呢&#xff0c;会出现一个apk包&#xff0c;这是后将这个包拖动发给随便一个人就行了。 然后接收到的那…

【Java 并发】CyclicBarrier 介绍

1 简介 在多线程编程中, 协调和同步线程的执行是至关重要的。Java 提供了许多并发工具来帮助开发人员有效地管理多线程应用程序。 其中之一是 CyclicBarrier, 它是一个强大的同步辅助类, 可用于在多个线程之间创建同步点, 以便它们可以在同一时间点协调执行某个任务。 Cyclic…