广义上讲,参数传递有两种方式:传值和传引用。 下面我们按入参的形式分别讨论。 1、传值 #include <stdio.h> #include <stdlib.h> #include <string.h> void func(int j) { printf(" j的地址是 %d/n", &j); printf(" j的值是 %d/n", j); j = 5; printf(" j = 5;/n"); } void main() { printf("-------测试传值-------/n"); int i = 1; printf("int i = 1;/n"); printf("i的地址是 %d/n", &i); printf("func(i)/n"); printf("{/n"); func(i); printf("}/n"); printf("调用函数后,i的值是 %d/n", i); getchar(); } 编译运行后,我们发现,在调用func函数时,形参j的地址与实参i的地址不同,这就意味着,在参数传递过程中,做了一次copy。 那么我们在函数func内部,对j所做的任何操作,与函数外面的i没有任何关系。 2、传值、一级指针和二级指针的比较 #include <stdio.h> #include <stdlib.h> void fa(int i) { printf(" 形参i的地址是:%d/n", &i); i = 5; printf(" i = 5;/n"); printf(" 形参i的值是:%d/n", i); } void fb(int* ptr) { printf(" 形参ptr的地址是:%d/n", &ptr); printf(" 形参ptr的值是:%d/n", ptr); *ptr = 5; printf(" *ptr = 5;/n"); printf(" 形参ptr的所指向的值是:%d/n", *ptr); } void fc(char** ptr) { printf(" 形参ptr的地址是:%d/n", &ptr); printf(" 形参ptr的值是:%d/n", ptr); *ptr = (char*)malloc(10 * sizeof(char)); printf(" *ptr = (char*)malloc(10 * sizeof(char));/n"); printf(" 形参ptr的所指向的值是:%d/n", *ptr); } void main() { printf("-------测试传指针-------/n"); printf("/n传递整型/n"); int a = 1; printf("int a = 1;/n"); printf("a的地址是:%d/n", &a); printf("fa(a)/n"); printf("{/n"); fa(a); printf("}/n"); printf("调用fa后a的值:%d/n", a); printf("/n传递指针/n"); int* b = &a; printf("int* b = &a;/n"); printf("b指向的值是:%d/n", *b); printf("fb(b)/n"); printf("{/n"); fb(b); printf("}/n"); printf("调用fb后b指向的值是:%d/n", *b); printf("/n传递二级指针/n"); char* c = NULL; printf("char* c = NULL;/n"); printf("c的地址是:%d/n", &c); printf("fc(&c)/n"); printf("{/n"); fc(&c); printf("}/n"); printf("调用fc后c的值:%d/n", c); delete c; getchar(); } 编译运行后,我们可以看到,无论我们传递的是整型、指针还是二级指针,参数都会进行复制。也就是说,形参是实参的一个拷贝。 对于实参是整型来说,修改形参的值,对于实参毫无影响; 对于实参是指针来说,我们需要注意到的是,实参和形参指向的是相同的地址,或者说是相同的目标。所以,在函数内部修改这个目标的值后, 函数外部在访问时,会发现这个目标值发生了变化。 对于实参是二级指针来说,我们需要注意到的是,传入的是一个指针的地址,在函数内部,对这个指针的地址重新赋值。对于一级指针, 我们改变的是指针指向的目标的值,而二级指针,我们改变的是这个指针本身,也就是说,让这个指针指向了另外的目标。 3、传数组 对于传递数组参数,有一点需要注意,数组会退化为指针(即按引用传递),所以使用sizeof是无法取得数组的大小的。 #include <stdio.h> #include <string.h> void test(char str[20]) { printf(" str的地址: %d/n", str); printf(" str size = %d/n", sizeof(str)); strcpy(str, "你好你好你好"); printf(" strcpy(str, /"你好你好你好/");/n"); } void main() { char str[20] = {0}; strcpy(str, "hello"); printf("str的地址: %d/n", str); printf("str: %s/n", str); printf("str size = %d/n", sizeof(str)); printf("test(str)/n"); printf("{/n"); test(str); printf("}/n"); printf("str: %s/n", str); getchar(); } 4、传值、引用和指针的比较 #include <stdio.h> void swapa(int x, int y) { printf("&x = %d, &y = %d/n", &x, &y); int temp = x; x = y; y = temp; } void swapb(int& x, int& y) { printf("&x = %d, &y = %d/n", &x, &y); int temp = x; x = y; y = temp; } void swapc1(int* x, int* y) { printf("&x = %d, &y = %d/n", &x, &y); int* temp = x; x = y; y = temp; } void swapc2(int* x, int* y) { printf("&x = %d, &y = %d/n", &x, &y); int temp = *x; *x = *y; *y = temp; } int main(void) { printf("-------初始-------/n"); int a = 1; int b = 2; printf("&a = %d, &b = %d/n", &a, &b); printf("a = %d, b = %d/n", a, b); printf("/n-------传值-------/n"); swapa(a, b); printf("a = %d, b = %d/n", a, b); a = 1; b = 2; printf("/n-------传引用-------/n"); swapb(a, b); printf("a = %d, b = %d/n", a, b); a = 1; b = 2; printf("/n-------传指针1-------/n"); swapc1(&a, &b); printf("a = %d, b = %d/n", a, b); a = 1; b = 2; printf("/n-------传指针2-------/n"); swapc2(&a, &b); printf("a = %d, b = %d/n", a, b); getchar(); return 0; } swapb(int x, int y)采用传引用的方式,传入的实参实际上是a和b的引用,对引用的改变会直接反应到a和b本身。