代码疑云(11)——指针与类型转换

来源:互联网 发布:数据挖掘毕业设计 编辑:程序博客网 时间:2024/06/14 08:16
1.#include <stdio.h>  2.#include <stdlib.h>  3.void swap(int  *pa, int *pb)  4.{  5.    int temp;  6.    temp = *pa;  7.    *pa = *pb;  8.    *pb = temp;  9.}  10.  11.int main()  12.{  13.  char a[]="BACD";  //a字符串数组  14.   15.  16.  swap((int*)&a[0],(int*)&a[1]);//经过强制转换后交换a和b的值,使原序列变为“ABCD”  17.  18.  19.  printf("after swap:\n");  20.  printf("%s",a);  //打印a字符串数组  21.    22.  system("pause");  23.  return 0;  24.}  

疑:以上c程序调用swap函数后能否得到预期的结果?结果是?

解释:不能,在32位机中,a为char型数组,各元素占用1字节内存空间,而在swap函数声明里的pa和pb为int 型指针,也就是说编译器会把pa,pb解析为指向连续四字节空间的指针,在进行各种运算时就是对pa、pb所指向的四字节进行运算,那么以上程序的pa、pb指向哪里呢?通过打印它们发现pa和pb的地址相差为1,pa小于pb,因为pa,pb对应a数组的地址所以实际上pa所指的四个字节是a数组下标第0,1,2,3的四个元素,而pb指向a数组下标为1,2,3,4的四个元素。图示:

 

pa对应a数组编号:       0        1       2      3

pa所指内存空间: | ‘B’ | ‘A’ | 'C' | 'D' |

 

pb对应a数组编号:      1        2       3      4

pb所指内存空间: | ’A‘ | 'C' | 'D' |'\0' |

所以在swap里,首先temp存储了*pa为[B,A,C,D],执行*pa=*pb后pa就变为[A,C,D,\0],此时a数组就变为[A,C,D,\0,\0], 然后执行*pb=temp,结果pb=[B,A,C,D],a数组又变为[A,B,A,C,D]。所以打印a字符串数组的最终结果是:ABACD然后后面跟着一堆乱码。

总结:强制转换指针变量类型是不明智的选择,除非你能确保转换后所指向的内存空间大小与没转换后是一样的,如果不是将会带来灾难性的后果,导致程序中其它变量被串改或由于指向了某段未经声明的内存空间而变为野指针。