& 是一个运算符,它的具体含义取决于它使用的上下文,主要有两种情况:

- 作为一元运算符(单目运算符):用于获取一个变量在内存中的地址,这是在函数参数中最常见的情况。
- 作为二元运算符(双目运算符):用于对两个数的二进制表示进行“按位与”操作。
下面我们重点讲解在函数参数中的第一种情况,也就是你问题中提到的 amp 参数。
核心概念:值传递 vs. 地址传递
要理解 & 作为参数的用途,首先要明白 C 语言函数调用的核心机制:值传递。
- 值传递:当你调用一个函数并传递一个参数时,C 语言会为这个参数创建一个副本,函数内部操作的是这个副本,原始变量的值不会被改变。
这会导致一个问题:如果我们想在函数内部修改一个函数外部的变量,该怎么办?
答案就是使用 & 运算符,将变量的地址传递给函数,这样,函数内部就可以通过这个地址直接找到并操作原始变量本身,这种方式通常被称为地址传递或引用传递(虽然 C 语言没有真正的引用,但效果类似)。

& 作为函数参数的详细解释
语法
当你定义一个函数时,如果希望接收一个变量的地址,你需要在函数的形参中使用 指针。
// 函数定义
void my_function(int *ptr) {
// ...
}
// 函数调用
int my_var = 10;
my_function(&my_var); // 注意这里的 & 符号
int *ptr:这是一个指针参数。 表示ptr是一个指针,int表示它指向一个整型变量的地址。&my_var:在调用函数时,&my_var获取my_var变量的内存地址,并将这个地址传递给my_function。
为什么需要这么做?(经典例子:交换两个变量的值)
假设我们想写一个函数来交换两个整数的值,如果我们不使用 &,会发生什么?
错误示例(值传递,无法交换)
#include <stdio.h>
// 尝试交换两个值,但会失败
void swap_fail(int a, int b) {
int temp = a;
a = b;
b = temp;
printf(" (在 swap_fail 函数内) a = %d, b = %d\n", a, b);
}
int main() {
int x = 5;
int y = 10;
printf("调用前: x = %d, y = %d\n", x, y);
swap_fail(x, y); // 传递的是 x 和 y 的副本
printf("调用后: x = %d, y = %d\n", x, y); // x 和 y 的值没有改变
return 0;
}
输出结果:

调用前: x = 5, y = 10
(在 swap_fail 函数内) a = 10, b = 5
调用后: x = 5, y = 10
分析:
swap_fail 函数内部确实交换了 a 和 b 的值,但交换的只是 x 和 y 的副本,当函数执行完毕,这些副本被销毁,main 函数中的 x 和 y 原始值保持不变。
正确示例(地址传递,成功交换)
现在我们使用 & 和指针来实现真正的交换。
#include <stdio.h>
// 成功交换两个变量的值
void swap_success(int *ptr_a, int *ptr_b) {
int temp = *ptr_a; // *ptr_a 是获取 ptr_a 地址上存储的值(即 x 的值)
*ptr_a = *ptr_b; // 将 y 的值赋给 x 的地址
*ptr_b = temp; // 将原来的 x 的值赋给 y 的地址
}
int main() {
int x = 5;
int y = 10;
printf("调用前: x = %d, y = %d\n", x, y);
swap_success(&x, &y); // 传递 x 和 y 的地址
printf("调用后: x = %d, y = %d\n", x, y); // x 和 y 的值成功交换
return 0;
}
输出结果:
调用前: x = 5, y = 10
调用后: x = 10, y = 5
分析:
main函数调用swap_success(&x, &y),将x和y的地址分别传递给ptr_a和ptr_b。ptr_a指向x。ptr_b指向y。
- 在
swap_success函数内部:*ptr_a表示“取出ptr_a所指向地址的值”,也就是x的值(5)。*ptr_b表示“取出ptr_b所指向地址的值”,也就是y的值(10)。
- 通过操作
*ptr_a和*ptr_b,我们实际上是在直接修改x和y在内存中存储的值,从而实现了真正的交换。
& 作为参数的关键点
| 特性 | 描述 |
|---|---|
| 符号 | & (读作 "ampersand" 或 "取地址") |
| 作用 | 获取一个变量的内存地址。 |
| 用途 | 将变量的地址传递给函数,以便函数可以直接修改原始变量。 |
| 函数参数类型 | 必须是指针,传递 int 变量的地址,参数类型应为 int *。 |
| 在函数内部 | 使用 (解引用/间接寻址) 运算符来访问或修改指针所指向地址的值。 |
& 的另一个用途:按位与(Binary AND)
虽然这通常不是在函数参数的上下文中讨论的,但为了完整性,也提一下 & 的第二个身份。
当 & 用于两个整数之间时,它会对两个数的二进制位进行与操作。
规则: 只有当两个对应位都为 1 时,结果的该位才为 1,否则为 0。
示例:
int a = 5; // 二进制: 0101 int b = 3; // 二进制: 0011 int c = a & b; // c 的结果是多少? // 计算过程: // 0101 (a) // & 0011 (b) // ------ // 0001 (c) // c 的值是 1
注意: 这种用法和取地址的 & 完全是两个不同的运算符,只是恰好使用了同一个符号,编译器会根据上下文来判断它的含义。
当你在 C 语言的函数参数中看到 amp (即 &) 时,它几乎总是指 “取地址” 运算符,这是 C 语言实现“引用传递”效果、让函数能够修改外部变量的核心机制,它将一个指针(内存地址)传递给函数,函数内部再通过这个指针来操作原始数据。
