黑马程序员——C语言学习——结构体、枚举

————————Java培训、Android培训、iOS培训、.Net培训、期待与您交流!————————

一、结构体基本概念

之前我们学习过数组,知道数组只能存储一种数据类型。很有局限性。有没有一种东西可以存储多种数据类型呢?

有,这就是结构体


和别的类型不一样,因为结构体的类型需要用户自己创建,你想,结构体可以存储不同的类型,它本身是不是也要随之改变。

1.定义结构体类型

struct 结构体类型名 { 阐明结构体要包含的类型 };

    struct Person // Person是结构体类型名
    { // 里面的3个变量,可以称为是结构体的成员或者属性
        int age; // 年龄
        double height; // 身高
        char *name; // 姓名
    };

2、利用结构体类型定义结构体
    struct Person p = {20, 1.55, "jack"};

/* 错误写法

    在定义结构体初始化的时候,可以进行直接赋值,其他情况不可以
    struct Person p2;
    p2 = {30, 1.67, "jake"};
    */
3、访问结构体中的成员

p.age; // 就是访问结构体中 age成员

p.age = 50; // 也可在这种情况下赋值


4、结构体的注意点

1.定义结构体变量的3种方式
     1> 先定义类型,再定义变量(分开定义)
        struct Student
           {
                  int age;
          };
        struct Student stu;
 
     2> 定义类型的同时定义变量
          struct Student
              {
                 int age;
              } stu;
     这句代码做了两件事情
     1.定义结构体类型
     2.利用新定义好的类型来定义结构体变量

 
    3> 定义类型的同时定义变量(省略了类型名称)
              struct
                 {
                     int age;
                  } stu;


     4>结构体类型不能重复定义
          struct Student
             {
                 int age;
             };
     
          struct Student
              {
                   double height;
              };
 2.结构体类型的作用域
 1> 定义在函数外面:全局有效(从定义类型的那行开始,一直到文件结尾)
 2> 定义在函数(代码块)内部:局部有效(从定义类型的那行开始,一直到代码块结束)

 3.结构体中不能嵌套定义结构体

    // 类型
    struct Student
    {
        int no; // 学号
        
        struct Date birthday; // 生日
        
        struct Date ruxueDate; // 入学日期
        
        // 这种写法是错误的
        //struct Student stu;
    };


二、 结构体内存分析

我们在定义结构体类型的时候是不分配存储空间的。只在定义结构体变量的时候才真正分配存储空间。

而且结构体内存涉及到一个补齐算法。 也就是结果题的内存是由结构体中占最大内存的变量类型决定的。

如:

struct Student
    {
        int age;// 4个字节
        
        char a; // 一个字节
    };

我们会认为这个结构体占5个字节,但实际上是占8个字节。系统直接把char类型规定和int占一样大小的内存。

这就是补齐算法。小的向大的看齐。


三、 结构体数组

模仿多维数组

结构体变量后面加上[],里面可以定义结构体数组的大小

定义结构体类型

   struct RankRecord
    {
        int no; // 序号  4

        int score; // 积分 4
        char *name; // 名称 8
    };

定义结构体数组

   struct RankRecord records[3] =
    {
        {1, "jack", 5000},
        
        {2, "jim", 500},
        
        {3, "jake",300}
    };

由于补齐算法,结构体实际大小为72个字节


四、 指向结构体的指针

 1.指向结构体的指针的定义
     struct Student *p;
 
 2.利用指针访问结构体的成员
     1> (*p).成员名称  (*p)就代表结构体,模仿:结构体变量.成员变量
     2> p->成员名称

struct Student
    {
        int no;
        int age;
    };
    // 结构体变量
    struct Student stu = {1, 20};
    
    // 指针变量p将来指向struct Student类型的数据
    struct Student *p;
    
    // 指针变量p指向了stu变量
    p = &stu;
    
    p->age = 30;
    
    // 第一种方式
    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);

五、 结构体和函数

和基本数据类型一样,要直接传进函数,只是相当于赋值操作,函数任何运算与外面无关不会影响到外面

如:

// 如果结构体作为函数参数,只是将实参结构体所有成员的值对应地赋值给了形参结构体的所有成员
// 修改函数内部结构体的成员不会影响外面的实参结构体
void test(struct Student s)
{
    s.age = 30;
    s.no = 2;
}

只有将结构体指针传进函数根据指针指向内存地址的特性,可以在函数中修改结构体变量。

// 会影响外面的实参结构体
void test2(struct Student *p)
{
    p->age = 15;
    p->no = 2;
}

六、 枚举

在实际生活中某些变量固定的就那几个取值。我就需要一直变量来存储有固定取值的数据。

比如性别: 只有,男 女两种。没有必要定义成千上万

这时候就引出的枚举,只存储固定数目数据的类型

定义格式:

1.和结构体一样先定义枚举类型

enum 枚举类型名 { 值1,值2,……};

    //  定义季节枚举类型
    enum Season
    { // 一年只有四季
        spring = 1, // 春
        summer,  // 夏
        autumn,  // 秋
        winter     // 冬
    };


————————Java培训、Android培训、iOS培训、.Net培训、期待与您交流!————————

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值