深⼊理解指针

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指针等。希望本文的介绍和示例能够帮助读者更容易地理解和掌握指针的知

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

爬虫课程考试方式说明

爬虫课程考试方式说明 一、开课情况 考查课 082116415 50人&#xff0c;0864211&#xff0c;1-15单周 理论学时16 实验学时0 上课地点&#xff1a;周一 3-4节 十号教学楼A303 51人&#xff0c;0864212&#xff0c;1-15单周 理论学时16 实验学时0 上课地点&#xff1a;周四 3-4…

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

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 date命令在Ubuntu系统中用于显示或设置系统的日期和时间。 date常见的参数 -d, --dateSTRING&#xff1a;显示STRING指定的时间&#xff0c;而不是当前时间。-u, --utc, --universal&#xff1a;显示或设置协调世界时间。-R, --…

协作机器人(Collaborative-Robot)安全碰撞的速度与接触力

协作机器人&#xff08;Collaborative-Robot&#xff09;的安全碰撞速度和接触力是一个非常重要的安全指标。在设计和使用协作机器人时&#xff0c;必须确保其与人类或其他物体的碰撞不会对人员造成伤害。 对于协作机器人的安全碰撞速度&#xff0c;一般会设定一个上限值&…

057:vue组件方法中加载匿名函数

第057个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

mysql主从复制(在虚拟机centos的docker下)

1.安装docker Docker安装(CentOS)简单使用-CSDN博客 2.部署2个mysql docker run --name some-mysql1 -p 33061:3306 -e MYSQL_ROOT_PASSWORD123456 -d mysql:5.7 --character-set-serverutf8mb4 --collation-serverutf8mb4_unicode_cidocker run --name some-mysql2 -p 330…

YACS(上海计算机学会竞赛平台)三星级挑战——牛奶供应(一)

题目描述 有一家牧场每天都会产出牛奶&#xff0c;在第 i 天&#xff0c;牛奶的产量为p[i]​。生产的牛奶可以卖到市场上&#xff0c;在第 i 天&#xff0c;市场需求为 c[i]​。如果市场需求不大&#xff0c;卖不掉牛奶&#xff0c;则多余的牛奶就会放进冷库保存。牛奶有一个保…

PyGame实现打砖块游戏

文章目录 砖块实现小车小球初始化和主循环 打砖块也是一个非常经典的小游戏&#xff0c;玩法大致如下&#xff0c;用一个小车接一个小球&#xff0c;然后反射小球&#xff0c;使之打在砖块上&#xff0c;当小球碰到砖块之后&#xff0c;则砖块被消掉&#xff0c;逻辑十分清晰。…

EDA实验-----直流电机驱动设计(Quartus II )

目录 一、实验目的 二、实验仪器设备 三、实验的重点和难点 四、实验原理 五、实验步骤 六、实验报告 七、实验过程 1.分频器代码 2.方向选择器 3.直流电动机工作原理 4.电路连接图 5.文件烧录 一、实验目的 了解直流电机控制的工作原理和实现的方法。掌握PWM波控…

linux下的进程组与会话的区别

进程组&#xff08;Process Group&#xff09;和会话&#xff08;Session&#xff09;是Unix/Linux操作系统中的两个概念&#xff0c;它们之间有一些关键区别&#xff1a; 定义和范围&#xff1a;一个进程组是一组相关进程的集合&#xff0c;它们具有相同的进程组ID&#xff08…

使用【OpenI启智平台】进行模型训练

前言 启智平台OpenI是一个人工智能开源开放平台&#xff0c;提供免费GPU算力可以进行模型训练。模式是git进行项目管理&#xff0c;可以创建调试任务调试代码以及保存镜像&#xff0c;创建训练任务训练模型&#xff0c;也提供推理和评测&#xff0c;我没用过就不讲述了。后来我…

Day67力扣打卡

打卡记录 美丽塔 II&#xff08;前缀和 单调栈&#xff09; 链接 class Solution:def maximumSumOfHeights(self, maxHeights: List[int]) -> int:n len(maxHeights)stack collections.deque()pre, suf [0] * n, [0] * nfor i in range(n):while stack and maxHeights…

嵌入式中断理解

一、概念 中断&#xff1a; 在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续运行。 中断优先级&#x…