对于C语言中结构体强制转换作了以下实验, 或许能够解惑一些问题ios
对于结构体, 我理解的属性有: 成员的顺序, 成员的类型,成员的个数,成员名称,这些属性在对结构操做的时候会有一些影响, 好比结构体的对齐, 结构体的强制转换.测试
处于对上述描述的理解,作出以下测试工做,spa
以结构强制转换实现为目的, 实现顺序,类型,个数在不一样的组合下,转换的结果,code
一 : 成员顺序&& 成员类型内存
#include <iostream> using namespace std; typedef struct _foo{ short a; int b; }foo; typedef struct _bar { int a; short b; }bar; int main() { foo f={1,2}; bar *pbar = (bar*)&f; printf("%d\r\n",pbar->a); printf("%d\r\n",pbar->b); return 0; } /* output: -859045887 2 */
#include <iostream> using namespace std; typedef struct _foo{ char* a; int b; }foo; typedef struct _bar { short a; long long b; }bar; int main() { foo f={"zhang",2}; bar* pbar = (bar*)&f; printf("%d\r\n",pbar->a); printf("%d\r\n",pbar->b); return 0; } /* output: -13200 -858993460 */
经过测试,在成员的顺序不一样的时候, 若是进行强制的转换,结果是不可预知的,危险.io
在成员类型彻底不一致的状况下, 结果是不能够预计的.class
// 成员名称stream
#include <iostream> using namespace std; typedef struct _foo{ short a; int b; }foo; typedef struct _bar { short b; int a; }bar; int main() { foo f={1,2}; bar* pbar = (bar*)&f; printf("%d\r\n",pbar->b); printf("%d\r\n",pbar->a); return 0; } /* output: 1 2 */
测试结论: 结构体强制转换时,与成员的名称没有关系,在顺序保持一致的状况下.gc
// 成员长度数据
#include <iostream> using namespace std; typedef struct _foo { int a; char *s; }foo; typedef struct _bar { int a; char* s; int b; }bar; int main() { foo f={1,"zhangchao"}; bar* pbar = (bar*)&f; printf("%d\r\n",pbar->a); while(*(pbar->s) != '\0') { printf("%c",*(pbar->s)); (pbar->s)++; } printf("\r\n"); printf("%d\r\n",pbar->b); return 0; } /* output: 1 zhangchao -858993460 */
在属性保持一致的状况下, 多的成员类型的值不可预计.
// 成员裁剪,
#include <iostream> using namespace std; typedef struct _foo { int a; char *s; }foo; typedef struct _bar { int a; char* s; int b; }bar; int main() { bar f={1,"zhangchao",2}; foo* pbar = (foo*)&f; printf("%d\r\n",pbar->a); while(*(pbar->s) != '\0') { printf("%c",*(pbar->s)); (pbar->s)++; } printf("\r\n"); // 以下的访问操做是错误的, 该语句仅仅是为了测试. //printf("%d\r\n",pbar->b); return 0; }
在多成员结构体转换为少成员结构体时,注意不要访问不存在的成员;
经过如上的测试, 若是要进行结构体的强制转换, 须要考虑如上的因素.
若是测试遗漏的,请指正,谢谢.
更新:
1 上述的测试代码只看到了表面 的现象, 结论是: 不一样的的结构体间互相的转换, 最终的结果是截断或是补充。
2 转换的实质是 : 按照数据在内存中的位置,逐个给左值中的成员赋值。 特别注意,结构体的对齐问题。
因此会出现读取到的数据是异常的