C语言 | chap8 结构体

结构体

8.1基本概念

  • C语言允许开发者根据实际开发需求来自定义数据类型,称之为构造数据类型。结构体就是构造数据类型中的一种。

  • 一般形式:

    struct 结构体标识符 {
    
    	类型  成员名;
    
    	类型  成员名;
    
    		…
    	}
    • 注意:新类型名称一定是 struct + 结构体标识符(也叫结构体类型名) ; struct 语句结束后一定要加分号

    • 代码例子:

      struct student {
      char name[30];
      int age;
      };
      
      
  • C语言中结构体的标识符单独拿出来是没有意义的,只有跟 struct 配合起来才表示一种结构体数据类型。例如:student单独拿出来使用是没有意义的,只有 struct student 才表示一种结构体数据类型。

  • 代码例子:

    sturct date{
    	int birthday_year;
    	int birthday_month;
    	int birthday_day;
    };
    
    struct student{
    	char name[30];
    	struct date birthday;
    	int count;
    };
    
    
    int main(void){
    	struct student s1;
    	struct student s2;
    };
    
  • C语言中不允许出现在结构体内部的包括:

    • 函数(行为类不允许)

    • 静态成员 ( static )

    • 当前结构体类型的成员

      • 如若一定要保存这种类型,就使用指针来定义代替:

        只要是指针,内存就是确定的

    • 当前结构体类型的别名(typedef 起的别名)

  • 简化结构体类型名:

    • 可以通过typedef来简化结构体类型名

      • 形式一:typedef struct student Student;

      • 形式二:

        typedef struct student 
        {
        char name[30];
        int name;
        } Student;
        
        • 区分一:

          struct student {
          	char name[30];
          	int name;
          } Student;
          没有 typedef 则表示定义一个变量
          
        • 区分二:

          struct student {
          char name[30];
          int name;
          } Student[10];
          没有 typedef 且是数组定义方式则表示定义一个数组
          
  • 不同结构体变量之间不允许赋值(类型不相同)

    • 代码例子:

      struct student{
      	char name[30];
      	int age;
      };
      struct teacher {
      	char name[30];
      	int age;
      };
      int main(void){
      	struct student zs;
      	struct teacher ls;
      ls = zs; // 错误,类型不相同不允许赋值
      
      
      return 0;
      }
      

8.2 结构体成员访问

  • 结构体变量访问成员:通过点运算符 . (结构体变量访问成员运算符)来访问结构体变量的成员。

  • 形式:使用结构体定义的变量 . 结构体内的成员

    #include <stdio.h>
    #include <string.h>
    
    struct student {
    	char name[30];
    	int age;
    };
    
    int main(void) {
    	struct student zs;
    	strcpy(zs.name, "zhangsan");
    	zs.age = 17;
    	printf("%d\n", zs.age);
    	puts(zs.name);
    	
    	return 0;
    }
    
  • 结构体指针访问成员:使用运算符 -> (结构体指针访问成员运算符)来访问成员

    • 指针为空为野在于结构体成员是否进行了初始化

    • !!!分清楚什么时候使用箭头进行结构体成员访问,什么时候使用点

8.3 结构体的对齐补齐

  • 结构体成员的对齐

  • 结构体整体的补齐:为系数最小整数倍

  • 设置编译时对齐系数:就是结构体大小须为n的整数倍

    • #pragma pack(n)更改当前对齐系数语句
    • n = 1 、2、 4、8、16 2的整数次幂
  • 结构体成员访问符号都高于取地址符

8.4 共用体(联合体)

  • 共用体:跟结构体很像。结构体中每个成员都有自己的内存空间;共用体的每个成员都是共同使用同一块内存。

  • 一般形式:

    union 标识符{
    	成员类型 成员名;
    	成员类型 成员名;
    }union test{
    	int a;
    	float b;
    }
    • a和b都可以使用这块union的内存;

    • 但是,a使用的时候b是无效的;b使用的时候a是无效的;(无效的变量值被复写掉了)

  • 可以用共用体返回不同类型的数据,因为虽然所有成员使用同一块内存,但是只有最后一个进行赋值的成员起作用

8.5 枚举体

  • 枚举体:如果一种类型,它所有的可能取值都可以枚举出来,那么这种类型就可以定义成枚举类型。例如:一周有几天,人的性别,一年有几个月

  • 一般形式:

    enum 标识符 {枚举值1,枚举值2,枚举值3,……}
    • 由于switch小括号内部只允许出现数值来着,枚举类型的变量内存里面存储的是数字,所以枚举值的真实数值可以直接去指定;
    • 布尔类型:C语言是没有布尔类型的,可以用enum定义一个
    enum boolen {true,false}
    • sex单独拿出来没有意义,只有跟enum一起才有意义;

    • 这种类型变量的赋值只能用枚举的值来进行赋值操作;

    • 但是只能把枚举类型值赋值给整型,不能把整型值赋值给枚举类型

    • 枚举类型的最大特点就是可读性很强;

8.6 动态链表

  • 链表:是一种存储结构,链式存储。数据存储在节点中,每个节点分为数据域(保存数据的)和指针域(指向下一个节点),节点与节点之间通过指针指向串联起来。

  • 链表和数组的区别:

    • 链表(链式存储):擅长进行插入和删除操作,不擅长元素访问

    • 数组(顺序存储):不擅长频繁的进行插入删除操作,擅长元素访问

    • 手动创建一个链表

      • 略 (太多了,需要请留言!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑眼圈子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值