精华内容
下载资源
问答
  • C语言结构体变量的初始化方法

    千次阅读 2019-07-07 17:08:03
    结构体变量的初始化方法 1.定义结构体变量并同时对其初始化 这里介绍三种方法: 顺序法 乱序法 C++风格的乱序 struct student { int score; const char *name; } 1.1 顺序法 按照结构体成员的声明顺序进行初始...

    结构体变量的初始化方法

    1.定义结构体变量并同时对其初始化

    这里介绍三种方法:

    1. 顺序法
    2. 乱序法
    3. C++风格的乱序
    struct student
    {
    	int score;
    	const char *name;
    }
    

    1.1 顺序法

    按照结构体成员的声明顺序进行初始化。

    struct student stu1={98,"li ming"};
    

    1.2 乱序法

    特点:成员顺序可以不定,Linux 内核多采用此方式。推荐使用这种初始化方法!

    struct student stu1=
    {
    	.name="li ming",
    	.score=89,
    };
    

    1.3 C++风格的乱序

    struct student stu1=
    {
    	name:"li ming",
    	score:89,
    };
    

    2.先定义结构体变量,再对其初始化

    struct student stu1;
    stu1.score=90;
    stu1.name="li ming";
    
    展开全文
  • C语言 结构体与共用体

    千次阅读 多人点赞 2016-12-05 19:07:04
    1 结构体1.1 什么是结构体?...1.2 结构体的定义方式与结构体变量的声明1) 定义形式定义结构体类型的同时定义结构体变量,形式如下struct 结构体名 { 类型标识符 成员名; 类型标识符 成员名; …

    1 结构体

    1.1 什么是结构体?

    结构体是C语言中的一种数据类型,它有如下特点

    1)  结构体是一种构造数据类型
    2)  把不同类型的数据组合成一个整体来自定义数据类型
    

    1.2 结构体的定义方式与结构体变量的声明

    1) 定义形式

    定义结构体类型的同时定义结构体变量,形式如下

    struct   结构体名
    {
          类型标识符    成员名;
          类型标识符    成员名;
             …………….
    }变量名表列;
    

    2) 几种定义方式

    结构体一般分为有名结构体、匿名结构体。有如下几种定义方式
    a) 方式1

    struct Student
    {
        int num;
        char name[30];
    }s1;
    或
    struct Worker
    {
        char name[20];
        int salary;
    };
    
    

    b) 方式2 匿名结构体

    struct {
        int id;
        char level[20];
    }vip;
    

    c) 方式3,使用define

    #define ds struct DefineStruct
    ds 
    {
        int i;
    };
    

    d) 方式4 使用typedef

    typedef struct date
    {
        int year;
        int month;
        int day;
    } Date;
    
    // Date date = {2016,12,4}; 
    

    注意:此时的Date是类型名而不是变量名

    错误示例

    typedef struct 
    {
        Date* date;   // 直到末尾Date才定义,此处引用时还未定义
        int year;
        int month;
        int day;
    } Date;
    

    改造如下:

    typedef struct _date
    {
        struct _date* d;
        int year;
        int month;
        int day;
    } Date;

    3) 结构体类型与结构体变量

    1. 结构体类型与结构体变量概念不同

      1)  类型:不分配内存;变量:分配内存
      2)  类型:不能赋值、存取、运算等操作,变量可以
      
    2. 结构体可嵌套,但防止递归嵌套
    3. 结构体成员名可与程序中变量名相同,不会造成混淆

    1.3 结构体变量的初始化

    有如下几种初始化形式:

    a) 形式一

    struct     结构体名
    {
          类型标识符    成员名;
          类型标识符    成员名;
             …………….
    };
    struct  结构体名  结构体变量={初始数据};
    
    例    struct  person
            {       int num;
                     char  name[20];
                     char sex;
                     int age;
                     char addr[30];
            }; 
    struct  person per={1,"XX",'M',19, "YY"};
    

    b) 形式二

    struct     结构体名
    {
          类型标识符    成员名;
          类型标识符    成员名;
             …………….
    }结构体变量={初始数据};
    
    例    struct  person
            {       int num;
                     char  name[20];
                     char sex;
                     int age;
                     char addr[30];
            }per={1,"XX",'F',18,"YY"};

    c) 形式三

    struct
    {
          类型标识符    成员名;
          类型标识符    成员名;
             …………….
    }结构体变量={初始数据};
    
    例    struct
            {       int num;
                     char  name[20];
                     char sex;
                     int age;
                     char addr[30];
            }per={2,"AA",'M',18,"YY"};
    

    1.4 结构体变量的引用

    3种引用成员形式

    1)  结构体变量名.成员名
    2)  结构体指针名->成员名;
    3) (*结构体指针名).成员名;
    

    等价关系描述如下:
    这里写图片描述

    1.4.1 引用规则

    a) 结构体变量不能整体引用,只能引用变量成员。引用方式如上的第一种,即 结构体变量名.成员名
    例 :

    struct   person
    {  
      int num;
      char  name[20];
      char sex;
      int age;
      char addr[30];
    }p1,p2; 
    
    p1={1,"XX",'F',19,"YY"};  ( 错)
    printf(“%d,%s,%c,%d,%f,%s\n”,p2);      ( 错)
    
    if(p1==p2) (错,表达式必须包含算术或指针类型 )
    ……
    
    p1.num=10;   // 赋值
    p2.age++;

    b) 结构体变量间相互赋值
    C语言不允许使用一个数组直接为另一个数组赋值,但使用一个结构体变量为另一个结构体变量赋值是合法的,可以使用赋值操作符(=)将一个结构变量赋值给另一个结构变量,如下是正确的:

    p2 = p1;     (  √    )

    c) 结构体嵌套时逐级引用

    例 struct  person
      {    
           int  age;
           char name[20];
           struct  
          {    int month;
                int day;
                int year;
          }date ;
      }p1,p2;
    
    
    p1.date.month=12;

    d) 结构体的自引用

    // 错误使用
    struct MyStruct
    {
        int a;
        struct MyStruct my;  // 形成了递归引用
    };
    
    // 正确使用
    struct MyStruct
    {
        int a;
        struct MyStruct* my;  // 使用指向结构体的指针
    };
    

    1.5 结构体嵌套与匿名结构体

    结构体嵌套就是“结构体中有另一个结构体”,某个结构的数据成员也是一个结构体变量,这样可以按层次结构合理组织数据。如下示例:

    struct student
    {
    char name[20];
    struct course           /*结构体course的定义*/
        {
        int math;
        int English;
        }c;                 /*声明结构体变量c*/
    };
    

    匿名结构体

    C语言允许定义匿名结构,所谓匿名结构,就是不指定结构体的名称,但一定要在结构体定义的同时声明至少一个结构体变量,否则这种用法没有实际意义,因为外部无法使用它来声明变量。

    struct
    {
    char name[20];
    int age;
    }a, b ;
    
    //  这样便声明创建了两个结构体变量a和b,可以通过诸如 a.age 等形式来访问其成员,但这种类型没有名称,因此无法在以后的程序中声明这种类型的变量。

    1.6 结构体数组

    1.6.1定义方式

    结构体数组定义的三种形式:
    形式一:

    struct  person
          {    
                 char name[20];
                 char sex;
                 int age;
          };
    struct  person per[5];
    

    形式二:

    struct  person
          {    
    
               char name[20];
               char sex;
               int age;
          }per[3];
    

    形式三:

      struct   // 匿名
          {     
    
             char name[20];
             char sex;
             int age;
          } per[2];
    

    1.6.2 创建结构体数组

    struct  person s[3] = { { 100,"XX",'M',18},{ 100,"YY",'F',19 },{ 100,"ZZ",'M',20} };
    
    struct person* p = (struct  person *)malloc(sizeof(struct  person )*3);  // 动态开辟
    
    for (int i = 0; i < 3; i++)
        {
            p[i].num = i;
            strcpy(p[i].name, "name");
            p[i].sex = i % 2 == 0 ? 'M' : 'F';
            p[i].age = i * 10;
        }
    

    1.6.3 结构体数组初始化与引用

    1) 结构体数组初始化
    分行初始化:

    struct  person
          {      
                 int  id;
                 char name[20];
                 char sex;
                 int age;
          };
    struct person per1[3]={{1,"XX",'M',20},{2,"YY",'F',19},{3,"ZZ",'M',19}}; 
    // 全部初始化时维数可省,如下
    struct person per2[]={{1,"XX",'M',20},{2,"ZZ",'M',19}}; 
    

    顺序初始化:

    struct  person
    {
        int  id;
        char name[20];
        char sex;
        int age;
    };
    struct  person  per[] = { 1,"XX",'M',20,10,"YY",'M',19 };
    

    定义时同时初始化

    struct  person
          {     int  id;
                 char name[20];
                 char sex;
                 int age;
          }per[ ]={{……},{……},{……}};
    
    例  struct 
          {     int  num;
                 char name[20];
                 char sex;
                 int age;
          }per[ ]={{……},{……},{……}};
    

    2) 引用方式

    结构体数组名[下标].成员名

    per[i].age += 1;
    strcpy(per[1].name, "hhd");  // 改变数组的内容
    
    for (int i = 0; i < 2; i++)
    {
    printf("%d,%s,%c,%d\n", per[i].id, per[i].name, per[i].sex, per[i].age);
    }

    1.7 结构体与指针

    1) 指向结构体变量的指针

    结构体指针存放结构体变量在内存的起始地址, 定义形式:struct 结构体名 *结构体指针名;

    例   struct  person *p;  
    

    2) 使用结构体指针变量引用成员形式

    struct    person  per;
    struct    person  *p=&per;  // p指向 per
    per.id =1;   // 或 (*p).id =1;
    

    使用示例

        struct student
        {
            long int num;
            char name[20];
            char sex;
            float score;
            struct student_info     // 结构体嵌套
            {
                int age;
                char adress[20];
            }info;
    
            struct student_info* _info;   // 结构体指针
        }stu1, *p;
    
        p = &stu1;  // p 指向 stu1
        struct student_info _info = {16,"aaaaa"};
        p->_info = &_info;
        stu1.num = 101;
        strcpy(stu1.name, "XX");
        p->sex = 'M';
        (*p).score = 89.5;
        p->info.age = 18;
        strcpy(p->info.adress,"yyyyyy" );
        printf("\nNo:%ld\nname:%s\nsex:%c\nscore:%f\nage=%d\nadress=%s\n",
            (*p).num, p->name, stu1.sex, p->score,p->info.age,p->info.adress);
        printf("\n_info.age=%d\n_info.adress=%s\n", p->_info->age, p->_info->adress);  // 访问结构体指针所指向的内容
    

    3) 指向结构体数组的指针

    struct person
        {
            int num;
            char name[20];
            char sex;
            int age;
        }stu[3] = { { 001,"AAA",'M',18 },
        { 002,"BBB",'M',19 },
        { 003,"CCC",'F',20 } };
    
    
        struct person *p = stu;  // 指向结构体数组首地址
        for (p = stu; p<stu + 3; p++)    // 指针每加一,移动一个结构体大小
        {   printf("No.=%d,name=%s,sex=%c,age=%d\n", p->num, p->name, p->sex, p->age);
    }
    

    1.8 结构体变量、指针作函数参数

    对比:

    1)  用结构体变量的成员作参数----值传递
    2)  用结构体变量作参数----多值传递,效率低  
    3)  用指向结构体变量或数组的指针作参数----地址传递
    4)  使用结构体数组作参数, 地址传递
    

    示例:

    // 结构体定义如下
    typedef struct date
    {
        int year;
        int month;
        int day;
    } Date;
    

    使用指向结构体变量或数组的指针作参数

    // 指向结构体变量的指针做参数
    void changeDate(Date* d)
    {
        d->day += 1;
        d->year -= 1;
        d->month -= 1;
    }
    

    使用结构体数组做参数

    // 使用结构体数组做参数
    void changeArr(Date date[])
    {
        for (int i = 0; i < 2; i++)
        {
            date[i].day -= 1;
            date[i].month -= 1;
            date[i].year -= 1;
        }
    }
    

    用结构体变量作参数

    // 值传递,无法改变内容,即使里面有数组元素
    void change_struct(Date date)
    {
        date.day += 1;
        date.month += 1;
        date.year += 1;
        strcpy(date.des, "nice");
        printf("change: year=%d,month=%d,day=%d,des=%s\n", date.year, date.month, date.day, date.des);
    }
    

    1.9结构体在内存中的存储与字节对齐

    结构体的大小本应该是所有成员的类型大小之和,但因为引入字节对齐的缘故,导致结构体真实的大小一般大于等于所有成员大小之和。成员在结构体中的位置对结构体的大小可能会造成影响。

    对于MyStruct1,内存分配如下:
    这里写图片描述

    1.9.1 结构体字节对齐机制

    出于效率的考虑,C语言引入了字节对齐机制,结构体变量占据的内存单元的个数应当大于等于其内部所有数据成员占据内存单元数的和。
    一般来说,不同的编译器字节对齐机制有所不同,但还是有以下3条通用准则:
    (1) 结构体的大小能够整除其最宽基本类型成员的大小;
    (2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
    (3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

    说明:
    字节对齐第(3)条准则提及最宽基本类型的概念,所谓基本类型是指像char、short、int、float、double这样的内置数据类型。“数据宽度”就是指其sizeof的大小。诸如结构体、共用体和数组等都不是基本数据类型。

    注意:如下示例都是在32位编译环境下测试的。

    示例:

    struct MyStruct1
    {
        char ch1;
        char ch2; //  两者不足4,填充
        int i1;   // 4
        int i2;  // 4
    };
    sizeof(struct MyStruct1)  // 12 
    
    struct MyStruct2
    {
        int i1;  // 4
        char ch1;
        char ch2; // 两者不足4,填充
        char chs[11];  // 12
    };
    
    sizeof(struct MyStruct2)  // 20
    struct MyStruct3
    {
        char ch1;  //4 
        int i;  // 4
        char chs[9]; // 12
    };
    sizeof(struct MyStruct3) // 20
    
    struct MyStruct4
    {
        char ch1;  // 8
        double db; // 8
        int i; // 4
        char chs[9]; // 12
    
    };
    sizeof(struct MyStruct4)  // 32
    
    struct MyStruct5
    {
        int i;  // 4
        short s;  // 4
        char chs[11]; // 12
    };
    sizeof(struct MyStruct5)  // 20
    

    1.9.2 结构体嵌套结构体

    当结构体嵌套结构体时,字节对齐所参考的最宽基本成员不局限与当前结构体,可能是所包含的结构体中的最宽基本成员。

    struct MyStruct7
    {
        int i;
        char ch;
    };
    
    struct MyStruct8
    {
        struct MyStruct7  s;   //此时参考的是MyStruct7中最宽的int
        char ch;
    
    };
    
    printf("%d\n", sizeof(struct MyStruct8));  //输出12
    

    1.9.3 offsetof(s,m)

    在stddef.h 头文件中,可以使用offsetof来看某个元素相对结构体的起始位置偏移了多少个字节

    typedef struct MyStruct6
    {
        char ch;
        int i;
        double d;
    };
    ...
    printf("%d,%d\n", sizeof(struct MyStruct6),offsetof(struct MyStruct6, i)); //输出 164
    

    1.9.4 手动设置成员对齐

    在vs2015中,依次点击 项目 –> 结构体 属性 –> C/C++ –> 代码生成,在如下界面的结构成员对齐选项进行设置:
    这里写图片描述

    例:

    struct MyStruct7
    {
        int i;
        char ch;
    };
    ... 
    printf("%d\n", sizeof(struct MyStruct7));
    
    // 当我们设置对齐字节为2字节时
    // 输出为6
    
    // 当我们设置对齐字节为8字节时
    // 输出为8
    

    注意: 当我么设置的字节数小于结构体最宽基本成员时,以设置的为主;当设置的字节数大于结构体最宽成员时,以结构体最宽基本成员的大小为主:总结即是两者按最小的来计算

    1.10 位域(bit field)

    位域一般用于限制结构体成员的大小从而起到节约内存的作用,由于涉及到类型的大小,相应的会影响软件的移植性。

    形式:

    struct 位域结构名
    { 
        位域列表 
    };
    
    其中位域列表的形式为: 类型说明符 位域名:位域长度;
    

    在C99中规定int、unsigned int和bool(C99新增关键字)可以作为位域类型,但不同编译器在实现时对此都作了相应扩展。使用Dev C++ IDE C99下测试,可以使用于位域的类型有char,short,int,long,bool,而浮点类型float、double则不在支持之列。

    注:C99下,使用bool需包含头文件stdbool.h( #include<stdbool.h> )  

    使用位域的主要目的是压缩存储,其大致规则为:

    1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
    2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
    3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
    4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
    5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
    

    使用的一般示例:

    struct MyStruct
    {
        unsigned char ch1:1;
        unsigned int i:4;
        unsigned long l : 8;
        unsigned short sh :2;
    //  double d:8;  // 位域的类型无效
    //  float f : 4;  // 位域的类型无效
    };
    

    使用位域案例

    通过位域来操作int类型数据,打印出其在内存中的二进制表示形式:

    
    struct bits
    {
        unsigned char ch1 : 1;
        unsigned char ch2 : 1;
        unsigned char ch3 : 1;
        unsigned char ch4 : 1;
        unsigned char ch5 : 1;
        unsigned char ch6 : 1;
        unsigned char ch7 : 1;
        unsigned char ch8 : 1;
    };
    
    void main()
    {
        int i = 4;
        struct bits* p = &i;
        int len = 4;
        while (len--)      
        {
            printf("%d%d%d%d%d%d%d%d ", (p+len)->ch8, (p + len)->ch7, (p + len)->ch6, (p + len)->ch5, (p + len)->ch4, (p + len)->ch3, (p + len)->ch2, (p + len)->ch1);// p每加1移动一个字节
        }
    
        system("pause");
    }
    

    打印结果:

    00000000 00000000 00000000 00000100

    2 共用体

    2.1共用体定义

    共用体也叫联合体,与结构体类似,也是一种构造数据类型,但却有着不同的行为方式。一般至少由一种数据类型构成,所有成员引用的是内存中相同的位置。

    2.2用途

    在不同的时刻把不同的东西存储与相同的内存位置(使几个不同类型的变量共占一段内存(相互覆盖))

    2.3 共用体变量的定义

    共用体可采用如下形式定义:

    union 共用体名称(或称标识)
    {
        存储数据列表(或称成员变量列表)
    };
    注意,结束花括号后的分号(};)不要遗漏,这种定义形式是一个完整的
    

    形式一:

    union data         
    {    
        int i;            
        char ch;            
         float f;
    }a,b;

    形式二:

    union data         
    {    
        int i;         
         char ch;            
     };      
    
      union data a,b,c,*p,d[3];
    

    形式三: 匿名

    union        
     {   
      int i; 
      char ch;              
     }a,b,c;

    2.4 共用体的特点

    1. 所有成员引用的是内存中相同的位置
    2. 共用体变量任何时刻只有一个成员存在;
    3. 共用体变量定义分配内存,长度取决于最长成员与最宽基本数据类型成员

    2.5 共用体大小

    原则上,共用体的大小取决于占据最多内存的成员的长度,但会受到最宽基本类型成员大小的影响。即:共用体的总大小为共用体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)

    如下例:

    union MyUnion
    {
        int i;
        char chs[11];
    };
    
    void main()
    {
        printf("%d\n", sizeof(union MyUnion));
    
        system("pause");
    }
    // 输出12
    

    2.6 共用体变量引用

    1. 引用方式:

      (1) 共用体变量名.成员名
      (2) 共用体指针名->成员名
      (3) (*共用体指针名).成员名

    2. 引用规则
      (1) 不能引用共用体变量,只能引用其成员
      (2) 共用体变量中起作用的成员是最后一次存放的成员
      (3) 不能在定义共用体变量时对所有成员进行初始化
      (4) 可以用一个共用体变量为另一个变量赋值

    2.7 结构体变量和共用体变量内存形式的不同

    结构体变量中的数据程序是并列关系,而编译器为共用体变量中的数据成员分配的是同一块内存,每个时刻只有一个数据成员有意义,从地址的角度来看两者的差异,形象地表明了这一点。
    这里写图片描述

    2.8 结构体与共用体的相互嵌套

    某些情况下需要嵌套使用以满足各种需求,如下示例:

    union MyUnion2
    {
        int i;
        struct MyStruct
        {
            int i;
            char ch;
        } s;
    
    };
    
    struct MyStruct
    {
        int type;
        union 
        {
            int i;
            float f;
            char *str;
        }value;
    };
    

    需要注意的是,嵌套后的结构体或共用体的大小仍遵循字节对齐。

    2.9 共用体变量的初始化

    在声明一个共用体变量的同时,可以完成其初始化,与结构变量的初始化不同的是,只能对共用体变量列表中的一个变量进行初始化。

    对共用体MyUnion来说,下列语句是合法的:

        union MyUnion mu = { 1 };  // 默认初始化第一个成员
        union MyUnion mu2 = { .chs = "hello" };  // 指定要初始化的成员

    与结构类似,可以把共用体定义、共用体变量声明及其初始化放在一起,如:

    union MyUnion
    {
        int i;
        char chs[11];
    }u = { 10 }, u2 = {.chs="niko"};   // 初始化
    

    使用示例:

    
    union MyUnion
    {
        int i;
        char chs[11];
    }u = { 10 }, u2 = {.chs="niko"};
    
    void main()
    {
        union MyUnion mu = { 1 };  // 默认初始化第一个成员
        union MyUnion mu2 = { .chs = "hello" };  // 指定要初始化的成员
        printf("mu.i=%d,mu.chs=%s\n", mu.i, mu.chs);  // 一个成员最后被赋值,其他的会出现垃圾值
        printf("mu2.i=%d, mu2.chs=%s\n", mu2.i, mu2.chs);
    
        u2 = u; // 赋值初始化
        strcpy(u2.chs, "hello world");  // 给共用体变量成员赋值
        printf("u2.i=%d,u2.chs=%s\n", u2.i, u2.chs);
        printf("MyUnion = %d\n", sizeof(union MyUnion));
    
        union MyUnion *up = &u;  //定义指向共用体的指针
        up->i = 100;
        printf("%d\n", up->i);
        system("pause");
    }
    

    后记:结构体与共用体的内容相对来说不算难,但内容还是有点多有点繁琐的。如发现错误,欢迎指正。欢迎交流学习~

    拓展阅读,结构体的使用案例:C语言 实现一个双链表

    展开全文
  • 在C++中除了类中可以有构造函数和析构函数外,结构体中也可以包含构造函数和析构函数,这是因为...(1)由于C语言是面向过程的,所以C中的结构体就不存在面向对象的任何特点:不能继承;不能封装;不能多态;不存在访

    在C++中除了类中可以有构造函数和析构函数外,结构体中也可以包含构造函数和析构函数,这是因为结构体和类基本雷同,唯一区别是,类中成员变量默认为私有而结构体中则为公有。注意,C++中的结构体是可以有析构函数和构造函数,而C则不允许。至于联合体,它是不可能有析构函数和构造函数的。本质上,它是一种内存覆盖技术的体现,也就是说,同一块内存在不同的时刻存储不同的值(可能是不同类型的)。

    C语言中的结构体

    (1)由于C语言是面向过程的,所以C中的结构体就不存在面向对象的任何特点:不能继承;不能封装;不能多态;不存在访问控制,只有作用域。
    (2)C语言中的结构体只能定义数据,而不能定义方法,虽然C语言的结构体中不能定义函数,但是却可以定义函数指针,不过函数指针本质上不是函数而是指针。
    (3)C语言中的结构体不能为空,否则会报错。定义一个结构体的变量时,结构体名前的struct关键字不能省略,否则会报错。

    struct  A
    {
        int num;
    };
    int main()
    {
        struct A a = { 1 };
    }
    

    c++ 结构体和类的区别

    而struct和class之间最本质的一个区别就是默认的访问控制: struct默认的数据访问控制是public的,而class默认的成员变量访问控制是private的。

    C++结构体的初始化

    结构体是常用的自定义构造类型,是一种很常见的数据打包方法。结构体对象的初始化有多种方式,分为**顺序初始化**、**指定初始化**、**构造函数初始化**。假如有如下结构体。

    struct A {
    	int b;
    	int c;
    };
    

    (1)顺序初始化因为书写起来较为简约,是我们最常用的初始化方式,但相对于指定初始化,无法变更数据成员初始化顺序,灵活性较差,而且表现形式不直观,不能一眼看出 struct 各个数据成员的值。

    A a = {1, 2};
    

    (2)指定初始化(Designated Initializer)实现上有两种方式,一种是通过点号加赋值符号实现,即“.fieldname=value”,另外一种是通过冒号实现,即“fieldname:value”,其中 fieldname 为结构体成员名称 。前者是 C99 标准引入的初始化方式,后者是 GCC 的扩展。遗憾的是有些编译器并不支持指定初始化,比如 Visual C++。

    // 点号+赋值符号
    A a = {.b = 1, .c = 2};
    

    //冒号
    A a = {b:1, c:2};

    Linux 内核喜欢用 .fieldname=value 的方式进行初始化,使用指定初始化,一个明显的优点是成员初始化顺序和个数可变,并且扩展性好,比如在结构体非末尾处增加字段时,避免了传统顺序初始化带来的大量修改。

    (3)构造函数初始化常见于 C++ 代码中,因为 C++ 中的 struct 可以看作 class,结构体也可以拥有构造函数,所以我们可以通过结构体的构造函数来初始化结构体对象。给定带有构造函数的结构体:

    struct A {
    	A(int a,int b) {
    		this-&gt;a=a;
    		this-&gt;b=b;
    	};
    	int b;
    	int c;
    }
    

    那么结构体对象的初始化可以像类对象的初始化那样,如下形式:

    注意: struct 如果定义了构造函数的话,就不能用大括号进行初始化了,即不能再使用指定初始化与顺序初始化了。

    2.结构体赋值

    变量的赋值和初始化是不一样的,初始化是在变量定义的时候完成的,是属于变量定义的一部分,赋值是在变量定义完成之后想改变变量值的时候所采取的操作。还是给定结构体 A:

    struct A {
    	int b;
    	int c;
    };
    

    注意: 结构体变量的赋值是不能采用大括号的方式进行赋值的,例如下面的赋值是不允许的。

    A a;
    a={1,2};	// 错误赋值
    

    下面列出常见结构体变量赋值的方法。

    (1)使用 memset 对结构体变量进行置空操作:

    按照编译器默认的方式进行初始化(如果 a 是全局静态存储区的变量,默认初始化为0,如果是栈上的局部变量,默认初始化为随机值)
    A a; 
    memset(&amp;a,0,sizeof(a));
    

    (2)依次给每一个结构体成员变量进行赋值:

    A a; 
    a.b=1;
    a.c=2;
    

    (3)使用已有的结构体变量给另一个结构体变量赋值。也就是说结构体变量之间是可以相互赋值的。

    A a={1,2};
    struct A a1;
    a1=a; 				// 将已有的结构体变量赋给a1
    

    初始化与赋值有着本质的区别,初始化是变量定义时的第一次赋值,赋值则是定义之后的值的变更操作,概念上不同,所以实现上也不一样。


    参考链接:

    链接: C++ 结构体初始化与赋值.
    链接: C++ 结构体的构造函数和析构函数.

    展开全文
  •  简单的来说,结构体就是一个可以包含不同数据类型的一个结构,它是一种可以自己定义的数据类型,它的特点和数组主要有两点不同,首先结构体可以在一个结构中声明不同的数据类型,第二相同结构的结构体变量是可以...
    结构体 

      结构体就是一个可以包含不同数据类型的一个结构,它是一种可以自己定义的数据类型,它的特点和数组主要有两点不同,首先结构体可以在一个结构中声明不同的数据类型,第二相同结构的结构体变量是可以相互赋值的,而数组是做不到的,因为数组是单一数据类型的数据集合,它本身不是数据类型(而结构体是),数组名称是常量指针,所以不可以做为左值进行运算,所以数组之间就不能通过数组名称相互复制了,即使数据类型和数组大小完全相同。 


      定义结构体使用struct修饰符,例如:
    struct test 
    { 
    float a; 
    int b; 
    };


      上面的代码就定义了一个名为test的结构体,它的数据类型就是test,它包含两个成员a和b,成员a的数据类型为浮点型,成员b的数据类型为整型。 

      注意:结构体生命的时候本身不占用任何内存空间,只有当你用你定义的结构体类型定义结构体变量的时候计算机才会分配内存。 


    各种结构体定义

    1.普通的结构体

    struct Person{  
            char name[20];  
            int age;  
            float height;  
    };  



    2.带变量初始化的结构体

    struct Person{  
            char name[20];  
            int age;  
            float height;  
    }Jack;  
      


    3.成员变量和声明一起定义


    struct Person Jack <"Jack",24,175>


    展开全文
  • c语言中允许自己创建类型,有结构体,枚举及联合体,以下就是对这三种自定义类型的讲解 文章目录结构体**结构体内存对齐****结构体传参**位段**位段的内存分配****位段的跨平台问题**枚举类型**枚举的优点****枚举的...
  • C语言结构体的应用

    2019-11-28 19:22:45
    有两本书,用同一个结构体类型,不同结构体变量来描述这本书的特点。 结构体的内容数据量可能相对很大,所以用函数进行处理,会使代码简便很多。 把结构体作为函数参数,传参方式与其他的类型或指针类似。 #...
  • c语言结构体详解

    2016-03-01 16:35:01
     简单的来说,结构体就是一个可以包含不同数据类型的一个结构,它是一种可以自己定义的数据类型,它的特点和数组主要有两点不同,首先结构体可以在一个结构中声明不同的数据类型,第二相同结构的结构体变量是可以...
  • 一、结构体  在前面的数组分享中,把同一类型...先定义结构体类型, 在定义结构体变量  struct student {  int age ;  char *name;  double height;  };  struct student sd;  2.定义结构体类型的同时
  •  简单的来说,结构体是个能包含不同数据类型的一个结构,他是一种能自己定义的数据类型,他的特点和数组主要有两点不同,首先结构体能在一个结构中声明不同的数据类型,第二相同结构的结构体变量是能相互赋值的,...
  • 一、结构体 在前面的数组分享中,把同一类型的数据进行保存通过数组,我们可以用数组来表示这个整体,但是数组有个特点:内部的每一个元素都必须是相同类型...1.先定义结构体类型, 在定义结构体变量 struct student {
  • 前面学习了变量和数组这些简单的数据结构,它们的特点是必须使用规定的数据类型。例如数组被定义为整型后,它的所有存储单元都是由整型构成。现实生活中某一类事物的共同属性可能是由不同的数据类型组成的集合,或者...
  • //---------------------结构体 什么是结构体? 答:若干个相同或者不同类型的数据组成的新的类型 如何定义结构体 struct 结构体名{  成员列表;...结构体变量特点: 一个复合类型,
  • 结构体

    2019-12-11 14:34:18
    lv2 Day4 02 条件编译与结构体一 C语言中结构体的好处,为什么要设计一个结构体?结构体的特点C语言中结构体的基本定义。 定义一个职工worker的...写出一个结构体成员本身也是一个结构体变量的例子。 例如 员工...
  • 文章目录结构体一般形式定义结构体变量方法:结构体变量的初始化共用体typedef内存管理动态内存malloc/free注意事项 结构体 一般形式 struct 结构体名 { 数据类型 成员名1; 数据类型 成员名2; }; 特点: ...
  • 我们在程序里会创建很多变量,有时候我们需要用某个变量来描述一个人,而一个人身上的特点有很多,不止一个,如果只用一个特点来描述就显得不那么准确。所以我们要创建多个变量来描述同一个人;而把这多个变量放在...
  • C语言程序设计 - 第1章 C语言学习基础 第7章 复杂数据结构 结构体联合及 用户自定义类型 本章教学目标 1掌握定义结构体类型结构体变量结构体数 组和结构体指针的方法 2掌握初始化结构体变量结构体数组的方法 3掌握...
  • 相信了解strcpy函数、struct结构体类型变量地址分配的人会一看就会知道为什么。 定义了一个struct结构体类型,如下: 给M_array[0]赋值如图所示: 然后按照赋值的顺序输出一下结果发现非常的amazing啊!如图所示: ...
  • 结构体数组指向结构体类型数据的指针访问形式结构体变量作函数参数动态储存分配malloc函数calloc函数free函数链表头指针建立动态链表对链表的删除操作对链表的插入操作共用体共用体和结构体的比较共用体类型数据的...
  • 目录一、结构体的定义二、结构体变量的定义三、结构体的注意点四、结构体的初始化五、结构体的使用六、结构体数组七、结构体作为函数参数八、指向结构体的指针变量   当一个整体由多个数据构成时,我们可以用...
  • 第七章 结构体一、目的二、特点三、声明、定义、初始化和使用1.声明2....结构体是由不同类型数据组成的组合型数据结构,在内存中这些数据按各自所占内存大小连续存放,每个结构体变量所占的内存为各...
  • 4.结构体变量的定义和初始化 5.结构体内存对齐 6.结构体传参 二、枚举 1.枚举类型的定义 2.枚举的使用 3.枚举的特点 三、联合 1.联合类型的定义 2.联合的特点 3.联合大小的计算 一、结构体 ...
  • 结构体变量的定义和初始化 结构体内存对齐 结构体传参 结构体实现位段(位段的填充&可移植性) 枚举 枚举类型的定义 枚举的优点 枚举的使用 联合 联合类型的定义 联合的特点 联合大小的...
  • 结构体变量的定义和初始化 结构体内存对齐 结构体传参 结构体实现位段(位段的填充&可移植性) 枚举 枚举类型的定义 枚举的优点 枚举的使用 联合 联合类型的定义 联合的特点 联合大小的计算 正文开始 结构体 ...
  • 结构体变量的定义和初始化 结构体内存对齐 结构体传参 结构体实现位段(位段的填充&可移植性) 2、枚举 枚举类型的定义 枚举的优点 枚举的使用 3、联合 联合类型的定义 联合的特点 联合大小的计算
  • 结构的成员变量可以是任何类型的,包括基本类型、结构体结构体指针等 成员访问方式: 通过结构变量名:结构变量名.成员变量名 通过结构体指针:指针->成员变量名 或 (*指针).成员变量 注: 点运算符的前体是...
  • 结构体&共用体

    2018-08-01 17:13:24
    结构体是C语言中的一种数据类型,它有如下特点 1) 结构体是一种构造数据类型 2) 把不同类型的数据组合成一个整体来自定义数据类型 1.2 结构体的定义方式与结构体变量的声明 1) 定义形式 定义结构体类型的同时...
  • 特点:可定义多种数据类型 描述:从定义和结合上来进行说明 一般形式:struct 结构体名  { 成员列表 } 变量列表 ; 定义+声明+初始化 // 结构体声明 + 定义 + 初始化 struct Student { char name[69]; char ...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 155
精华内容 62
关键字:

c语言结构体变量特点

c语言 订阅