【C语言】详解 指针
前言:
在学习指针前,通过比喻的方法,让大家知道指针的作用。
想象一下,你在一栋巨大的图书馆里找一本书。如果没有书架编号和目录,这几乎是不可能完成的任务。
在 C 语言中,指针就像是图书馆的索引系统,它能让你快速定位和访问内存中的数据。
一·内存与地址:指针的基础
- 内存:计算机中用于临时存储数据的地方,类似于一排排连续的 "小格子"
- 内存地址:每个小格子的唯一编号,就像房间号一样
- 变量:存储在内存中的数据,有自己的类型和值
当你定义一个变量时,C 语言会在内存中为这个变量分配一块空间:
int num = 10; // 在内存中分配4字节空间存储整数10
char ch = 'A'; // 分配1字节空间存储字符'A'
每个变量都有一个内存地址,可以通过&
运算符获取:
printf("num的地址是:%p\n", &num); // 输出类似0x7ffeefbff5ac的地址值
二·指针变量:存储地址的特殊变量
指针变量是一种特殊的变量,它存储的不是普通的数据,而是内存地址。
定义指针变量的语法如下:
数据类型 *指针变量名;
例如,定义一个指向整数的指针:
int *p; // 定义一个指向int类型的指针p
指针变量也需要初始化,否则它会指向一个随机的内存地址(野指针),这是非常危险的:
int num = 10;int *p = # // 指针p指向变量num的地址
不可以是
int p=#
这样毫无作用。
三·解引用操作符:通过地址访问数据
*
运算符除了用于定义指针外,还有另一个重要作用:解引用(dereference)。通过解引用操作,你可以访问指针所指向的内存位置的数据:
int num = 10;
int *p = #printf("p指向的地址:%p\n", p); // 输出num的地址
printf("p指向的值:%d\n", *p); // 输出10(通过解引用访问num的值)*p = 20; // 通过指针修改num的值
printf("修改后num的值:%d\n", num); // 输出20
以将指针想象成一把钥匙,p
是钥匙本身,而*p
则是用这把钥匙打开的房间里存放的东西。
四·指针与数组:亲密的关系
在 C 语言中,数组名本质上是一个指向数组首元素的常量指针。
例如:
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr; // arr等价于&arr[0],即数组首元素的地址printf("arr[0]的值:%d\n", *p); // 输出1
printf("arr[2]的值:%d\n", *(p + 2)); // 输出3(p+2表示偏移2个int单位的地址)
指针算术是指针操作的重要特性:
- 指针加 1:指向下一个同类型元素(地址值增加 sizeof (数据类型))
- 指针减 1:指向前一个同类型元素
利用指针遍历数组:
int arr[5] = {1, 2, 3, 4, 5};
int *p;for (p = arr; p < arr + 5; p++)
{printf("%d ", *p); // 依次输出1 2 3 4 5
}
五·指针作为函数参数:传值与传址的区别
C 语言中函数参数传递有两种方式:值传递和地址传递。
值传递
void swap(int a, int b)
{int temp = a;a = b;b = temp;
}int main()
{int x = 10, y = 20;swap(x, y); // 值传递,swap函数操作的是x和y的副本printf("x=%d, y=%d\n", x, y); // 输出x=10, y=20,未交换return 0;
}
地址传递(址传递)
void swap(int *a, int *b)
{int temp = *a;*a = *b;*b = temp;
}int main()
{int x = 10, y = 20;swap(&x, &y); // 传递地址,swap函数直接操作x和y的内存printf("x=%d, y=%d\n", x, y); // 输出x=20, y=10,成功交换return 0;
}