C语言学习 指针: 案例: 交换两个变量的值
第一版:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <io_utils.h> 5 6 void Swap(int a,int b){ 7 int temp=a; 8 a=b; 9 b=temp; 10 } 11 12 int main() { 13 { 14 int a=1; 15 int b=2; 16 Swap(a,b); 17 PRINT_INT(a); 18 PRINT_INT(b); 19 } 20 return 0; 21 }
交换完, 没起作用。 因为参数传进去了, 这个变量是复制一份, 所以函数中的a和b跟外部的a和b不是一个东西,所以不起作用
第二版, 好用,
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <io_utils.h> 5 6 void Swap(int *a,int *b){ 7 int temp=*a; 8 *a=*b; 9 *b=temp; 10 } 11 12 int main() { 13 { 14 int a=1; 15 int b=2; 16 Swap(&a,&b); 17 PRINT_INT(a); 18 PRINT_INT(b); 19 } 20 return 0; 21 }
第二版, 但是如果交换别的类型, 那就不支持了。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <io_utils.h> 5 6 void Swap(int *a,int *b){ 7 int temp=*a; 8 *a=*b; 9 *b=temp; 10 } 11 12 int main() { 13 { 14 int a=1; 15 int b=2; 16 17 double c=3.0; 18 double d=4.0; 19 20 Swap(&a,&b); 21 PRINT_INT(a); 22 PRINT_INT(b); 23 24 Swap(&c,&d); 25 PRINT_DOUBLE(c); 26 PRINT_DOUBLE(d); 27 } 28 return 0; 29 }
上面这个为什么交换完, 没变呢, 因为int是4个字节, double是8个字节, 函数中用int 接收, 这里的a 的值其实是头4位,00 00 00 00, 值是0, b的值也是头4位, 也是0, 所以只交换了头4位,对于后四位没变化,整个值也就没变化了。
内存地址如下
第三版, 支持不同类型
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <io_utils.h> 5 6 void Swap(void *a,void *b, size_t size){ 7 void *temp= malloc(size); 8 if(temp){ 9 memcpy(temp,a,size); 10 memcpy(a,b,size); 11 memcpy(b,temp,size); 12 }else{ 13 //分配内存失败, 异常处理 14 } 15 } 16 17 int main() { 18 { 19 int a=1; 20 int b=2; 21 22 double c=3.0; 23 double d=4.0; 24 25 Swap(&a,&b,4); 26 PRINT_INT(a); 27 PRINT_INT(b); 28 29 Swap(&c,&d,8); 30 PRINT_DOUBLE(c); 31 PRINT_DOUBLE(d); 32 } 33 return 0; 34 }
第四版: 上面需要传size, C语言可以用宏, 宏不校验参数的类型
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <io_utils.h> 5 6 void Swap(void *a,void *b, size_t size){ 7 void *temp= malloc(size); 8 if(temp){ 9 memcpy(temp,a,size); 10 memcpy(a,b,size); 11 memcpy(b,temp,size); 12 }else{ 13 //分配内存失败, 异常处理 14 } 15 } 16 17 #define SWAP(a,b,type){type temp=a;a=b;b=temp;} 18 19 int main() { 20 { 21 int a=1; 22 int b=2; 23 24 double c=3.0; 25 double d=4.0; 26 27 SWAP(a,b,int); 28 PRINT_INT(a); 29 PRINT_INT(b); 30 31 SWAP(c,d,double); 32 PRINT_DOUBLE(c); 33 PRINT_DOUBLE(d); 34 } 35 return 0; 36 }
第五版: GCC 编译器提供了typeof 方法,这样可以不传type,进行交换
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <io_utils.h> 5 6 void Swap(void *a,void *b, size_t size){ 7 void *temp= malloc(size); 8 if(temp){ 9 memcpy(temp,a,size); 10 memcpy(a,b,size); 11 memcpy(b,temp,size); 12 }else{ 13 //分配内存失败, 异常处理 14 } 15 } 16 17 #define SWAP(a,b){typeof(a) temp=a;a=b;b=temp;} 18 19 int main() { 20 { 21 int a=1; 22 int b=2; 23 24 double c=3.0; 25 double d=4.0; 26 27 SWAP(a,b); 28 PRINT_INT(a); 29 PRINT_INT(b); 30 31 SWAP(c,d); 32 PRINT_DOUBLE(c); 33 PRINT_DOUBLE(d); 34 } 35 return 0; 36 }
第六版, 上面用宏有个坑。 宏相当于替换, 下面main里面的代码, 替换完事成下面第二张图这样了,就直接if结束了, 没有else啥事,所以会报错。
怎么解决上面的问题, 用do while,
或者 用的时候用大括号包起来