关于结构体的学习笔记

本人小白一枚 ,第一次写Blog,如有不对,请大家多指教!

好吧,那就开始吧。

    今天看到一篇关于结构体和共用体的文章,学到了很多东西,在这里先谢过前辈(文章链接:https://blog.csdn.net/xboxmicro/article/details/19946705?locationNum=2&fps=1)。原文很详细,有兴趣的朋友可以去看看,鄙人写这篇文章主要是对其的笔记作用。

 tips_one:
    文章中首先通过struct 和  union的结合使用 介绍了一下结构体的作用,这里就不再重复描述,随后给了一道Intel、微软等公司曾经出过一道类似的面试题:

1. #i nclude

2. #pragma pack(8)

4. {

3. struct example1

4. {

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

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

  到此,本文也就告一段落了  希望大神们给予宝贵的指教,再次谢谢原文博主!


你可能感兴趣的:(c/c++,笔记)