【C语言】指针详解

前言

许多同学闻C语言指针色变,但是指针其实并没有大家想象中的那么难,也没有那么复杂,其实连能想到生活,指针还是很好理解的,虽然题目是指针的详解,但是详细程度在大家的眼中不太相同,但是我会把我学到的有关指针的东西尽力地写出来,帮助大家更好的理解、运用指针!


一、内存和地址

内存对于计算机来说就是存储数据的地方,内存也可以划分为一个个内存单元,每个内存单元一个字节大小,而每一个内存单元都有一个相对应的地址,也就是说内存就像是一个酒店,里面的所有房间都有一个房间号,我们可以通过房间号快速地访问到我们要去的房间


二、指针变量

在C语言中,变量的声明就是向内存空间申请空间的过程,而指针变量存储的是变量的内存地址。这个地址可以是任何类型的数据,包括整数、浮点数、结构体等,我们也可以通过指针访问我们的内存空间,我们观察下面的代码

#include <stdio.h>
int main() {

	int a = 0;
	int* pa = &a;
	printf("%p\n", pa);

	return 0;
}

在这里插入图片描述
这里我们声明了一个变量 a ,并且声明了一个指针变量 pa 储存变量 a 的地址,至于取地址符号& 与 解引用符号 * 我已经在操作符详解里面讲过了


三、指针变量的类型

指针变量是用很多类型的,比如上面的代码的指针变量是整形指针变量,指针还有char* 、double*、float*等等

指针类型多种的意义: 为指针的解引用提供依据,给解引用说明按照什么类型解引用
下面我们看两段代码

//代码1
#include <stdio.h>
	int main(){
		int n = 0x11223344;
		int *pi = &n;
		*pi = 0;
	return 0;
}

在这里插入图片描述
在这里插入图片描述
下面我们看代码二

#include <stdio.h>
int main() {
	int n = 0x11223344;
	char* pi = (char*)&n;
	*pi = 0;
	return 0;
}

在这里插入图片描述
在这里插入图片描述
结论: 指针的类型决定了,对指针解引用的时候有多大的权限(一次能操作几个字节)。
比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

※ void 类型指针(空指针)

在上面我们说过,指针解引用时会根据指针的类型对指针指向的内存进行解读,但是对于 void 类型的指针是无法解引用的,因为 void 指针的类型为空,指针解引用不知道如何去读这一段内存,所以 void 类型的指针只能当作一个零时的指针拷贝,也就是保存指针的变量,如下面的代码

#include <stdio.h>
int main() {
	int n = 0x11223344;
	int* pi = &n;
	void* tmpp = pi;
	
	int* pa = (int*)tmpp;
	printf("%d\n", *pa);

	return 0;
}

在这里插入图片描述
这里的代码,tmpp为一个空指针类型,它存储了 n 的内存地址,并且把这个地址赋值给了 pa ,这时 pa 、pi 都指向 n 的内存地址
void 指针(空指针)无法直接解引用,编译器会报错


四、指针的运算

指针是一个变量,存储的是一个地址,是十六进制的数值,它也可以进行运算,下面我们看一段代码及运行结果
指针只能进行 +、-、比较 三种运算

#include <stdio.h>
int main() {
	int n = 0;
	char a = '0';
	int* pn = &n;
	char* pa = &a;

	printf("pn-> %p\n", pn);
	printf("pa-> %p\n", pa);
	printf("pn + 1-> %p\n", pn + 1);
	printf("pa + 1-> %p\n", pa + 1);
	
	return 0;
}

在这里插入图片描述
下面是运行结果
pn-> 0000006AA94FF634
pa-> 0000006AA94FF654
pn + 1-> 0000006AA94FF638
pa + 1-> 0000006AA94FF655
我们可以发现对于整数型指针变量 pn 加 1 后它的地址向后偏移了 4,而对于字符型指针变量 pa 加 1 后,它的地址向后偏移了 1 ,4 与 1 是地址便宜的字节量,int整数型变量大小为4个字节,而char字符型数据大小为1个字节,也就说,指针类型的不同决定着指针运算时的步幅大小


五、野指针

概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

野指针有三种成因: 指针未初始化、指针越界访问、指针指向的空间释放

指针未初始化

#include <stdio.h>
int main() {
	int* p; //此时p为野指针
	int a = 10;
	p = &a;

	return 0;
}

指针越界访问

#include <stdio.h>
int main()
{
	int arr[10] = {0};
	int *p = &arr[0];
	int i = 0;
	for(i=0; i<=11; i++)
	{
		//当指针指向的范围超出数组arr的范围时,p就是野指针
		*(p++) = i;
	}
	return 0;
}

指针指向的空间释放

#include <stdio.h>
int main() {
	int* pn = (int*)malloc(sizeof(int));
	assert(pn);
	free(pn);

	return 0;
}

避免野指针的出现需要避免出现这些错误!


六、二级指针及多级指针

我们知道指针是一个变量,指针存放着其他变量的内存地址,也正是因为指针是一个变量,所以在内存中也有着相应的内存地址存放着指针变量,当我们用指针指向另一个指针的内存地址时,这个指针就称为二级指针,同理,若是我们有一个指针指向二级指针的地址时,这个指针就称为三级指针,以此类推,下面我们举例说明

#include <stdio.h>
int main() {
	int a = 0;
	int* pa = &a;//一级指针
	int** ppa = &pa;//二级指针
	int*** pppa = &ppa;//三级指针

	return 0;
}

多级指针的命名

从上面的代码中,我们也可以看出多级指针是如何命名的,类型*(N),多少级指针后面就跟多少个*号


End

好了,对于基本的指针知识就介绍到这里,后面我还会写其他有关指针的文章,希望这篇文章对你有帮助!谢谢你的阅读!

标题“51单片机通过MPU6050-DMP获取姿态角例程”解析 “51单片机通过MPU6050-DMP获取姿态角例程”是一个基于51系列单片机(一种常见的8位微控制器)的程序示例,用于读取MPU6050传感器的数据,并通过其内置的数字运动处理器(DMP)计算设备的姿态角(如倾斜角度、旋转角度等)。MPU6050是一款集成三轴加速度计和三轴陀螺仪的六自由度传感器,广泛应用于运动控制和姿态检测领域。该例程利用MPU6050的DMP功能,由DMP处理复杂的运动学算法,例如姿态融合,将加速度计和陀螺仪的数据进行整合,从而提供稳定且实时的姿态估计,减轻主控MCU的计算负担。最终,姿态角数据通过LCD1602显示屏以字符形式可视化展示,为用户提供直观的反馈。 从标签“51单片机 6050”可知,该项目主要涉及51单片机和MPU6050传感器这两个关键硬件组件。51单片机基于8051内核,因编程简单、成本低而被广泛应用;MPU6050作为惯性测量单元(IMU),可测量设备的线性和角速度。文件名“51-DMP-NET”可能表示这是一个与51单片机及DMP相关的网络资源或代码库,其中可能包含C语言等适合51单片机的编程语言的源代码、配置文件、用户手册、示例程序,以及可能的调试工具或IDE项目文件。 实现该项目需以下步骤:首先是硬件连接,将51单片机与MPU6050通过I2C接口正确连接,同时将LCD1602连接到51单片机的串行数据线和控制线上;接着是初始化设置,配置51单片机的I/O端口,初始化I2C通信协议,设置MPU6050的工作模式和数据输出速率;然后是DMP配置,启用MPU6050的DMP功能,加载预编译的DMP固件,并设置DMP输出数据的中断;之后是数据读取,通过中断服务程序从DMP接收姿态角数据,数据通常以四元数或欧拉角形式呈现;再接着是数据显示,将姿态角数据转换为可读的度数格
MathorCup高校数学建模挑战赛是一项旨在提升学生数学应用、创新和团队协作能力的年度竞赛。参赛团队需在规定时间内解决实际问题,运用数学建模方法进行分析并提出解决方案。2021年第十一届比赛的D题就是一个典型例子。 MATLAB是解决这类问题的常用工具。它是一款强大的数值计算和编程软件,广泛应用于数学建模、数据分析和科学计算。MATLAB拥有丰富的函数库,涵盖线性代数、统计分析、优化算法、信号处理等多种数学操作,方便参赛者构建模型和实现算法。 在提供的文件列表中,有几个关键文件: d题论文(1).docx:这可能是参赛队伍对D题的解答报告,详细记录了他们对问题的理解、建模过程、求解方法和结果分析。 D_1.m、ratio.m、importfile.m、Untitled.m、changf.m、pailiezuhe.m、huitu.m:这些是MATLAB源代码文件,每个文件可能对应一个特定的计算步骤或功能。例如: D_1.m 可能是主要的建模代码; ratio.m 可能用于计算某种比例或比率; importfile.m 可能用于导入数据; Untitled.m 可能是未命名的脚本,包含临时或测试代码; changf.m 可能涉及函数变换; pailiezuhe.m 可能与矩阵的排列组合相关; huitu.m 可能用于绘制回路图或流程图。 matlab111.mat:这是一个MATLAB数据文件,存储了变量或矩阵等数据,可能用于后续计算或分析。 D-date.mat:这个文件可能包含与D题相关的特定日期数据,或是模拟过程中用到的时间序列数据。 从这些文件可以推测,参赛队伍可能利用MATLAB完成了数据预处理、模型构建、数值模拟和结果可视化等一系列工作。然而,具体的建模细节和解决方案需要查看解压后的文件内容才能深入了解。 在数学建模过程中,团队需深入理解问题本质,选择合适的数学模
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值