c语言学习第二十九课——自定义类型:结构体与枚举

简介: c语言学习第二十九课——自定义类型:结构体与枚举

结构体

结构体的的声明:

struct tag
{
  member-list;  //结构体成员列表
}variable-list;  //变量列表

这里举例定义一个学生类型的结构体

struct Stu
{
  //成员变量
  char name[20];
  int age;
  int weight;
}s3,s4,s5;//也可以直接创建,这里是全局变量
int main  ()
{
  struct Stu s1;//创建结构体变量 
  struct Stu s2;//这里是局部变量
  return 0;
}

匿名结构体类型

struct   //结构体名,省略掉。
{
  char cl;
  int b;
  double d;
}s1;
struct   
{
  char cl;
  int b;
  double d;
}*p;    //结构体的指针变量

在这里,p = &s1;会报错,类型不兼容。其次建议不要使用该种写法,一次性用品结构体,无法创建新的结构体变量

结构的自引用

在数据结构中,描述数据在内存的存储结构,顺序表,单链表都是线性结构,二叉树,树结构

当一个结构体要包含一个自己一样的结构体,

struct Node//可确定结构体大小
{
  int data;
  struct Node* next;
};

这里只能用该结构体去包含自己的指针,不能直接在结构体在创建本身。

结构体变量的定义和初始化

struct S
{
  int a;
  char c;
}s1;
struct B
{
  float a;
  struct S s;
};
int main()
{
  int arr[10] = {1,2,3};
  struct S s2 = { 100,'q' };
  struct  B sb = { 3.14f,{200,'w'} };//浮点数精确保存
  printf("%f,%d,%c", sb.a, sb.s.c);
  return 0;
}

定义指针类型的

struct S
{
  char name[20];
  int* ptr;
};
int main()
{
  struct S a = { "ABXDEF",NULL };//&+变量
  return 0;
}

结构体的大小

先举例

struct s1
{
  int a;
  char c;
};
struct s2
{
    char c;
  int a;
  char d;
};
struct s3
{
  int a;
  char c;
  char d;
  char e;
};
int main()
{
  printf("%d", sizeof(struct s1));//8
  printf("%d", sizeof(struct s2));//12
  printf("%d", sizeof(struct s3));//12
  return 0;
}

为什么会是这样呢?这里需要求了解关于结构体内存是对齐的知识。先了解结构体是怎样在内存中存放的。

存放规则  1.每一个字节相对起始位置都有一个偏移量,结构体的第一个成员永远被放在0偏移处,对齐数假设从0开始往后。

2.从第二个成员开始,以后每个成员都要对齐到某个对齐数的整数倍数。这个对齐数是:成员自生身大小和默认对齐数中的较小值 备注 vs环境下是8,gcc下没有,默认为自身大小为对齐数。

3.结构体的总大小必须是,所有成员对齐数中最大对其数的整数倍,如果不是,则浪费空间使对齐。

这里举例  struct s2

从这里可以看出,结构体成员的定义顺序会影响其在内存的存放方式

struct _s2
{
  char c;
  char d;
    int  a;
};


787b30064cd94df082d03e230ecf6d0d.png

第四条规则:如果嵌套了结构体,则该结构体只能放在自身最大对其数的整数倍的位置上,整个结构体的大小必须是最大对齐数的整数倍(包含嵌套结构体中最大的对其数)。

struct s3
{
  int a;
  char c;
  char d;
  char e;
  struct s1 s;
};
int main()
{
  printf("%d", sizeof(struct s3));//16
  return 0;
}

设计结构体时,既要满足对齐,又要节省空间

这里提供了可以修改默认对齐数

#pragma pack(8);设置默认对齐数为8

offsetof宏,求该成员与上一个成员的偏移量.

结构体传参

void print2(const struct s* ps)
{
  printf("%d", ps->num);
}

结构体实现的位段

位段的声明和结构是类似的,位段的成员通常为int unsigned int,位段的成员名后边有一个和一个数字

位段表示的意义:给一定的大小空间,结构体成员认为是足够的。

struct A
{
  int _a : 2;//2个比特
  int _b : 5;
  int _c : 10;
  int _d : 30;
};
int main()
{
  struct A sa = { 0 };
  printf("%d\n", sizeof(sa));//8个字节
  return 0;
}

不同的编译器,位段是不一样的。在vs中

struct S
{
  char _a : 3;
  char _b : 4;
  char _c : 5;
  char _d : 4;
};
int main()
{
  struct S s = { 0 };
  s._a = 10;
  s._b = 12;
  s._c = 3;
  s._d = 4;
  return 0;
}

1.分配的内存中比特位是从右向左使用,

2.分配的内存空间不够成员使用时,浪费掉。

  位段是不跨平台的位段的成员可以是 int 、unsigned int、 signed int 或者是 char (属于整型家族)类型

位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的。

位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

枚举

顾名思义。就是列举。把可能的取值一一列举。如星期几,性别等,枚举的用法简单,这里不做赘述。

枚举类型的定义

enum Day
{
  Mon=1,
  Tuse,
  Thus,
  wentu,//枚举常量,可以赋值
  frid,
};
int main()
{
  enum  Day day1 = Mon;
  printf("%d\n", Mon);//打印直接打印
  return 0;
}

枚举可以使代码的可读性增加,便于调试。可定义多个常量。

相关文章
|
21天前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
105 14
|
25天前
|
存储 编译器 C语言
【C语言】结构体详解 -《探索C语言的 “小宇宙” 》
结构体通过`struct`关键字定义。定义结构体时,需要指定结构体的名称以及结构体内部的成员变量。
113 10
|
1月前
|
存储 数据建模 程序员
C 语言结构体 —— 数据封装的利器
C语言结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个整体。它支持数据封装,便于管理和传递复杂数据,是程序设计中的重要工具。
|
1月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
129 13
|
1月前
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
62 11
|
1月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
60 4
|
存储 C语言
【C语言】 条件操作符 -- 逗号表达式 -- []下标访问操作符,()函数调用操作符 -- 常见关键字 -- 指针 -- 结构体
【C语言】 条件操作符 -- 逗号表达式 -- []下标访问操作符,()函数调用操作符 -- 常见关键字 -- 指针 -- 结构体
【C语言】——define和指针与结构体初识
【C语言】——define和指针与结构体初识
|
存储 C语言
C语言初识-关键字-操作符-指针-结构体
C语言初识-关键字-操作符-指针-结构体
66 0
【C语言】指针,结构体,链表
【C语言】指针,结构体,链表