C语言-----自定义类型-----结构体&枚举&联合

简介: C语言-----自定义类型-----结构体&枚举&联合

结构体和数组一样,都是一群数据的集合,不同的是数组当中的数据是相同的类型,但是结构体中的数据类型可以不相同,结构体里的成员叫做成员变量

结构体类型是C语言里面的一种自定义类型,我们前面已经了解到过int,char,float,double等数据类型,结构体也是一种数据类型,而且是使用者自己定义的数据类型,用法如下:

1.结构体类型的声明

struct stu
{
   char name[20];
   int age;
   char sex;
};

2.结构体变量的创建和初始化

结构体变量.结构体成员------对应的参数进行打印

struct stu
{
   char name[20];
   int age;
   char sex;
};
struct stu t={"小明",15,"男"};
struct stu
{
   char name[20];
   int age;
   char sex;
}s1={"小明",15,"男"};
//这种是在声明结构体同时定义变量
//也可以额外定义
struct stu s1={"小明",15,"男"};
struct stu s1={.name="小明",.age=15,.sex="男"};//这种可以不按照顺序

3.结构体传参

#include<stdio.h>
struct  s
{
  int num;
};
    struct s t = 100;
void print1(struct s t)
{
  printf("%d\n", t.num);
}
void print2(struct s *p)
{
  printf("%d\n", p->num);
}
int main()
{
  print1(t);
  print2(&t);
  return 0;
}

这里给出了传值,传地址两种方式,当参数较大时候,传参时候压栈会使得系统在时间空间的开销过大,所以尽量使用传地址的形式;

4.结构的自引用

一个结构体里面不能够包含一个相同的结构体,但是我们可以使用结构体指针,线性数据结构包括顺序表和链表,顺序表就是按照一定的顺序依次排列的结构,链表就是像链子一样串连起来的结构,链表包括数据域和指针域,数据域用来储存相应的数据,指针域便于找到下一个数据;

struct Node
{
   int time;
   struct Node* next;
};
//这种引用的方法是正确的,如果不使用指针,我们无法计算结构体的大小,所以们我们用结构体指针
typedef struct
{
   int time;
   Node* next;
}Node;
//这个是对匿名结构体的重新命名,这种写法是错误的因为Node没有定义就是用了Node*

5.结构体的大小--内存对齐现象

(1)结构体的第一个成员对齐到结构体变量起始偏移量是0的地方

(2)对齐数是编译器的默认对齐数8和结构体成员变量的较小值

(3)结构体的总大小是最大对齐数的整数倍,最大对齐数是所有成员对齐数的最大值

(4)结构体嵌套结构体的时候,嵌套的结构体成员对齐到自己成员最大对齐数的整数倍,整个结

构体的大小就是所有结构体成员最大对齐数的整数倍(把内置的嵌套结构体也当作一个结构体成

员);

(5)根据结构体的对齐规则,我们应该尽量让小的结构体成员放在一起,大的结构体成员放在一

起,这样就可以节省时间和空间;

6.结构体实现位段功能

(1)位段中的位是指二进制位,一个二进制位是一个比特,举个例子:int a:2;正常情况下,一个整型a

要占4个字节,也就是32个比特位,但是我们只为他分配2个比特位来存放数据,2的二进制表示是

0020,2个比特位就存放后两位20,这样就节省了6个比特位,由此可见,位段就是为了节省内存

空间,但是位段不具有跨平台性;

(2)位段有时候几个成员共同使用1个字节,所以不能对他直接取地址,所以应该定义变量,对变

量输入一个值,然后将这个变量的值赋值给结构体的成员;

8.枚举

枚举就是把可能的值一一列举,比如一周有7天

枚举类型的使用,当然,我们在使用的时候可以给枚举常量赋值;

9.联合体(共用体)

联合体的成员共同使用一块内存空间,一起使用的时候会影响彼此的数值,所以联合体的使用条件就是联合体的成员不会同时使用,互不影响;

这个案例是使用匿名联合体判断机器是大端还是小端;

10.联合体的大小

联合体的大小至少是最大成员的大小;

但是通过上面这个案例,我们可以知道联合体也有对齐现象,char是5个1,int是4;但是满足最大对齐数4的整数倍,所以是8;

相关文章
|
27天前
|
存储 C语言
如何在 C 语言中实现结构体的深拷贝
在C语言中实现结构体的深拷贝,需要手动分配内存并逐个复制成员变量,确保新结构体与原结构体完全独立,避免浅拷贝导致的数据共享问题。具体方法包括使用 `malloc` 分配内存和 `memcpy` 或手动赋值。
36 10
|
27天前
|
安全 编译器 Linux
【c语言】轻松拿捏自定义类型
本文介绍了C语言中的三种自定义类型:结构体、联合体和枚举类型。结构体可以包含多个不同类型的成员,支持自引用和内存对齐。联合体的所有成员共享同一块内存,适用于判断机器的大小端。枚举类型用于列举固定值,增加代码的可读性和安全性。文中详细讲解了每种类型的声明、特点和使用方法,并提供了示例代码。
24 3
|
27天前
|
存储 大数据 编译器
C语言:结构体对齐规则
C语言中,结构体对齐规则是指编译器为了提高数据访问效率,会根据成员变量的类型对结构体中的成员进行内存对齐。通常遵循编译器默认的对齐方式或使用特定的对齐指令来优化结构体布局,以减少内存浪费并提升性能。
|
1月前
|
编译器 C语言
共用体和结构体在 C 语言中的优先级是怎样的
在C语言中,共用体(union)和结构体(struct)的优先级相同,它们都是用户自定义的数据类型,用于组合不同类型的数据。但是,共用体中的所有成员共享同一段内存,而结构体中的成员各自占用独立的内存空间。
|
1月前
|
存储 C语言
C语言:结构体与共用体的区别
C语言中,结构体(struct)和共用体(union)都用于组合不同类型的数据,但使用方式不同。结构体为每个成员分配独立的内存空间,而共用体的所有成员共享同一段内存,节省空间但需谨慎使用。
|
1月前
|
编译器 C语言 C++
C语言结构体
C语言结构体
28 5
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
34 3
|
11天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
27 6
|
1月前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
36 10
|
25天前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。