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
};

拖欠枚举名为TimeofDay,共产生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

位域的牵线

以这边,对于位域,只是一个简的牵线,这个用之莫是广大,766net必赢亚洲手机版如果真的得为此,建议读者去官网看教程。
位域的定义
所谓“位域”是将一个字节中的亚上前位划分也几单例外的区域,并说明每个区域的位数。每个地方有一个域名,允许以程序中按域名展开操作。这样即便得管几乎独例外之对象用一个字节的二进制位域来表示。
位域的概念和结构体的定义相似,其貌似式如下:

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

中位域列表的款型呢

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

例如:

 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语言的基础知识点我们且已经拟的差不多了。希望能被读者带来帮助。

结尾

意在读者真诚之自查自纠每一样起事情,每天还能学到新的知识点,要牢记,认识不久,开心呢是过一样上,不开心也是如出一辙天,无所事事也是均等上,小小收获吧是同天,欢迎收藏和点赞、喜欢。最后送读者一句子话:你的里程你自己选。

发表评论

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