1. 实参与形参相互独立
在 C 语言中,函数内部的参数(形参)与外部传入的变量(实参)是独立的。在前面的示例中,我们来看看如何通过一个 `swap` 函数交换两个变量的值:
```
#include <stdio.h>
void swap(int x, int y) {
int temp = x;
x = y;
y = temp;
}
int main() {
int a, b;
a = 1;
b = 2;
printf("a=%d b=%d\n", a, b);
// 调用 swap 函数
swap(a, b);
// 结果依然是 a 和 b 的初始值
printf("a=%d b=%d\n", a, b);
return 0;
}
```
在这个例子中,尽管我们在函数 `swap` 中交换了 `x` 和 `y` 的值,但它们不会影响到 `main` 函数中的 `a` 和 `b`。因为它们是独立的。
2. 使用指针作为参数
由于我们无法直接修改 `main` 中的变量,可以通过传入变量的地址(指针)来间接修改它们。这里是代码示例:
```
#include <stdio.h>
void swap(int *x, int *y) {
int temp = *x;
*x = *y;
*y = temp;
}
int main() {
int a, b;
a = 1;
b = 2;
printf("a=%d b=%d\n", a, b);
// 传递变量的地址
swap(&a, &b);
printf("a=%d b=%d\n", a, b);
return 0;
}
```
在这个例子中,我们将 `a` 和 `b` 的地址传入 `swap` 函数。通过指针,我们可以在函数内部修改它们的值。
3. 指针不仅仅是首地址
指针存储的不仅仅是变量的首地址,还包含了数据类型的信息。这是很重要的一点。不同类型的指针在进行算术运算时,步长是由它们所指向的数据类型决定的。例如:
- `char *` 的步长是 `sizeof(char)`
- `int *` 的步长是 `sizeof(int)`
这样,指针能够知道如何正确地计算内存中的位置。
4. 使用 `void *` 使函数更通用
如果我们想让 `swap` 函数能够交换不同类型的变量,可以使用 `void *` 类型的指针,它仅保存首地址,不包含类型信息。这里是修改后的函数定义:
```
#include <stdio.h>
void swap(void *x, void *y, int size) {
char *pX = (char *)x;
char *pY = (char *)y;
char temp;
for (int i = 0; i < size; i++) {
temp = pX[i];
pX[i] = pY[i];
pY[i] = temp;
}
}
// 示例调用
int main() {
int a = 1, b = 2;
swap(&a, &b, sizeof(int));
printf("a=%d b=%d\n", a, b);
return 0;
}
```
在这个例子中,通过将 `void *` 指针转换为 `char *`,我们能够逐个字节交换内存内容。这样,`swap` 可以用于不同类型的变量。
总之,使用指针和 `void *` 让我们的函数更加灵活,能够处理多种数据类型,而不仅仅局限于特定的类型。希望这个解释能够帮助你更好地理解指针和参数传递的机制!