C语言结构体

谨记

怎么是价值?或许没有稍微人可以明白,其实价值并不是实在存在的,它应当是一种呈现,比如为都市点缀最美好的一面而起早摸黑的打扫的都市清洁工的大婶四伯;为中国航天事业而多少个月没回家奋斗在一线的工程师们;为城市交通方便,上班不迟到的公交车司机;为友好人生而奋斗终生的你等等。太多了,价值是无处不在的,不管您在身在哪儿,做着怎样事,你都反映了您的一份价值,或许你的价值在外人心里是那么的巨大,又或者是那么的一线,请你势必要牢记,你的一举一动一言一行都控制了您的价值。

引用

前面我们学习了关于C语言很多的知识,希望大家都掌握了,对于C语言来说,大部分高级语法其实和C语言是想通的,所以,学好C语言将来你要转其他语言是很轻松的。那么,今天我们将学习C语言的结构体、枚举以及简单的介绍一下位域,希望读者认真的理解结构体和枚举。

结构体

1、结构体的定义

在其实的拍卖目的中,有好多音信是由两个例外品类的数码整合在联合举办描述,而且这个不同门类的多少是相互联系组成了一个有机的共同体。此时,就要用到一种新的构造类型数据——结构体(structure),简称结构。
结构体的功用:为了处理千头万绪的数据结构(如动态数据结构等)提供了实用的手段,而且,它们为函数间传递不同档次的数据提供了便于。
结构体和数组一样,也是一种构造型数据类型,是用户自定义的新数据类型,在结构体中得以涵盖若干个例外数据类型和不同含义的数量项(当然也可以一样),从而使这么些多少项组成起来反映某一个信息。
譬如,可以定义一个学童student结构体,在这个结构体中概括学生学号、姓名、性
别、年龄、家庭住址、联系电话。那样就可以用一个结构体数据类型的变量来存放在某个学生的装有相关音讯。并且,用户自定义的数据类型student也足以与int、double等主导数据类型一样,用来作为定义其他变量的数据类型。

定义一个结构体类型的一般形式为
struct  结构体名
{
   数据类型   成员名1;
   数据类型   成员名2;
   :
   数据类型   成员名n;
};
在花括号中的内容也称为“成员列表”或“域表”。
其中,每个成员名的命名规则与变量名相同;
数据类型可以是基本变量类型和数组类型,或者是一个结构体类型;
用分号“;”作为结束符。整个结构的定义也用分号作为结束符。

struct student{   
    long number;
    char name[20];
    char gender;        
    int age;            //  age是成员名
    float salary;
    char address[80];
};                      //注意分号不能省略
int  age = 10;      //age是变量名 

协会体类型中的成员名可以与程序中的变量名相同,二者并不代表一样对象,编译程序可以活动对它们举行区分。
出于结构体的分子的数据类型可以是此外项目,可能是大旨变量类型、数组类型、结构体类型、联合体类型或枚举类型等。

总结

布局体类型的特性:
a.结构体类型是用户自动协会的;
b.它由若干例外的主导数据类型的数据整合;
c.它属于C语言的一种数据类型,与整型、浮点型相当。由此,定义它时不分配空间,唯有用它定义变量时才分配空间。

2、结构体变量的宣示、开首化及利用

2.1 结构体变量的注解
在概念了协会体类型后,就足以注脚结构体类型的变量。有下边两种样式:
① 先定义结构体类型,再定义变量名
概念结构体变量的相似格局如下:

struct 结构体名{
类型 成员名;
类型 成员名;
……
};
struct 结构体名 结构体变量名;

此间的布局体名是结构体的标识符,不是变量名。类型可以是基本的数据类型也得以是其他构造型数据类型。

struct Person
    {
        char array[20];
        char *name;
        int age;
        double height;
    };
    struct Person p;

注意

struct Person代表的是项目名,不可以分别和精炼写,比如“struct
P”;这是荒谬的语法。

② 在概念类型的还要,定义变量
这种格局的概念的貌似格局为

struct 结构体名
    {
类型 成员名;
类型 成员名;
……
    }变量名;

struct Person
    {
        char array[20];
        char *name;
        int age;
        double height;
    }per;

③ 直接定义结构体变量
只要简单结构体名,则称之为无名结构体,这种状态时常出现在函数内部。
这种形式的概念的貌似模式为

struct 
    {
类型 成员名;
类型 成员名;
……
    }变量名;

struct
    {
        char array[20];
        char *name;
        int age;
        double height;
    }per;

结构体所占内存空间大小

一个结构体变量占用内存的实在尺寸,可以利用sizeof求出。它的演算说明式为
sizeof(运算量)
里头运算量可以是变量、数组或结构体变量,能够是数据类型的名称。这样,就足以求出给定的运算量占用内存空间的字节数。
sizeof(struct person);
sizeof(per);

2.2、结构体变量的应用
结构体变量是见仁见智数据类型的多少数目标集合体。在先后中动用结构体变量时,一般景象下不可能把它看成一个完好无损插足数据处理,而出席各样运算和操作的是结构体变量的次第成员项数据。

结构体变量的成员用以下一般形式表示:
    结构体变量名.成员名

在概念了结构体变量后,就可以用不同的赋值方法对结构体变量的每个成员赋值。

per.age = 27;
per.name = "helloworld";

除去,还可以够引用结构体变量成员的地址以及成员中的元素。例如:引用结构体变量成员的首地址&per.name;引用结构体变量成员的第二个字符per.name[1];引用结构体变量的首地址&per。

和谐指示
结构体变量在使用中应留神以下几点。

无法将一个布局体类型变量作为一个整机加以引用,而只可以对协会体类型变量中的各样成员分别引用。

printf("%s",per);//这种写法是错的
printf("%s\n",per.name);//这是可以的

举一个一体化的示范:

#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[]) {
    struct person {
        char name[20];
        int  age;
        double height;
    }per;
    memset(&per, 0, sizeof(per));
    printf("name:");
    scanf("%s",per.name);
        printf("age:");
    scanf("%d",&per.age);
    printf("height:");
    scanf("%lf",&per.height);
    printf("%s\n  %d\n %lf\n",per.name,per.age,per.height);
    return 0;
}
输出结果:
name:helloworld
age:12
height:178
helloworld
  12
 178.000000
Program ended with exit code: 0


假诺成员自身又属一个布局体类型,则要用若干个成员运算符,一流一流地找到最低的一级成员。只可以对最低级的成员开展赋值或存取以及运算。

#include <stdio.h>
#include <string.h>
#define N 64
struct employee{
    char name[N];
    struct {
        int year;
        int month;
        int day;
    }birthday;
    char gender;
    char address[N];
    float salary;
};
int main(int argc, const char * argv[]) {
    struct employee e1;
    memset(&e1, 0, sizeof(e1));
    printf("name:");
    scanf("%s", e1.name);
    printf("year:");
    scanf("%d", &e1.birthday.year);
    printf("month:");
    scanf("%d", &e1.birthday.month);
    printf("day:");
    scanf("%d", &e1.birthday.day);
    getchar();
    printf("gender:");
    scanf("%c", &e1.gender);
    printf("address:");
    scanf("%s", e1.address);
    printf("salary:");
    scanf("%f", &e1.salary);
    printf("\ninformation:%s %d-%d-%d %c %s %f\n", e1.name, e1.birthday.year,
            e1.birthday.month, e1.birthday.day, e1.gender, e1.address, e1.salary);
    return 0;
}
输出结果:
name:zhangsan
year:1989
month:12
day:11
gender:m
address:Suzhou
salary:3200.5

information:zhangsan 1989-12-11 m Suzhou 3200.500000
Program ended with exit code: 0

在该程序中,结构体的成员birthday,是一个构造体类型的变量。对于如此的变量,可以如此访问各成员:

e1.birthday.year
e1.birthday.month
e1.birthday.day

注意:无法用e1.birthday来访问e1变量中的成员birthday,因为birthday本身是一个结构体变量。

对成员变量可以像普通变量一样举行各种运算(按照其项目决定可以展开的演算)。例如:

e2.age=e1.age;
sum=e1.age+e2.age;
e1.age++;


在数组中,数组是不可以互相赋值的,而构造体类型变量可以互相赋值。在C程序中,同一结构体类型的结构体变量之间允许互相赋值,而不同结构体类型的结构体变量之间不容许相互赋值,即便两者包含有一样的积极分子。

2.3、结构体变量起始化
与此外系列变量一样,也得以给结构体的各类成员赋初值,这称之为结构体的起始化。一种是在概念结构体变量时进行初叶化,语法格式如下:

struct  结构体名 变量名={初始数据表};

另一种是在概念结构体类型时开展结构体变量的初阶化。

struct  结构体名
{
类型 成员名;
类型 成员名;
……
}变量名={初始数据表}; 

那里就不在举例了,后边的事例会用。

社团体数组

不无同样结构体类型的结构体变量也足以组合数组,称它们为结构体数组。结构体数组的每一个数组元素都是结构体类型的数码,它们都各自包括各个成员(分量)项。
概念结构体数组的措施和概念结构体变量的措施相仿,只需表明其为数组即可。可以动用以下形式。
① 先定义结构体类型,再用它定义结构体数组,定义情势如下:

struct 结构体名 
{
类型 成员名;
类型 成员名;
……

};
struct 结构体名 数组名[元素个数];

#define N 64
struct employee{
    char name[N];
    int age;
    char gender;
    char address[N];
    float salary;
};
struct employee e[10];
这种声明格式是最常见的。

② 定义结构体类型的同时,定义结构体数组,定义形式如下:

struct 结构体名 
{
类型 成员名;
类型 成员名;
……

}数组名[元素个数];

#define N 64
struct employee{
    char name[N];
    int age;
    char gender;
    char address[N];
    float salary;
} e[10];
这种情况,定义结构体数组,不用重复写结构体类型,很简洁。一般,当需要声明一个全局的结构体数组时,使用这种方式。

③ 直接定义结构体数组,定义形式如下:

struct  
{
类型 成员名;
类型 成员名;
……

}数组名[元素个数];

#define N 64
struct{
    char name[N];
    int age;
    char gender;
    char address[N];
    float salary;
} e[10];

结构体数组最先化
社团体数组在概念的还要也足以拓展起先化,并且与结构体变量的起先化规定同样。
社团体数组开头化的貌似形式是:

   struct 结构体名  
    {
    类型 成员名;
    类型 成员名;
    ……
    };
    struct 结构体名 数组名[元素个数]={初始数据表};
    或者
    struct 结构体名 
    {
    类型 成员名;
    类型 成员名;
    ……
    }数组名[元素个数]={初始数据表};
    或者
    struct
    {
    类型 成员名;
    类型 成员名;
    ……
    }数组名[元素个数]={初始数据表};

鉴于结构体变量是由若干不同连串的数量整合,而构造体数组又是由若干结构体变量组成。所以要特别注意包围在大括号中的初始数据的一一,以及它们与各种成员项间的附和关系。
社团体数组的应用
一个布局体数组的因素相当于一个结构体变量,因在此之后边介绍的有关结构体变量的条条框框也适应于结构体数组元素。
(1)引用某一元素中的成员。
(2)可以将一个布局体数组元素值赋给一样结构体类型的数组中的另一个因素,或赋给同样类型的变量。
(3)不能把协会体数组元素作为一个整机直接举办输入输出。

#include <stdio.h>
#include <string.h>
#define N 64
struct employee{
    char name[N];
    struct {
        int year;
        int month;
        int day;
    }birthday;
    char gender;
    char address[N];
    float salary;
}e1[2] = { {"zhangsan", {1980, 9, 4}, 'w', "Shanghai", 3400}, 
           {"lisi", {1991, 10, 24}, 'w', "Hebei", 3400}};
int main(int argc, const char * argv[]) {
    struct employee e2[2] = {{"wangwu", {1986, 2, 24}, 'w', "Hubei", 6400}, 
                             {"Lucy", {1986, 8, 14}, 'w', "Henan", 3421}};
    int i;
    for (i = 0; i < sizeof(e1)/sizeof(struct employee); i++)
        printf("information :%s %d-%d-%d %c %s %f\n", e1[i].name, 
                e1[i].birthday.year, e1[i].birthday.month, e1[i].birthday.day, 
                e1[i].gender, e1[i].address, e1[i].salary);
    printf("\n");
    for (i = 0; i < sizeof(e2)/sizeof(struct employee); i++)
        printf("information :%s %d-%d-%d %c %s %f\n", e2[i].name, 
                e2[i].birthday.year, e2[i].birthday.month, e2[i].birthday.day, 
                e2[i].gender, e2[i].address, e2[i].salary);
    return 0;
}
在该程序中,声明了两个结构体数组,一个全局数组,一个局部数组。在声明的同时,写初始化列表初始化。

结构体指针

可以设定一个指针变量用来针对一个结构体变量。此时该指针变量的值是结构体变量的苗头地址,该指针称为结构体指针。
结构体指针与前方介绍的各类指针变量在特点和章程上是同一的。与前述相同,在先后中结构体指针也是通过拜访目的运算“*”访问它的对象。结构体指针在先后中的一般定义格局为

struct 结构体名  *结构指针名;

里面的构造体名必须是早就定义过的协会体类型。
例如,对于上一节中定义的构造体类型struct
employee,可以印证使用这种社团体类型的协会指针如下:

struct employee *p;

内部p是指向struct
employee结构体类型的指针。结构体指针的验证规定了它的数量特性,并为结构体指针本身分配了迟早的内存空间。不过指针的始末从未确定,即它指向随机的对象,需要为指针变量赋初值。

#include <stdio.h>
#include <string.h>
#define N 64
struct employee{
    char name[N];
    int age;
    char gender;
    char address[N];
    float salary;
};
void input(struct employee *p){
    printf("name:");
    scanf("%s", p->name);
    printf("age:");
    scanf("%d", &p->age);
    getchar();
    printf("gender:");
    scanf("%c", &p->gender);
    printf("address:");
    scanf("%s", p->address);
    printf("salary:");
    scanf("%f", &p->salary);
}
void output(struct employee *p){
    printf("information:%s %d %c %s %f\n", p->name, p->age,
            p->gender, p->address, p->salary);
}
int main(int argc, const char * argv[]) {
    struct employee e1;
    memset(&e1, 0, sizeof(e1));
    input(&e1);
    output(&e1);
    return 0;
}
输出结果:
name:zhao
age:21
gender:m
address:Shanghai
salary:3421.1
information:zhao 21 m Shanghai 3421.100098
Program ended with exit code: 0

枚举

在C语言中还有一种构造类型,即枚举。在骨子里问题中,有些变量只有两种可能的取值。例如:一周有七天,程序中的错误唯有那么二种等。针对如此特其它变量,C语言中提供了“枚举”类型,在枚举的定义中,会将变量的值一一列出来。当然,枚举类型的变量的值也就只限于列举出来的值的界定内。
枚举类型的定义
枚举类型的概念格局如下:
enum 枚举名{ 枚举成员列表 };
在枚举成员列表中列出具有可能的取值,以分公司结尾。注意和结构体、联合体类似,“enum
枚举名”是新定义的档次名。
比方如下:

enum TimeofDay 
{ 
morning, 
afternoon, 
evening
};

该枚举名为提姆eofDay,共有3种可能的取值。在概念该枚举类型的变量时,也只好取其中的一个值,举办赋值。
枚举变量的宣示
其实枚举变量的讲明和我们地点说的结构体变量的宣示是千篇一律的。
艺术一:先定义类型,再讲明变量

enum TimeofDay 
{ 
morning, 
afternoon, 
evening 
};
enum TimeofDay a, b;

方法二:在概念类型的还要,表明变量

enum TimeofDay 
{ 
morning, 
afternoon, 
evening 
} a, b;

主意三:直接定义无名枚举变量

   enum 
    { 
    morning, 
    afternoon, 
    evening 
    } a, b;

枚举变量的使用
经过一个演示来说吧

#include <stdio.h>
enum TimeofDay{
    morning = 2,
    afternoon,
    evening
}a;
int main(int argc, const char * argv[]) {
    enum TimeofDay b, c;
    a = morning;
    b = afternoon;
    c = evening;
    printf("a=%d b=%d c=%d\n", a, b, c);
    c = 10;
    printf("a=%d b=%d c=%d\n", a, b, c);
    return 0;
}
运行结果:
a=2 b=3 c=4
a=2 b=3 c=10
Program ended with exit code: 0

通过该程序,可以见到,可以把枚举成员的值赋予枚举变量,也得以把整数值直接授予枚举变量。实际上,枚举变量,也是一种整型变量,因而,也可以使用switch-case结构,示例程序如下:

#include <stdio.h>
enum TimeofDay{
    morning,
    afternoon,
    evening
};
int main(int argc, const char * argv[]) {
    int i, j;
    enum TimeofDay a[10];
    j = morning;
    for (i = 0; i < 10; i++)
    {
        a[i] = j;
        j++;
        if (j > evening)
            j = morning;
    }
    for (i = 0; i < 10; i++)
    {
        switch (a[i])
        {
            case morning: printf("%d morning\n", a[i]); break;
            case afternoon: printf("%d afternoon\n", a[i]); break;
            case evening: printf("%d evening\n", a[i]); break;
            default:break;
        }
    }
    return 0;
}
输出结果:
0 morning
1 afternoon
2 evening
0 morning
1 afternoon
2 evening
0 morning
1 afternoon
2 evening
0 morning
Program ended with exit code: 0

位域的介绍

在这边,对于位域,只是一个简短的介绍,那么些用的不是诸多,如若真需要用,提议读者去官网看教程。
位域的概念
所谓“位域”是把一个字节中的二进位划分为多少个不等的区域,并证实每个区域的位数。每个域有一个域名,允许在先后中按域名举办操作。这样就可以把几个不等的目的用一个字节的二进制位域来表示。
位域的定义与结构体的定义相似,其相似形式如下:

struct 位域结构名
{   
  位域列表 
};

766net必赢亚洲手机版,其中位域列表的样式为

类型说明符 位域名:位域长度

例如:

 struct data{
    unsigned int a:2;
    unsigned int b:3;
    unsigned int c:3;
};
其中a表示data的低两位,表示data的3~5位,c表示data的6~8位。

有关位域的定义,有一部分问题亟待小心。
① 个位域必须存储在同一个字节中,不可以跨四个字节。
② 位域的占用的位数,无法超越8个二进制位。
③ 允许位域无域名。
位域的利用
位域的施用和结构成员的施用相同,其貌似形式为
位域变量名.位域名
示范代码

#include <stdio.h>
struct data{
    unsigned int a: 2;
    unsigned int b: 4;
    unsigned int: 0;
    unsigned int c: 3;
}t;
int main(int argc, const char * argv[]) {
    struct data *p;
    t.a = 3;
    t.b = 5;
    t.c = 6;
    printf("t.a=%d t.b=%d t.c=%d\n",t.a, t.b, t.c);
    p = &t;
    p->a = 2;
    p->b &= 0;
    p->c |= 1;
    printf("t.a=%d t.b=%d t.c=%d\n",t.a, t.b, t.c);
    return 0;
}
输出结果:
t.a=3 t.b=5 t.c=6
t.a=2 t.b=0 t.c=7
Program ended with exit code: 0
说明:由于位域中的各个域是以二进制位为单位,因此,大部分的位域程序,都有位运算

总结

本篇随笔介绍了C语言的结构体、枚举、位域,以及结构体和数组、指针的联络,内容比较多,希望读者认真的敞亮和认知,那么,在此地,C语言的根底知识点我们都早就学的大多了。希望能给读者带来帮忙。

结尾

企望读者真诚的相比每一件事情,每一日都能学到新的知识点,要切记,认识不久,满面春风也是过一天,不开玩笑也是一天,无所事事也是一天,小小收获也是一天,欢迎收藏和点赞、喜欢。最终送读者一句话:你的路你协调挑选。

发表评论

电子邮件地址不会被公开。 必填项已用*标注