user-0 提问: 一个函数原本参数是B类型结构体，把A类型强制转换成B类型传参会打印出的不是原来的成员，而是A类型结构体最后一个成员的原理是什么？

回复:
user: user-1
content: 理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

user: user-2
content: double类型通常是用IEEE 754格式存储的， 当你在第5个字节写入‘z'时，该double值对应的内存数据为0x00000000 0000007A little-endian下会存储如下。 00: ... 04:   01111010 (0x7a) 05:   00000000 06:   00000000 07:   00000000 08:   00000000 09:   00000000 0A:   00000000 0B:   00000000  这一内存数据对应的double值 =  122.0 / (2的1023次方）。 所以当你printf输出的时候之所以会显示为0.000000，是因为这个数太小了。

user: user-0
content: 引用 3 楼 qq423399099 的回复:[quote=引用 2 楼 baidu_28726667 的回复:] [quote=引用 1 楼 qq423399099 的回复:] 楼主你的初始化有问题struct A a={(3,4,7)}; 这样赋值只会让 i 赋上7,而 j 和 k 是不会赋上值的（楼主可以打印验证），所以你强转后打印出来的是7 应该改为以下这样（这样就能打印出3了）  struct A a = {3, 4, 7};   感谢回答啊，原来是这个问题。意思小括号里面的，跟= 一样的效果所以最后是7吗？   另外改了下代码。 这个强制类型转换的打印结果 o=3  i=0  j=0.000000  最后一个0.000000是因为A里面不存第3个成员吧？ 但是char j的‘z’为什么没有能把 asiii值打印出来呢？ 这样强制转换不是第一个成员对第一个成员，第二个对第二个，第三个因为缺少了所以导致打印有问题吗？  #include<stdio.h>  struct A { 	int i; 	char j;  };  struct B { 	char o; 	char i; 	double j; };  void f(struct B* pb) { 	printf("o=%d\n",pb->o); 	printf("i=%d\n",pb->i); 	printf("j=%f\n",pb->j); }  int main(void) { 	struct A a={3,'z'}; 	f((struct B*)&a);  	return 0; } [/quote] 肯定不是一个成员对一个成员的啊，你的B中的两个char都是对着A中的int的，而且一般现在的机子都是小端模式，即低位高字节 i赋成3以后在内存中存储方式为0000 0011 0000 0000 0000 0000 0000 0000,所以B中的o对应前八位0000 0011打印出3 而i对应 0000 0000所以打印出0 之后的double涉及到数据对齐,B中的char o和char i会占8字节（6个字节是补齐double的），（A由于对齐一共占8字节） 所以B中的double指的位置已经超过A了（double j从第九个位置开始）[/quote]  小端不是低字节低地址吗？ 而且stcuct b的  char o 和 char i 不是一共4字节码？我是在ubuntu 12.04 vi gcc编译的 .这个结构体一共12字节。 好像是超过cpu字长按4字节存放？ 所以char o+char i 补齐后一共4字节，而double 要占两个4字节的空间就8个字节，一共12个吧。

user: user-3
content: 引用 2 楼 baidu_28726667 的回复:[quote=引用 1 楼 qq423399099 的回复:] 楼主你的初始化有问题struct A a={(3,4,7)}; 这样赋值只会让 i 赋上7,而 j 和 k 是不会赋上值的（楼主可以打印验证），所以你强转后打印出来的是7 应该改为以下这样（这样就能打印出3了）  struct A a = {3, 4, 7};   感谢回答啊，原来是这个问题。意思小括号里面的，跟= 一样的效果所以最后是7吗？   另外改了下代码。 这个强制类型转换的打印结果 o=3  i=0  j=0.000000  最后一个0.000000是因为A里面不存第3个成员吧？ 但是char j的‘z’为什么没有能把 asiii值打印出来呢？ 这样强制转换不是第一个成员对第一个成员，第二个对第二个，第三个因为缺少了所以导致打印有问题吗？  #include<stdio.h>  struct A { 	int i; 	char j;  };  struct B { 	char o; 	char i; 	double j; };  void f(struct B* pb) { 	printf("o=%d\n",pb->o); 	printf("i=%d\n",pb->i); 	printf("j=%f\n",pb->j); }  int main(void) { 	struct A a={3,'z'}; 	f((struct B*)&a);  	return 0; } [/quote] 肯定不是一个成员对一个成员的啊，你的B中的两个char都是对着A中的int的，而且一般现在的机子都是小端模式，即低位高字节 i赋成3以后在内存中存储方式为0000 0011 0000 0000 0000 0000 0000 0000,所以B中的o对应前八位0000 0011打印出3 而i对应 0000 0000所以打印出0 之后的double涉及到数据对齐,B中的char o和char i会占8字节（6个字节是补齐double的），（A由于对齐一共占8字节） 所以B中的double指的位置已经超过A了（double j从第九个位置开始）

user: user-0
content: 引用 1 楼 qq423399099 的回复:楼主你的初始化有问题struct A a={(3,4,7)}; 这样赋值只会让 i 赋上7,而 j 和 k 是不会赋上值的（楼主可以打印验证），所以你强转后打印出来的是7 应该改为以下这样（这样就能打印出3了）  struct A a = {3, 4, 7};   感谢回答啊，原来是这个问题。意思小括号里面的，跟= 一样的效果所以最后是7吗？   另外改了下代码。 这个强制类型转换的打印结果 o=3  i=0  j=0.000000  最后一个0.000000是因为A里面不存第3个成员吧？ 但是char j的‘z’为什么没有能把 asiii值打印出来呢？ 这样强制转换不是第一个成员对第一个成员，第二个对第二个，第三个因为缺少了所以导致打印有问题吗？  #include<stdio.h>  struct A { 	int i; 	char j;  };  struct B { 	char o; 	char i; 	double j;  };  void f(struct B* pb) { 	printf("o=%d\n",pb->o); 	printf("i=%d\n",pb->i); 	printf("j=%f\n",pb->j); }  int main(void) { 	struct A a={3,'z'}; 	f((struct B*)&a);  	return 0; }

user: user-3
content: 楼主你的初始化有问题struct A a={(3,4,7)}; 这样赋值只会让 i 赋上7,而 j 和 k 是不会赋上值的（楼主可以打印验证），所以你强转后打印出来的是7 应该改为以下这样（这样就能打印出3了）  struct A a = {3, 4, 7};