本人小白一枚 ,第一次写Blog,如有不对,请大家多指教!
好吧,那就开始吧。
今天看到一篇关于结构体和共用体的文章,学到了很多东西,在这里先谢过前辈(文章链接:https://blog.csdn.net/xboxmicro/article/details/19946705?locationNum=2&fps=1)。原文很详细,有兴趣的朋友可以去看看,鄙人写这篇文章主要是对其的笔记作用。
tips_one:
1. #i nclude <iostream.h>
2. #pragma pack(8)
4. {
3. struct example14. {
5. short a;
6. long b;
7. };
8. struct example2
9. {
10. char c;
11. example1 struct1;
12. short e;
13. };
14. #pragma pack()
15. int main(int argc, char* argv[])
16. {
17. example2 struct2;
18. cout << sizeof(example1) << endl;
19. cout << sizeof(example2) << endl;
20. cout << (unsigned int)(&struct2.struct1) - (unsigned int)(&struct2)
<< endl;
21. return 0;
22. }
问程序的输入结果是什么?
对于我这个小白来说,不懂
#pragma pack()的作用,就只
能蒙了,结果一看,居然蒙对了!
简单介绍一下怎么蒙这题的吧:
首先第一个输出其实就是问 struct example1 结构的 大小,那就是看怎么对齐的啦,我印象里知道结构体要按最大的size对齐,回头一看
struct example1
{
short a;
long b;
};
short 2字节,long 4字节,如果忽略
#pragma pack()的作用 那就是8字节了,于是就蒙了个8,
同理呢,example2 中 char 1字节, 所以还是按4字节对齐 ,那就是16啦,
最后一个输出呢其实是问再struct example2中 char a 占了几个字节,既然都是按4字节对齐的 ,就算是char ,那也是要占4字节啦,就是4吧,
蒙完了一对比答案,哈哈 全对了 , 那#pragam pack()呢? 摆设?带着这个问题,我继续往下看,原来啊,这个#pragam pack(8)就是用来指定对齐字节的(我说呢,怎么会是摆设呢),参数8就是对齐字节啦 ,但是呢,最大的是4个字节的long,你这一来就8字节,是不是浪费了,再一看,原来啊,要是这个参数大于最大字节的话 ,就不起作用了(看来还是摆设),所以按我的做题思路,就蒙对了。
tips_two:
接着 文中介绍了C++中的struct 和 class的区别 :
例如,定义struct类和class类:
struct structA
{
char a;
…
}
class classB
{
char a;
…
}
则:
structA a;
a.a = 'a'; //访问public成员,合法
classB b;
b.a = 'a'; //访问private成员,不合法
还有就是struct可以在定义的时候直接以{ }对其成员变量赋初值,而class则不能,
例:
struct structA
{
char a;
char b;
int c;
};
structA a = {'a' , 'a' ,1}; // 定义时直接赋初值
tips_three:
第3点就是提醒了大家一些struct编程是要注意的事项,比如说
看看下面的程序:
1. #i nclude <iostream.h>
2. struct structA
3. {
4. int iMember;
5. char *cMember;
6. };
7.int main(int argc, char* argv[])
8. {
9. structA instant1,instant2;
10. char c = 'a';
11. instant1.iMember = 1;
12. instant1.cMember = &c;
13. instant2 = instant1;
14 .cout << *(instant1.cMember) << endl;
15. *(instant2.cMember) = 'b';
16. cout << *(instant1.cMember) << endl;
17. return 0;
}
14行的输出结果是:a
16行的输出结果是:b
是不是很奇怪?为什么明明是改变instant2 ,而instant1却改变了!原来啊,关键是在13行,逐个拷贝成员变量时,instant2.cMember和instant1.cMember就变成了同一指针,也就是原文中说的访问同于区域,这就导致了,改变instant2 ,而instant1却改变了,收益匪浅啊!
tips_four:
最后一点,介绍了union (联合体),
union 和 struct 的相同之处
联合也是一种新的数据类型, 它是一种特殊形式的变量。
联合说明和联合变量定义与结构十分相似。其形式为:
union 联合名{
数据类型 成员名;
数据类型 成员名;
...
} 联合变量名;
联合表示几个变量公用一个内存位置, 在不同的时间保存不同的数据类型和不同长度的变量。
下例表示说明一个联合a_bc:
union a_bc{
int i;
char mm;
};
再用已说明的联合可定义联合变量。
例如用上面说明的联合定义一个名为lgc的联合变量, 可写成:
union a_bc lgc;
在联合变量lgc中, 整型量i和字符mm公用同一内存位置。
当一个联合被说明时, 编译程序自动地产生一个变量, 其长度为联合中最大的变量长度。
联合访问其成员的方法与结构相同。同样联合变量也可以定义成数组或指针,但定义为指针时, 也要用"->;"符号, 此时联合访问成员可表示成:
联合名->;成员名
另外, 联合既可以出现在结构内, 它的成员也可以是结构。
例如:
struct{
int age;也就
char *addr;
union{
int i;
char *ch;
}x;
}y[10];
若要访问结构变量y[1]中联合x的成员i, 可以写成:
y[1].x.i;
若要访问结构变量y[2]中联合x的字符串指针ch的第一个字符可写成:
*y[2].x.ch;
若写成"y[2].x.*ch;"是错误的。
union 和 struct 的不同之处,
结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合转只存放了一个被选中的成员, 而结构的所有成员都存在,正是因为这样,所以对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。
比如下面这个例子:
main()
{
union{
int i;
struct{
char first;
char second;
}half;
}number;
number.i=0x4241;
printf("%c%c\n", number.half.first, number.half.second);
number.half.first='a';
number.half.second='b';
printf("%x\n", number.i);
getch();
}
输出结果为:
AB
6261
当union访问的是字节half.first和half.second时,其实就是访问 int i 的高低字节,也就是0x42,0x41,所以输出的是其ASCLL码 A B
同理当union访问的是int i 的时候 就会把half.first和half.second当做是 i 的高低字节,也就是0x61 0x61,所以输出的i 就是0x6261
到此,本文也就告一段落了 希望大神们给予宝贵的指教,再次谢谢原文博主!