zoukankan      html  css  js  c++  java
  • (C/C++学习笔记) 十五. 构造数据类型

    十五. 构造数据类型

    ● 构造数据类型概念

    Structured data types 构造数据类型

    结构体(structure), 联合体/共用体 (union), 枚举类型(enumeration type), 要有意识这三者是数据类型

     

    Union is also like structure, i.e. collection of different data types which are grouped together. Each element in a structure or a union is called member.

        Structure allocates storage space for all its members separately.

        Whereas, Union allocates one common storage space for all its members

     

    ● 结构体使用场景

    无论是基本数据类型还是数组都仅仅描述了事物某一方面的特性, 但是, 一种事物往往具有多方面的属性, 如一个同学有学号, 姓名, 性别, 年龄等属性.

    定义形式:

    struct union_type_name

    {

        member_type        member_name_1;

        member_type        member_name_2;

        ...

        member_type        member_name_n;

    };

     

    结构体变量的定义 & 结构体成员的初始化, 例如:

    struct person_info

    {

        int index;

        char name[30];

        short age;

    };

    person_info Eric, Peter;

    struct person_info

    {

        int index;

        char name[30];

        short age;

    } Eric, Peter;

     

     

    ● 结构体成员初始化的两种方法

    //结构体变量名.成员名

    #include <iostream>

    using namespace std;

     

    void main()

    {

        struct person_info

        {

            int index;

            char name[30];

            short age;

        };

        person_info p_info;        //也可以写成struct person_info p_info;

        p_info.index=1;

        strcpy(p_info.name,"Jim");    //位字符数组赋值需要使用字符串复制函数strcpy(), 否则会提示: cannot convert from 'char [4]' to 'char [30]'

        p_info.age=20;

     

        cout << p_info.index<< endl;

        cout << p_info.name << endl;

        cout << p_info.age << endl;

     

        cout<<sizeof(person_info)<<endl;

        cout<<sizeof(p_info)<<endl;        //结构体类型和结构体变量的大小都是36字节, 4+30+2=36

    }

     

    /*

    可以在声明一个结构体变量后赋值:

    struct person_info

    {

        int index;

        char name[30];

        short age;

    };

    person_info p_info={1,"Jim", 20};

    */

    /* 也可以在定义结构体变量时直接对成员赋值:

    struct person_info

    {

        int index;

        char name[30];

        short age;

    } p_info={1,"Jim", 20};*/

    //结构体指针变量->成员名

    //在定义结构体的同时, 声明结构体指针变量

    #include <iostream>

    using namespace std;

     

    void main()

    {

        struct person_struct

        {

            int index;

            char name[30];

            short age;

        }*p, p_info={1,"Jim",20};

        p=&p_info;

        cout <<p->index << endl;

        cout <<p->name << endl;

        cout << p->age << endl;

        cout <<(*p).index << endl;

        cout <<(*p).name << endl;

        cout <<(*p).age << endl;

     

        cout << sizeof(p) << endl;

        cout << sizeof(p_info) << endl;

    }

     

    //也可以写成:

    struct person_info

    {

        int index;

        char name[30];

        short age;

    };

    person_info p_info={1,"Jim",20};

    struct person_info *p=&p_info; //一定要写定义的结构体类型名, 不能写成struct *p=&p_info;

    总之, 在上述案例中, 访问结构体成员有下面三种方法:

    ① p_info.index; p->index; (*p).index;

    ② 当一个结构体类型定义完成后, 如果要使用这个类型, 保留字structC语言中必须使用,而在C++中则可被省略不写。

     

    ● 结构体的嵌套, 子结构体(sub-structure)

    #include <iostream>

    using namespace std;

     

    void main()

    {

        struct person_info

        {

            int index;

            char name[30];

            short age;

            struct work_place

            {

                char address[150];

                char postCode[30];

                char gateCode[50];

                char street[100];

                char area[50];

            }WP; //子结构体(sub-structure)

    };

     

        person_info p_info;    //p_infoperson_info结构体类型变量

        strcpy(p_info.WP.address,"House");    //可以把WP看作是p_info变量的子变量(sub-variable)

        strcpy(p_info.WP.postCode,"10000");

        strcpy(p_info.WP.gateCode,"302");

        strcpy(p_info.WP.street,"Lan Tian");

        strcpy(p_info.WP.area,"China");

     

        cout << p_info.WP.address << endl;

        cout << p_info.WP.postCode << endl;

        cout << p_info.WP.gateCode<< endl;

        cout << p_info.WP.street << endl;

        cout << p_info.WP.area << endl;

    }

     

    ● 结构体变量作函数参数

    #include <iostream>

    using namespace std;

     

    struct person_info //定义结构体

    {

        int index;

        char name[30];

        short age;

    };

    void show_stuct_message(struct person_info my_info) //自定义函数,形参是结构体变量my_info, 输出结构体变量成员, 不返回值

    {

        cout << my_info.index << endl;

        cout << my_info.name << endl;

        cout << my_info.age<< endl;

     

    }

    void main()

    {

        

        person_info p_info; //声明结构体变量p_info, 作为形参

        p_info.index=1;

        strcpy(p_info.name,"Jim");

        p_info.age=20;

        show_stuct_message(p_info); //调用自定义函数

    }

     

    ● 结构体指针做函数参数

    #include <iostream>

    using namespace std;

    struct person_info

    {

        int index;

        char name[30];

        short age;

    };

    void show_struct_message(struct person_info *my_info)

    {

        cout << my_info->index << endl;

        cout << my_info->name << endl;

        cout << my_info->age<< endl;

     

    }

    void main()

    {

        

        person_info p_info;

        p_info.index=1;

        strcpy(p_info.name,"Jim");

        p_info.age=20;

        show_struct_message(&p_info);

    }

     

    ● 结构体数组的声明与引用 & 指针访问结构体数组

    结构体数组: 每个元素都是结构体变量的数组

    //定义结构体数组的一般形式:

    struct 结构体名

    {

        成员列表;

    }数组名;

    struct Student    //可以把Student这个结构体名省略

    {

        char name[20];

        int number;

        char sex;

        int grade;

    }student[5];

    //结构体数组中各数据在内存中的存储是连续的,例如:

    #include <iostream>

    using namespace std;

     

    void main()

    {

        struct person_info

        {

            int index;

            char name[30];

            short age;

        }p_info[5]={{1,"Jim",20},    //p_ifno是一个结构体数组

                    {2,"Eric",21},

                    {3,"Peter",22},

                    {4,"Amy",22},

                    {5,"Lucy",22}};

     

        struct person_info *p;

        p=p_info;    //p_info是一个结构体数组名, 因此就代表一个地址值

        for(int i=0;i<5;i++,p++)

        {

            cout << p->index << endl;

            cout << p->name << endl;

            cout << p->age << endl;

        }

    }

     

    ● 共用体变量的大小

    所有共用体在同一时刻只能有一个值, 它属于某一数据成员, 不过其它成员会共享这个值, 只是会转换成这些成员的数据类型

    共用体变量的大小是其最大成员的大小.

    联合体使用场景:

    例如通信中的数据包会用到共用体, 因为不知道对方会发一个什么数据类型的包过来,用共用体的话就很简单了,定义几种格式的包,收到包之后就可以直接根据包的数据类型取出数据。

    定义形式:

    union union_type_name

    {

        member_type        member_name_1;

        member_type        member_name_2;

        ...

        member_type        member_name_n;

    };

     

     

    联合体变量的定义, 例如:

    //第一种形式:

    union my_union

    {

        int i;

        char ch;

        float f;

    };

    my_union u;

    //第二种形式:

    union my_union

    {

        int i;

        char ch;

        float f;

    } u;

    #include<stdio.h>

     

    union data_union            /*声明共用体类型*/

    {

        int a;            /*成员变量*/

        char b;            

    };

     

    int main()

    {

        union data_union my_union;        /*定义共用体变量*/

        my_union.a=97;                /*为共用体变量中成员赋值*/

        printf("a: %d ",my_union.a);        /*输出成员变量数据*/

        printf("b: %c ",my_union.b);

        my_union.b='A';            /*改变成员的数据*/

        printf("a: %d ",my_union.a);        /*输出成员变量数据*/

        printf("b: %c ",my_union.b);

        printf("sizeof(data_union): %d ",sizeof(data_union));

        printf("sizeof(my_union): %d ",sizeof(my_union));

        return 0;

    }

     

    ● 枚举类型(enumeration type)

    使用场景: 很多集合描述的状态为有限几个, 例如比赛结果只有输, 赢和平手三种状态; 一周只有七天等等.

    枚举类型是一些标识符的集合, 这些标识符代表整型常量. 声明形式:

    标识符没有被赋值

    enum 枚举类型名 {枚举常量1, 枚举常量2,…, 枚举常量n}

    enum enumeration_type_name { enumeration_constant_1, enumeration_constant_2, ..., enumeration_constant_n}

    例如:

    enum weekday {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};

    如果标识符没有被赋值, 标识符会被自动赋值为从0开始的整型常量

    标识符被赋值

    enum enumeration_type_name    //方括号(中括号)内的内容可以写或不写

    {

        identifier[=integral constant],

        identifier[=integral constant],

        ...

        identifier[=integral constant],

    };

    上面的枚举类型声明相当于:

    enum Weekday {Sunday=0, Monday=1, Tuesday=2, Wednesday=3, Thursday=4, Friday=5, Saturday=6};

    也可以自己赋值, :

    enum Weekday {Sunday=2, Monday=3, Tuesday=4, Wednesday=5, Thursday=0, Friday=1, Saturday=6};

    如果只给前几个标识符赋值, 编译器会给后面的标识符自动累加赋值, 例如:

    enum Weekday {Sunday=7, Monday=1, Tuesday, Wednesday, Thursday, Friday, Saturday};

    相当于:

    enum Weekday {Sunday=7, Monday=1, Tuesday=2, Wednesday=3, Thursday=4, Friday=5, Saturday=6};

     

    枚举类型变量(enumeration variable/enum variable)

    enum Weekday {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};

    Weekday myworkday;

    也可以去掉上面花括号后面的分号, 然后直接写变量的标识符:

    enum Weekday {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday} myworkday;

     

    注意:① C语言中, 还需要写关键字, : enum weekday myworkday;

    枚举变量的值只能在SundaySaturday之间, 即一个整型数据不能直接赋给一个枚举变量, 不过可以先将一个整型常量强转为Weekday枚举类, 然后再赋值.

     

    ● 枚举类型的声明, 枚举类型变量的声明及其运算

    #include <iostream>

    using namespace std;

     

    void main()

    {

        enum Weekday {Sunday,Monday,Tuesday,Wednesday,Thresday,Friday,Saturday};

        int a=2,b=1;

        Weekday day;

     

        day=Tuesday;

        cout<<day<<endl;

     

        day=(Weekday)a; //将整型的a强转为Weekday类型

            cout << day << endl;

     

        day=(Weekday)(Sunday+Wednesday); //Sunday+Wednesday后得到一个整型常量, 因此也需要强转

            cout << day << endl;

     

        day=(Weekday)5; //等价于day=(enum Weekday)5; 输出Weekday的第5个标识符代表的整型常量(0开始计数)

        cout << day << endl;

     

        Weekday another_day;

        another_day=Tuesday;

        cout<<day-another_day<<endl;

     

        cout<<sizeof(Weekday)<<endl;

        cout<<sizeof(another_day)<<endl;

        //enum类型的长度以及每个enum类型变量的长度都是一个枚举常量的长度, sizeof(int)=4;

    }

     

  • 相关阅读:
    MIT自然语言处理第三讲:概率语言模型(第四部分)
    MIT自然语言处理第二讲:单词计数(第三部分)
    MIT自然语言处理第五讲:最大熵和对数线性模型(第二部分)
    MIT自然语言处理第二讲:单词计数(第四部分)
    MIT自然语言处理第三讲:概率语言模型(第一部分)
    MIT自然语言处理第二讲:单词计数(第二部分)
    MIT自然语言处理第五讲:最大熵和对数线性模型(第一部分)
    MIT自然语言处理第四讲:标注(第二部分)
    MIT自然语言处理第二讲:单词计数(第一部分)
    MIT自然语言处理第一讲:简介和概述(第二部分)
  • 原文地址:https://www.cnblogs.com/ArrozZhu/p/8377959.html
Copyright © 2011-2022 走看看