C语言中的结构体和枚举


1、结构体的基本使用:

 定义形式:

<pre name="code" class="objc">struct 结构体名
{
    类型名1 成员名1;
    
    ......
    
    类型名n 成员名n ;
};


struct是关键字,是结构体类型的标志 

例如:

#include<stdio.h>
/*
 数组:只能由多个相同类型的数据构成
 
 结构体:可以由多个不同类型的数据构成
 */

int main()
{
    //1.定义结构体类型
    struct Person
    {
        //里面的三个变量,可以称为是结构体的成员或者属性
        int age;  //年龄
        double height;  //身高
        char *name;  //姓名
    };
    
    //2.根据结构体类型,定义结构体变量
    struct Person p = {20,1.55,"jack"};
    
    p.age = 20;
    p.name = "rose";
    
    printf("age = %d,name = %s,height = %f\n",p.age,p.name,p.height);
 
    struct Person p2 = {.age = 30,.name = "rose",.height = 1.62};
    
//这样是错误的,只能在定义的时候赋值
//    struct Person p2;
//    p2 = {30,1.67,"jack"};
    
    
    return 0;
}


2.结构体变量的三种定义方式:

先定义结构体类型在定义结构体变量

定义结构体类型的同时,定义结构体变量

直接定义结构体类型变量,省略类型名

#include <stdio.h>

/*
 1.定义结构体变量的3种方式
 1> 先定义类型,再定义变量(分开定义)
 struct Student
 {
    int age;
 };
 struct Student stu;
 
 2> 定义类型的同时定义变量
 struct Student
 {
    int age;
 } stu;
 struct Student stu2;
 
 3> 定义类型的同时定义变量(省略了类型名称)
 struct
 {
    int age;
 } stu;
 
 2.结构体类型的作用域
 1> 定义在函数外面:全局有效(从定义类型的那行开始,一直到文件结尾)
 2> 定义在函数(代码块)内部:局部有效(从定义类型的那行开始,一直到代码块结束)
 */

// 从这行开始,一直到文件结尾,都是有效(跟全局变量一样)
struct Date
{
    int year;
    int month;
    int day;
};

int a;

void test2()
{
    struct Date
    {
        int year;
    };
    // 这里使用的是test2函数内部的struct Date类型
    struct Date d1 = {2011};
    
    
    // 结构体类型也是有作用域,从定义类型的那一行开始,一直到代码块结束
    struct Person
    {
        int age;
    };
    
    struct Person p;
    
    a  = 10;
}

int main()
{
    struct Date d1 = {2009, 8, 9};
    
    
    test2();
    
    // 不能使用test2函数中定义的类型
    // struct Person p2;
    
    return 0;
}

// 定义结构体变量
void test()
{
    // 定义结构体变量的第3种方式
    struct {
        int age;
        char *name;
    } stu;
    
    struct {
        int age;
        char *name;
    } stu2;
    
    
    /*结构体类型不能重复定义
     struct Student
     {
     int age;
     };
     
     struct Student
     {
     double height;
     };
     
     struct Student stu;
     */
    
    /* 错误写法:结构体类型重复定义
     struct Student
     {
     int age;
     double height;
     char *name;
     } stu;
     
     struct Student
     {
     int age;
     double height;
     char *name;
     } stu2;c
     */
    
    /*
     这句代码做了两件事情
     1.定义结构体类型
     2.利用新定义好的类型来定义结构体变量
     */
    // 定义变量的第2种方式:定义类型的同时定义变量
    /*
     struct Student
     {
     int age;
     double height;
     char *name;
     } stu;
     
     struct Student stu2;
     */
    
    /*
     // 定义变量的第1种方式:
     // 1.类型
     struct Student
     {
     int age;
     double height;
     char *name;
     };
     
     // 2.变量
     struct Student stu = {20, 1.78, "jack"};
     */
}


3.结构体内存分析:

#include<stdio.h>

int main()
{
    struct Student
    {
        int age; //4个字节
        char *name;  //8个字节
    };
    
    struct Student stu;
    stu.age= 20;
    stu.name = "jack";
    //补齐算法(对齐算法)  结构体所占存储空间为最大成员字节数的倍数  8+4 =12,自动补齐16
    
    int s = sizeof(stu);
    printf("%d\n",s);    //输出结果为16
    
    return 0;
}

//结构体的内存细节
void test()
{
//1.定义结构体类型(并不会分配存储空间)
    struct Date
    {
        int year;
        int month;
        int day;
    };
    //2.定义结构体变量(真正分配存储空间)
    struct Date d1 = {2014,4,10};
    
    struct Date d2 = {2012,8,9};
    
    //会将d1所有成员变量的值对应地赋值给d2的所有成员
    d2 = d1;
    
    d2.year = 2010;     //会只改变d2的的值
    
     //输出结果只有d2的year发生改变,其他都一样
     printf("%d - %d - %d\n ",d1.year,d1.month,d1.day);
     printf("%d - %d - %d\n ",d2.year,d2.month,d2.day);
    
    /*
    printf("%p - %p - %p\n ",&d1.year,&d1.month,&d1.day);
    
    int s = sizeof(d1);
    
    printf("%d\n",s);*/
}


定义结构体类型,只是说明了该类型的组成情况,并没有给它分配存储空间,就像系统不为int类型本身分配空间一样。只有当定义属于结构体类型的变量时,系统才会分配存储空间给该变量

4.结构体数组:

和结构体一样,结构体数组同样有3种定义形式:

<span style="color:#999900;">定义方式1:</span>
<span style="color:#999900;">struct Student {
    char *name;
    int age;
};
struct Student stu[5]; </span>
<span style="color:#999900;">定义方式2:</span>
<span style="color:#999900;">struct Student {
    char *name;
    int age;
} stu[5]; :</span>

定义方式3:

<span style="color:#999900;">struct {
    char *name;
    int age;
} stu[5]; </span>
结构体数组的初始化,和普通数组的用法是一样的,可以用数组的下标访问每一个结构体元素

#include<stdio.h>

int main()
{
    struct RankRecord
    {
        int no;   //序号
        char *name;  //名称
        int score;   //积分
    };
    /*
    struct RankRecord r1 = {1, "jack",600};
    struct RankRecord r2 = {2, "tack",500};
    struct RankRecord r3 = {3, "make",200};
     */
    
    //int ages[3] = {29,16,15};
    
    //对齐算法
    //能存放3个结构体变量,每个结构体变量占16个字节
    struct RankRecord records[3] =
    {
        {1,"jack",600},
        {2,"take",500},
        {3,"make",200}
    };
    
    records[0].no = 5;
    //错误写法
    //records[0] = {4,"rose",900};
    
    for (int i = 0; i<3; i++)
    {
        printf("%d\t%s\t%d\n",records[i].no,records[i].name,records[i].score);
    }
    
    return 0;
}


5.指向结构体的指针:

每个结构体都有自己的存储空间,因此指针也可以指向结构体变量

结构体指针变量的定义形式:struct 结构体名称 *指针变量名

3种访问结构体成员的方式:

结构体变量名.成员名

(*指针变量名).成员名

指针变量名->成员名

#include<stdio.h>
int main()
{
    struct Student
    {
        int no;
        int age;
    };
    //结构体变量
    struct Student stu = {1,20};
    
    //指针变量p用来指向struct Student类型的数据
    struct Student *p;
    
    //指针变量p指向来stu变量
    p = &stu;
    
    //第一种方式
    printf("age= %d,no =%d\n",stu.age,stu.no);
    
    //第二种方式
    printf("age=%d,no =%d\n",(*p).age ,(*p).no);
    
    //第三种方式
    printf("age=%d,no =%d\n",p->age,p->no);
    
    return 0;
}


枚举:当一个变量有几个固定的可能取值时,可以将这个变量定义为枚举类型。

比如,可以用一个枚举类型的变量来表示季节,因为季节只有4种可能的取值:春天、夏天、秋天、冬天。

枚举类型的定义:

一般形式为:enum 枚举名 {枚举元素1,枚举元素2,……};

enum Season {spring, summer, autumn, winter}; 

枚举变量的定义:

  先定义枚举类型,再定义枚举变量

enum Season {spring, summer, autumn, winter};
enum Season s;

定义枚举类型的同时定义枚举变量
enum Season {spring, summer, autumn, winter} s;

省略枚举名称,直接定义枚举变量
enum {spring, summer, autumn, winter} s;

枚举元素的值取决于定义时各枚举元素排列的先后顺序。默认情况下,第一个枚举元素的值为0,第二个为1,依次顺序加1。

枚举变量的赋值:

可以给枚举变量赋枚举常量或者整型值

enum Season {spring, summer, autumn, winter} s;

s = spring; // 等价于 s = 0;

s = 3; // 等价于 s = winter;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值