指针作为函数参数
指针作为函数参数是 C 语言中实现"传址调用"的方式。通过传递变量的地址,函数可以修改调用者的变量,也可以避免大型结构体的复制开销。
修改实参
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int x = 3, y = 5;
swap(&x, &y); /* x = 5, y = 3 */
传递大型结构体
struct BigData { char buffer[1000]; };
/* 传值:复制 1000 字节 */
void process_value(struct BigData data);
/* 传指针:只复制 4/8 字节 */
void process_pointer(const struct BigData *data);
输出参数
/* 通过指针返回多个值 */
void divide(int a, int b, int *quotient, int *remainder)
{
*quotient = a / b;
*remainder = a % b;
}
int q, r;
divide(17, 5, &q, &r); /* q = 3, r = 2 */
数组参数
/* 数组退化为指针 */
void fill(int arr[], int n, int value)
{
for (int i = 0; i < n; i++)
arr[i] = value;
}
int data[10];
fill(data, 10, 0); /* 填充为 0 */
const 保护
/* 承诺不修改 */
void print(const int arr[], int n);
/* 可以修改 */
void sort(int arr[], int n);
常见错误
忘记取地址:
int x = 10;
swap(x, y); /* 错误:传递的是值,不是地址 */
/* 正确 */
swap(&x, &y);
空指针:
void func(int *p)
{
*p = 10; /* 危险:如果 p 为 NULL,崩溃 */
}
/* 正确 */
void func(int *p)
{
if (p != NULL)
*p = 10;
}
最佳实践
- 需要修改实参时,传指针
- 大型结构体传
const指针 - 输出参数放在参数列表后面
- 检查指针是否为 NULL
- 用
const明确表达不修改的意图