user-0 提问: 给出程序，求各式结果并分析!!

回复:
user: user-0
content: 谢谢各位的解答！

user: user-1
content: 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

user: user-2
content: 引用 3 楼 自信男孩 的回复:第一个sizeof是考察结构体对齐的知识点，在32位系统里是按照4字节对齐的，不足4字节的编译器会补齐4字节。因此：short int data; char ha;  data加上ha的长度是3个字节，因此会补一个字节。short ba[5];长度是10字节，因此后面也会补2个字节。所以长度是28；  c. p+0x200=? d. (unsigned long)p+0x200=? 这两个是考察指针类型与偏移值的关系。p是info_t因此p + 1即p向后偏移sizeof(info_t)即，偏移28个字节，所以p + 0x200 = (char *)p + 0x200 * 28;同理(unsigned long)p + 0x200 = (char *)p + 0x200 * sizeof(usigned long); 我的回复有一个问题：d. (unsigned long)p+0x200=?这个我看成(unsigned long *)p + 0x200;所以，不是(char *)p + 0x200 * sizeof(long);  而是相当于0x10000000 + 0x200;因为p为0x10000000;

user: user-0
content: 引用 2 楼 user-4 的回复:[quote=引用 1 楼 user-4 的回复:] a. 28 b. 4 c . 0x10003800 d   0x10000800 e  0x10000200 a. 首先对成员变量进行对齐运算，然后看结构体自己是否对齐到4字节：  typedef struct{ long num;       // 4 bytes char *name;    // 4 bytes; short int data;    //2 bytes char ha;             // 1 bytes //因为short需要从2的倍数开始，所以这里空余 1byte short ba[5];       //10 bytes //因为int需要从4的整数倍开始，所以这里空余 2bytes int crc;               // 4bytes }info_t; info_t *p;  合计: 28bytes.  b. 因为是32位机器，所有指针都是4个字节  c.  p+0x2000， 移动地地址由p指针指向的类型决定。28字节为0x1c, 结果是0x200乘以0x1c, 再加上其实地址 d.  unsigned long长度为4字节，结果为4*0x200 , 再加上起始地址 e. char*指向长度为1字节，所以结果是起始地址加上0x200[/quote]   疑问？？ 如果问题e由（char*）p+0x200改为（char）p+0x200  ，我的理解是这样的，char长度为1字节，结果为1*0x200，再加上起始地址，所以是0x10000200，加*和不加*结果一样？

user: user-3
content: struct结构内存对齐

user: user-4
content: 引用 4 楼 半根烟浪江湖 的回复:[quote=引用 2 楼 user-4 的回复:] [quote=引用 1 楼 user-4 的回复:] a. 28 b. 4 c . 0x10003800 d   0x10000800 e  0x10000200 a. 首先对成员变量进行对齐运算，然后看结构体自己是否对齐到4字节：  typedef struct{ long num;       // 4 bytes char *name;    // 4 bytes; short int data;    //2 bytes char ha;             // 1 bytes //因为short需要从2的倍数开始，所以这里空余 1byte short ba[5];       //10 bytes //因为int需要从4的整数倍开始，所以这里空余 2bytes int crc;               // 4bytes }info_t; info_t *p;  合计: 28bytes.  b. 因为是32位机器，所有指针都是4个字节  c.  p+0x2000， 移动地地址由p指针指向的类型决定。28字节为0x1c, 结果是0x200乘以0x1c, 再加上其实地址 d.  unsigned long长度为4字节，结果为4*0x200 , 再加上起始地址 e. char*指向长度为1字节，所以结果是起始地址加上0x200[/quote]   疑问？？ 如果问题e由（char*）p+0x200改为（char）p+0x200  ，我的理解是这样的，char长度为1字节，结果为1*0x200，再加上起始地址，所以是0x10000200，加*和不加*结果一样？[/quote] 抱歉看错了。d是“(unsigned long)p+0x200”的话，结果是0x10000200.相当于无符号整数相加。  e如果修改为(char)p+0x200, 也相当于两个整数相加，结果也是0x10000200. (char*)p + 0x200, 是地址增加，结果也是0x10000200. 结果没变。

user: user-2
content: 第一个sizeof是考察结构体对齐的知识点，在32位系统里是按照4字节对齐的，不足4字节的编译器会补齐4字节。因此：short int data; char ha;  data加上ha的长度是3个字节，因此会补一个字节。short ba[5];长度是10字节，因此后面也会补2个字节。所以长度是28；  c. p+0x200=? d. (unsigned long)p+0x200=? 这两个是考察指针类型与偏移值的关系。p是info_t因此p + 1即p向后偏移sizeof(info_t)即，偏移28个字节，所以p + 0x200 = (char *)p + 0x200 * 28;同理(unsigned long)p + 0x200 = (char *)p + 0x200 * sizeof(usigned long);

user: user-4
content: 引用 1 楼 user-4 的回复:a. 28 b. 4 c . 0x10003800 d   0x10000800 e  0x10000200 a. 首先对成员变量进行对齐运算，然后看结构体自己是否对齐到4字节：  typedef struct{ long num;       // 4 bytes char *name;    // 4 bytes; short int data;    //2 bytes char ha;             // 1 bytes //因为short需要从2的倍数开始，所以这里空余 1byte short ba[5];       //10 bytes //因为int需要从4的整数倍开始，所以这里空余 2bytes int crc;               // 4bytes }info_t; info_t *p;  合计: 28bytes.  b. 因为是32位机器，所有指针都是4个字节  c.  p+0x2000， 移动地地址由p指针指向的类型决定。28字节为0x1c, 结果是0x200乘以0x1c, 再加上其实地址 d.  unsigned long长度为4字节，结果为4*0x200 , 再加上起始地址 e. char*指向长度为1字节，所以结果是起始地址加上0x200

user: user-4
content: a. 28 b. 4 c . 0x10003800 d   0x10000800 e  0x10000200