tutorial上的一道题,再回顾遇到了不理解,希望得到指点。
原题是英文的有点长,大意就是不用.和->来访问结构体中的成员,提示了用offsetof。
上面是结构体定义。
在main中有个struct hazard hazard1,将其各个结构体中的成员初始化后,不使用.和->替换这条代码:
hazard1.severityClass = 'B';
答案给的是*(char *)((void *)&hazard1 + offsetof(struct hazard, severityClass)) = 'B';
我不明白为什么是(void *)而不是(struct hazard *)
首先这是从内存的角度来分析,struct hazard* 的变量代表一个结构体,如果对结构体的指针进行指针偏移的操作,必定
得到的指针不是原来结构体指针的范围。比方说,struct hazard* stHa, 对stHa指针而言,stHa既是整个定义结构体的起始
初地址,和&stHa是等价的。但是当进行指针偏移的操作的时候,比如stHa+1,表示的地址比不是这个stHa的地址了,已经
偏移了sizeof(stHa)这个多的内存,所以最终的操作必定乱码!
其次,结构体如果没有任何的其他修饰,在C语言中会采取字节对其的方式,而字节对齐的基本单位是char,因此当转为void或者直接使用char问题不大,这样进行的偏移操作是在结构体的水平范围内,不会超出sizeof(struct hazard)的偏移大小。
另外,C语言为了能够更好地进行移植性,使用void来代替其他类型的指针,比方说char int*等等,方便强制转换
THX