C语言怯魅——指针和数组
指针—— C的精华,也是重难点,很多人将C作为入门语言,指针往往成了新手入门编程的拦路虎。 其本质很简单,但由于衍生出来的用法多样,知晓如何以及何时使用指针并不简单。
以下是我个人的一些经验分享:
1. 指针的本质
- 直接从字面意思来理解,就是指向一个方向的方向标,可以类比为指南针的磁针
- 指针其指向的位置——地址(这里往往会和数组结合起来)
2. 指针的运用
1. 解引用 *
- 因为指向地址,而非值,需要解引用”*“(一个星号)
- 通过解引用指针可以直接对数据进行修改(就相当于一座桥梁,直接让作用对象变为了数值)
#include <stdio.h>
int main() {
// 定义并初始化一个整数数组
int arr[5] = {10, 20, 30, 40, 50};
// 定义一个整数变量
int num;
// 让指针 ptr 指向变量 num
int *ptr = #
// 将数组 arr 的首元素的值赋给 ptr 所指向的变量
*ptr = *arr; // 不可以的理解为ptr = arr 这是两个东西
//上式的本质是值的赋值,而ptr = arr是地址的赋值 // 非常重要
// 输出 ptr 所指向变量的值
printf("ptr 指向的变量的值是: %d\n", *ptr);
return 0;
}
2. 改变实参的值
- 指针传入函数后,函数依据指针所指向的地址,就可以直接对传入的实参进行修改
- 因为指针可以改变实参的值
(直接对数据本身进行修改(指针一般无法改变其指向的数据类型),”本源伤害“)
因此在函数传参时传入在形参前加上*,就可以对传入的函数值进行修改
以下是示例:
#include <stdio.h>
// 交换两个整数的值的函数
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int num1 = 10;
int num2 = 20;
printf("交换前: num1 = %d, num2 = %d\n", num1, num2);
// 调用 swap 函数,传入 num1 和 num2 的地址
swap(&num1, &num2);
printf("交换后: num1 = %d, num2 = %d\n", num1, num2);
return 0;
}
解析:
- 一个简单的通过传入指针实现值交换的函数。
- 这里指针的运用使得形参可以对实参产生影响
3. 与数组的结合
- 数组的名称就是它的首地址,比如:
int arr[10]; //这里arr就是数组的首地址
- 在传入函数的时候,可以将数组名传入函数其实就是将数组的地址传入
- 如此就可以实现对数组的元素进行修改
要注意:
-
这里数组名已经是地址了,传入函数时,如果要求传入的是数组的地址
-
不要对它解引用,否则传入的将是数组的第一个元素
-
(对数组首地址解引用不就是对数组的第一个元素的地址解引用吗!
解出来当然是数组的一个元素了)
-
那么如果要传入第i个数组元素的地址,那该传入的就该是arr[i]了
-
如果定义了一个*ptr(pointer的简写)指向arr[10],那就该写为
int *ptr;
int arr[10];
ptr = arr;
-
以下代码中的*ptr = *arr,其实就是ptr = arr的对赋值语句两边的解引用,
从而实现对指针指向的值的赋值
#include <stdio.h>
int main() {
// 定义并初始化一个整数数组
int arr[5] = {10, 20, 30, 40, 50};
// 定义一个整数变量
int num;
// 让指针 ptr 指向变量 num
int *ptr = #
// 将数组 arr 的首元素的值赋给 ptr 所指向的变量
*ptr = *arr;
// 输出 ptr 所指向变量的值
printf("ptr 指向的变量的值是: %d\n", *ptr);
return 0;
}
4. &取地址符——解引用的逆操作
总结:
指针在C语言中非常重要,也是C++中许多操作的内置机理(比如引用)
熟练掌握指针的使用场景,会为未来学习C++以及其他语言打好基础。
本文篇幅不长,列举的例子也都比较简单,指针的运用要多写代码,才能加深理解。
不必因为一时学习指针有些困难垂头丧气,再啃一段时间,对其理解慢慢加深后,就会感觉好很多。