指针的详解与应用
指针
指针(poiner)是c语言的重要知识点,其使用灵活,功能强大,是c语言的灵魂。
指针与底层硬件联系紧密,使用指针可以操作数据的地址,实现数据的间接访问。
1. 计算机的存储机制
int a = 0x12345678
因为一个地址下面只能放一个字节的数据,a超过了一个字节,就会拆分掉去存放,现在大多数的计算机的存储方式都是小端存储,意思就是说拆出来的最低的俩位,0x78,放在地址的开头,然后从这个地址往下,依次存放剩下的0x56,0x34……
(每个十六进制占0.5个字节,0x00表示一个字节)
2. 定义指针
- 指针即指针变量,本身也是一种变量。用于存放其他数据单元(变量/数组/结构体/函数等)的首地址。若指针存放了某个数据单元的首地址,则这个指针指向了这个数据单元,若指针存放的值是0,则这个指针是空指针。
定义语法:
1 | 数据类型 * 指针变量名称 = 被指向的变量名称; |
不同于不同数据类型所定义出来的变量所占的字节数不同,指针变量的所占的字节数并不取决于定义指针时的数据类型。而是取决于操作系统:
16位操作系统 :2字节, 32位操作系统 :4字节, 64位操作系统 :8字节。
3. 指针的操作
- 取地址 :p = &a; 将数据a的首地址赋值给p。
- 取内容 : *p; 取出指针指向的数据单元。
- 加 : p++; 使指针向下移动一个数据宽度(数据宽度就是定义指针的时候的前面的那个数据类型)。
- 减 : p–; 使指针向上移动一个数据宽度。
(加减一般用于数组,否则一般的加减没有意义。)
4. 数组与指针
- 数组是一些相同数据类型的变量组成的几何,其数组名就是指向该数据类型的指针。数组的定义等效于申请内存,定义指针和初始化。利用数组下标引用数组数据也等效于指针取内容。(可以说:数组就是指针,二者是一样的。你可以直接拿数组名当做指针来用,数组名++之类的。)
注意事项:
- 在对指针取内容之前,一定要确保指针指在合法的位置,否则将导致程序出现不可预知的错误。
- 同级指针之间才能相互赋值,跨级赋值会导致编译器报错或警告。因为指针再取地址就得到二级指针,变量取地址可以赋值给指针,但是不能跨级赋值给二级指针,同样的,指针取内容可以赋值给变量,而不能直接把指针赋值给变量,这样子也是跨级,得先强制类型转换才可以赋值给变量。
5. 指针的应用
5.1 传递参数
使用指针传递大容量的参数,主函数和子函数使用的是同一套数据,避免了参数传递过程中的数据复制,提高了运行效率,减少了内存占用。
使用指针传递输出参数,利用主函数和子函数使用同一套数据的特性,实现数据的返回,可实现多返回值函数的设计。
5.2 传递返回值
- 将模块内的公有部分返回,让主函数持有模块的“句柄”,便于程序对指定对象的操作。(句柄就是把手的意思,只要有一个把手就可以操作。可以认为是指针)
详细示例
5.3 直接访问物理地址下的数据(单片机中的应用)
- 访问硬件指定内存下的数据,比如设备ID号等
- 将复杂格式的数据转换为字节,方便通信与存储。
最后一段的内容有点东西,实现了把char型指针转化为float型指针的过程。实现了传递一个float类型的数据。
原理:float类型的数据手机的存储其实是:最高位是符号位,然后有一段是阶码,就是多少次方,科学计数法嘛。然后还有一段是尾码,就是科学计数法的x.x的数字。所以float类型可以存储很大的数字,但是进度有问题。
但是发送数据出去,都是以字节为单位发送的,(我认为不可以直接定义float的指针去作为函数的参数去发送float数据)怎么办?那就定义一个unsigned char 的指针,用这个指针去指向这个float的数据(float的数据要先取地址再强制类型转换),这样子就把这个float的所有字节数据都发过去了。然后接收的时候再定义一个float的指针去把数据取出来,相当于进行了解码。
- 存储器都是以字节为单位进行存储,所以都可以用一个unsigned char *去存储。读的时候再强制类型转换为相应类型的指针。就可以把所有复杂格式的数据转换为字节来通信和存储,这种复杂格式包括:结构体,float,double等等。总之就当做字节来看就可以存储了。
- Title: 指针的详解与应用
- Author: CM
- Created at: 2023-07-19 19:08:40
- Updated at: 2023-07-20 13:32:20
- Link: https://redefine.ohevan.com/2023/07/19/指针的详解与应用/
- License: This work is licensed under CC BY-NC-SA 4.0.