C 语言 第五章 指针(5)
目录
函数参数传递机制:地址传递
值传递
简单变量指针作为形参
举例1:
举例2:
举例3:
数组作为形参
举例:
函数参数传递机制:地址传递
值传递
void test(int a, int b) { a = 10; b = 20; printf("test函数输出: a = %d,b = %d\n", a, b); // 10 20
}
int main() { int x = 6, y = 8; printf("调用函数之前: x = %d,y = %d\n", x, y); // 6 8 输出调用test()函数之前x,y都值test(x, y); printf("调用函数之后:x = %d,y = %d\n", x, y);//6 8 输出调用test()函数之后的值
}
分析:为什么在 test() 函数内变量 a 和 b 的值改变,而主调函数 main() 中实参 x 和 y 却没有改变?
原因:
- 这是参数按值传递的缘故。如果想要实现值的改变,这就需要传入变量的地址,即地址传递。
- 地址传递,又称传地址方式、指针传递,就是把实参地址进行复制,传送给形参。
- 实参将地址传递给形参,二者地址值相同。
简单变量指针作为形参
当函数的形参类型是指针类型时,使用该函数时,需要传递指针或者地址给该形参。函数内以指针的方式操作变量。
举例1:
int num = 100;
int* p1 = #
int* p2 = p1;
*p2 = 50;
printf("%d\n", num); //50
举例2:
void increment(int* a) { (*a)++; printf("a = %d\n", *a); // a = 11
}
int main() { int i = 10; printf("i = %d\n", i); // i = 10 increment(&i); printf("i = %d\n", i); // i = 11 return 0;
}
注:因为传入的是地址,函数体内部对该地址包含的值的操作,会影响到函数外部变量的值。
举例3:
void test(int* a, int* b) { //函数参数为指针类型 *a = 10; *b = 20; printf("test函数输出*a = %d,*b = %d\n", *a, *b); //输出交换后的结果
}
int main() { int x = 6, y = 8; printf("调用函数之前:x = %d,y = %d\n", x, y); //输出调用test()函数之前x,y的值 test(&x, &y); printf("调用函数之后:x = %d,y = %d\n", x, y); //输出调用test()函数之后x,y的值
}
注:通过传入x,y的地址,函数内部就可以直接操作该地址,从而实现改变两个变量的值
数组作为形参
数组名本身就代表该数组首地址,传数组的本质就是传地址。
因此,把数组名传入一个函数,就等同于传入一个指针变量。在函数内部,就可以通过这个指针变量获得整个数组。
举例:
定义一个数组,通过函数给数组元素赋值
void setvalue(int vals[], int len) { for (int i = 0; i < len; i++) { vals[i] = i * 10; }
}
int main() { int nums[5] = {0}; //数组初始化 setvalue(nums, 5); //调用函数,传递数组名和简单变量 printf("调用函数后输出结果:\n"); for (int i = 0; i < LENGTH; i++) { //遍历数组元素 printf("nums[%d] = %d\n", i, nums[i]); } return 0;
}
上例中,传入一个整数数组,与传入一个整数指针是同一回事,数组符号 [] 与指针符号 * 是可以互换的。比如:
void setvalue1(int *vals, int len) { int i; for (i = 0; i < len; i++) { vals[i] = i * 10; }
}