以前不明白这句话,c语言能让程序员为所欲为。这里谈谈一点体会,c语言之所以强大,很重要的一点是c的强制类型转换,这使得程序员能够突破原来定义的类型而操作内存中额外的部分。这里的“强制类型转换”,以前因为人云亦云自己也这样说,今天看来确实不太恰当,容易造成日后的误解。
看一段代码:
char *p = (char *)malloc(1024);
memset(p, 0, 1024);
printf("p=0x%x\n", (unsigned int)p);
*(char **)p = 0x12345678;//注意这句
printf("p=0x%x\n",(unsigned int)p);
free(p);
如果按照“强制类型转换”的概念,会认为注释那句就是把p的类型强制转成char**,然后*((char**)p)就是指向char的指针,把这个指针p赋值为0x12345678。但是事实上p本身的值没有改变,只是p指向的内容改变了。所以这个“强制类型转换”说法不当,而应该是“强制类型认为”,也就是说把p强制认为是char**类型,*(char **)p强制认为p指向的内容是char*(这样就不是声明时认为的char了),然后把这些内容改为0x12345678。整个过程p的类型都是char* 没有变,编译器就是这么认为的,是我们程序员强制认为p是不同类型的指针,好方便向其所指的内容赋不同类型(大小)的值而已。
严格地说强制类型转换会发生在类型变量中而不是指针变量中:
int data=1;
int *pdata=&data;
unsigned char *p=pdata;//强制类型认为
unsigned char toc=*pdata;//强制类型转换,把原来是int型的内容转换为unsigned char
这个例子在小端模式下说明不了问题( *p还是为1,toc=1),在大端模式下就知道了( *p为0,toc=1)。
看一段代码:
char *p = (char *)malloc(1024);
memset(p, 0, 1024);
printf("p=0x%x\n", (unsigned int)p);
*(char **)p = 0x12345678;//注意这句
printf("p=0x%x\n",(unsigned int)p);
free(p);
如果按照“强制类型转换”的概念,会认为注释那句就是把p的类型强制转成char**,然后*((char**)p)就是指向char的指针,把这个指针p赋值为0x12345678。但是事实上p本身的值没有改变,只是p指向的内容改变了。所以这个“强制类型转换”说法不当,而应该是“强制类型认为”,也就是说把p强制认为是char**类型,*(char **)p强制认为p指向的内容是char*(这样就不是声明时认为的char了),然后把这些内容改为0x12345678。整个过程p的类型都是char* 没有变,编译器就是这么认为的,是我们程序员强制认为p是不同类型的指针,好方便向其所指的内容赋不同类型(大小)的值而已。
严格地说强制类型转换会发生在类型变量中而不是指针变量中:
int data=1;
int *pdata=&data;
unsigned char *p=pdata;//强制类型认为
unsigned char toc=*pdata;//强制类型转换,把原来是int型的内容转换为unsigned char
这个例子在小端模式下说明不了问题( *p还是为1,toc=1),在大端模式下就知道了( *p为0,toc=1)。