传址调用就是传地址调用,也称为传引用调用。函数的另外一种调用方式是传值调用。
传值调用建立参数的一份拷贝并把它传给调用的函数,在调用函数中修改参数值的拷贝不影响原始的变量值;传引用调用允许调用函数修改原始变量的值。
如何写一个函数来交换两个整数变量呢?
1 2 3 4 5 | void swap(int x, int y) { int t; t = x; x = y; y = t; } |
显然是不行的。 swap 并不知道参数的实际地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h> void swap(int *px, int *py) { int t; t = *px; *px = *py; *py = t; } int main(int argc, char *argv[]) { int a=5, b=3; swap(&a, &b); printf("%d %d\n", a, b); return 0; } |
你需要告诉 swap,参数 a 和 b 的地址才能完成真正的交换操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <stdio.h> void swap(int *px, int *py) { int t; printf("px=%p\n", px); printf("py=%p\n", py); t = *px; /* 将地址 px 指向的值保存到 t */ *px = *py; /* 将地址 py 指向的值直接保存到地址 px */ *py = t; /* 将值 t 直接保存到地址 py */ } int main() { int a=5, b=3; printf("a address is %p\n", &a); printf("b address is %p\n", &b); swap(&a, &b); printf("%d %d\n", a, b); return 0; } |
程序运行结果如下:
1 2 3 4 5 | a address is 0028FF3C b address is 0028FF38 px=0028FF3C py=0028FF38 3 5 |
a 和 b 的地址由操作系统动态分配,未必和上面的结果一致。
1 |
定义函数,求两个浮点数的之和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h> double add(double x,double y) { double z; z=x+y; return z; } int main() { double a,b,c; scanf("%lf %lf",&a,&b); c=add(a,b); printf("sum is %.3lf\n",c); return 0; } |
如果要求变一下:定义函数,求两个浮点数的之和、差
可以分别定义两个函数来完成,可以再定义一个新的函数。但如果只能使用一个函数呢? 一个函数只能有一个返回值,如果同时提供两个返回值呢?
在C语言中,可以通过地址传递来解决。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <stdio.h> void add_sub(double x,double y, double *t1, double *t2) { *t1=x+y; *t2=x-y; } int main() { double a,b,c, d; scanf("%lf %lf",&a,&b); add_sub(a,b, &c, &d); printf("sum is %.3lf, sub is %.3lf\n",c, d); return 0; } |
传址调用的另外的一个作用就是避免数组的复制(或移动)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <stdio.h> void bubble_sort(int v[ ], int n) { int i, j, t; printf("%p-%p\n", v, v+n); for(i=0; i<n-1; i++) for (j=0; j<n-1-i; j++) if (v[j]>v[j+1]) { t = v[j]; v[j] = v[j+1]; v[j+1]=t; } } int main(int argc, char *argv[]) { int v[6] = { 2, 3, 9, 1, 0, 7}; int i; bubble_sort(v, 6); for (i=0; i<6; i++) printf("%d ", v[i]); printf("\n"); return 0; } |