指针
指针(pointer)是C语言的一个重要知识点,是C语言的灵魂
指针与底层硬件(内存)联系紧密,使用指针可操作数据的地址,实现数据的间接访问
内存地址
在学习指针之前先了解另一个概念:内存地址(注意:我们这里提到的内存并不是人们常说的计算机的物理内存,而是虚拟的逻辑内存空间)
(这个可以直接看 [C语言] 指针的详解与应用 视频的讲解可能更直观一点)
内存地址(Memory Address)是计算机中用来标识内存中数据存储位置的唯一标识符(简单地说:地址就是可以唯一标识某一点的一个编号,即一个数字)
可以把它看作是存储器中每一个字节或存储单元的“门牌号码”,通过这个号码,CPU或其他硬件组件可以准确找到所需的数据或指令
内存地址常常用其对应的十六进制数来表示,比如 0x1A2B 这样
在 C 程序中,每一个定义的变量,在内存中都占有一个内存单元,比如 int 类型占四个字节,char 类型占一个字节等等,每个字节都有一个对应的编号,C语言允许在程序中使用变量的地址,并可以通过地址运算符"&"得到变量的地址
指针的定义
在了解了内存地址的概念之后,再来看指针
指针是一种变量,即指针变量,其值为内存地址
换句话说,指针存储的是其他数据单元(变量/数组/结构体/函数等)的首地址,指针本身并不存储实际的数据
若指针存放了某个数据单元的首地址,则这个指针指向了这个数据单元;若指针存放的值是 0,则这个指针为空指针
表示方法
指针的操作
若已定义:
int a; //定义一个 int 型数据
int *p; //定义一个指向 int 型数据的指针; 注意:int * 是一个整体
则对指针 p 有如下操作方式
【注意事项】
-
在对指针取内容之前,一定要确保指针指在了合法的位置,否则将会导致程序出现不可预知的错误
-
同级指针之间才能相互赋值,跨级赋值将会导致编译器报错或警告
指针的应用
主要讲一下:传递参数 & 传递返回值,其他应用更复杂,后续有机会再写
C语言中函数参数传递的三种方式
- 传值,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个形式参数,因而在函数里对形参的改变不会影响到函数外的变量的值
- 传址,就是传变量的地址赋给函数里形式参数的指针,使指针指向真实的变量的地址,因为对指针所指地址的内容的改变能反映到函数外,也就是能改变函数外的变量的值
- 通过指针来实现,能达到使用的效果如传址,可是使用方式如传值
#include <stdio.h>
void change(int *a, int &b, int c){
c = *a;
b = 30;
*a = 20;
}
int main(){
int a = 10, b = 20, c = 30;
change(&a, b, c);
printf("%d, %d, %d", a, b, c);
return 0;
}
------------------
结果:20 30 30
【分析】
- 指针传参 ➡️ 将变量 a 的地址直接传入函数,函数中可以对其值进行修改
- 引用传参 ➡️ 将变量 b 的引用传入函数,效果和指针相同,同样函数中可以对其值进行修改
- 值传参 ➡️ 在传参过程中,首先将 c 的值复制给函数 c 变量,然后在函数中修改的即是函数的 c 变量,然后函数返回时,系统自动释放变量 c,而对 main 函数的 c 没有影响,故 c 输出的值不变
文章参考
程序中地址与指针实例讲解 文章