08-C语言指针(续2)

plana_lab 发布于 19 天前 82 次阅读


接上集,我们来学习指针和函数的关系


指针与函数

前面我们学习了指针可以通过地址访问和修改数据。

例如:

int a = 10;
int *p = &a;

*p = 20;

此时:

a → 20
*p → 20

那么问题来了:

如果把变量传给函数,函数能不能直接修改这个变量?


普通函数参数

先看一个简单的例子:

#include <stdio.h>

void change(int x) {
    x = 20;
}

int main() {

    int a = 10;

    change(a);

    printf("%d\n", a);

    return 0;
}

输出:

10

虽然调用了:

change(a);

但是 a 并没有变成 20。

为什么?

因为:

void change(int x)

这里的 x 是函数自己的一个变量。

调用:

change(a);

实际上是把 a 中的数据复制给了 x。

可以理解成:

main:

a
↓
10


调用 change(a)

↓


函数:

x
↓
10

此时实际上存在两个变量:

a → 10

x → 10

所以:

x = 20;

修改的是 x,而不是 a。

函数结束后,x 被销毁:

a → 10

所以最后还是:

10

通过指针让函数修改变量

如果希望函数修改 a,就可以把 a 的地址传给函数。

例如:

#include <stdio.h>

void change(int *p) {
    *p = 20;
}

int main() {

    int a = 10;

    change(&a);

    printf("%d\n", a);

    return 0;
}

输出:

20

这里发生了什么?

首先:

int a = 10;

然后:

change(&a);

把 a 的地址传给了函数。

函数:

void change(int *p)

使用一个 int * 类型的指针接收这个地址。

可以理解为:

main:

a
↓
┌──────┐
│  10  │
└──────┘
   ↑
   │
  &a
   │
   ↓
函数:

p
↓
保存 a 的地址

因此:

*p

就可以通过这个地址访问 a。

执行:

*p = 20;

实际上修改的是 a。

所以:

a → 20
*p → 20

函数中的指针参数

来看完整的关系:

void change(int *p)

这里的:

int *p

表示:

p 是一个 int 类型的指针变量。

调用:

change(&a);

就是把:

&a

传给函数。

所以:

&a
 ↓
a的地址
 ↓
p保存这个地址
 ↓
*p
 ↓
访问a

因此:

*p = 20;

就可以修改 a。


一个更直观的例子

#include <stdio.h>

void add(int *p) {
    *p = *p + 10;
}

int main() {

    int a = 10;

    add(&a);

    printf("%d\n", a);

    return 0;
}

输出:

20

执行:

add(&a);

之后:

a → 10

&a
 ↓
p

函数执行:

*p = *p + 10;

实际上就是:

*p → 10

10 + 10

*p → 20

a → 20

为什么要传地址?

如果只是:

change(a);

传进去的是:

a中的数据

函数得到的是数据的副本:

a → 10

x → 10

修改 x 不会影响 a。

而:

change(&a);

传进去的是:

a的地址

函数得到的是这个地址:

a
↓
10
↑
│
p

所以函数可以通过:

*p

找到并修改原来的数据。

可以简单记成:

传值:

a → 10
     ↓
     x → 10

修改x
↓
a不变


传地址:

a → 10
↑
│
p

*p → 10

修改*p
↓
a也改变

函数修改数组

前面我们学习了指针可以遍历数组。

因此也可以把数组的地址传给函数。

例如:

#include <stdio.h>

void print_array(int *p, int size) {

    for (int i = 0; i < size; i++) {
        printf("%d\n", *(p + i));
    }

}

int main() {

    int a[5] = {10, 20, 30, 40, 50};

    print_array(a, 5);

    return 0;
}

输出:

10
20
30
40
50

这里:

print_array(a, 5);

数组名 a 在这里会转换成指向第一个元素的指针。

因此函数接收到的:

int *p

指向:

a[0]

然后:

*(p + i)

就可以访问数组中的每一个元素。

关系是:

a
↓
a[0] 的地址
↓
p

p + 0 → a[0]
p + 1 → a[1]
p + 2 → a[2]
p + 3 → a[3]
p + 4 → a[4]

函数通过指针修改数组

不仅可以读取数组,还可以修改数组。

例如:

#include <stdio.h>

void change_array(int *p, int size) {

    for (int i = 0; i < size; i++) {
        *(p + i) = *(p + i) * 2;
    }

}

int main() {

    int a[5] = {1, 2, 3, 4, 5};

    change_array(a, 5);

    for (int i = 0; i < 5; i++) {
        printf("%d\n", a[i]);
    }

    return 0;
}

输出:

2
4
6
8
10

因为函数中的:

*(p + i)

访问的就是 a[i]。

所以:

*(p + i) = *(p + i) * 2;

实际上就是修改数组中的元素。


指针与函数的核心

到这里,我们可以把前面学习的内容全部连接起来:

变量
 ↓
变量有地址
 ↓
&a 获取地址
 ↓
指针保存地址
 ↓
*p 通过地址访问数据
 ↓
把地址传给函数
 ↓
函数通过指针访问和修改原来的数据

例如:

void change(int *p) {
    *p = 20;
}

int main() {

    int a = 10;

    change(&a);

    printf("%d\n", a);

}

核心关系:

a
↓
&a
↓
传给函数
↓
p
↓
*p
↓
修改a

记住:

普通参数:

change(a)

传递a中的数据


指针参数:

change(&a)

传递a的地址

因此,当函数需要修改调用者中的变量时,就可以使用指针参数。

此作者没有提供个人介绍。
最后更新于 2026-09-17