首页 > 其他分享 >C:结构体、联合体

C:结构体、联合体

时间:2024-12-06 13:32:12浏览次数:5  
标签:struct int 联合体 char 对齐 变量 结构

结构体

  • 结构体类型的存储区里包含多个子存储区,每个子存储区可以用来记录对应的信息
    • 子存储区(成员变量)可以是不同的数据类型,也可以是结构体类型的
    • 结构体声明语句用来创建结构体类型,需要使用struct关键字
      • 结构体类型名称由关键字struct和结构体名称一起构成
    • 结构体成员变量声明语句不会分配内存,只是用来表示存储区的类型和名称
    • C语言结构体中不可以包含函数
  • 结构体类型可以在头文件里声明
  • 结构体作为数据类型定义变量时,这种变量叫做结构体变量,变量会被分配内存,可以存储数据

typedef关键字

typedef关键字可以用来给数据类型起别名,别名可以提到原来的类型名称使用

/*声明结构体数据类型*/
struct student{
    int age;
    char name[32];
};
/*定义结构体数据类型变量*/
struct student stu1 = {"18","liming"};
/*struct student相当于int的作用,可以使用typedef给struct student起个别名*/
typedef struct student Student;
Student stu2;			//相当于strust student stu2;
stu2.age = 18;
strcpy(stu2.name,"lisi");//需要include <string.h>
printf("age:%d\nname:%s\n",stu2.age,stu2.name);
/*输出结果
cwork$./a.out 
age:18
name:lisi
*/
typedef unsigned int u32;	//给unsigned int起一个别名u32
typedef struct _PERSON{
	char name[64];
	int age;
}Person;					//给struct _PERSON起一个别名Person

void test(){
	u32 val; 		//相当于 unsigned int val;
	Person person;	//相当于 struct PERSON person;
}

结构体和函数

  • 结构体作为参数
    • 可以直接使用结构体类型作为参数向函数中传递数据
      • 直接使用结构体类型的形式参数就会造成时间和空间的浪费
      • 使用结构体指针类型的形式参数可以避免这种浪费
    • 使用结构体指针作为形式参数的适合尽量使用const关键字声明
  • 结构体作为返回值
    • 可以把结构体类型的变量直接作为返回值使用,这样可以从被调用函数向调用函数传递结构体数据
      • 函数的调用过程会发生结构体内容的复制,更会造成时间和空间上的狼覅额
      • 使用结构体存储区的地址作为返回值可以避免这个问题
      • 不可以把非静态局部结构体存储区的地址作为返回值使用,因为函数执行完成后,其中的局部变量就释放了

内存对齐补齐

C语言中的内存对齐(Memory Alignment)是指在内存中分配数据时,将数据放置在特定的地址上,以使得数据的访问更加高效。对齐的规则通常取决于所使用的硬件架构和编译器。

对齐的原因

  1. 提高数据访问速度:许多处理器在访问未对齐的内存时效率较低。对齐的数据可以使得处理器一次访问所需的数据,从而提高性能。
  2. 防止硬件异常:某些处理器在访问未对齐的内存时可能会产生硬件异常或错误。

补齐(Padding)是在结构体或数组等复合数据类型中,为了实现对齐而在数据成员之间或数据成员之后插入的额外字节。补齐通常发生在数据成员的大小和其对齐要求不匹配的情况下。

例如,考虑以下C语言的结构体:

struct Example {  
    char a;      // 1 byte  
    int b;       // 4 bytes  
    short c;     // 2 bytes  
};

假设我们的系统要求 int 类型数据必须 4 字节对齐,那么编译器可能会在 char a 后面插入 3 个字节的补齐,以确保 int b 从 4 字节边界开始。同样地,编译器也可能在 int bshort c 之间插入 2 个字节的补齐,以确保 short c 从 2 字节边界开始。因此,整个 struct Example 的大小可能大于其数据成员大小的总和。

为了避免不必要的内存浪费,程序员通常需要了解其所使用的硬件和编译器的对齐规则,并据此设计数据结构。在某些情况下,可以使用编译器指令或特性来控制对齐行为。

#pragma pack(2),结构体的有效对齐值为pack(n)指定和最大成员长度中较小者;

联合体

  • 联合也是用来创建新的数据类型
    • 联合类型需要先声明才能使用
    • 声明联合类型使用union关键字
    • 联合成员变量对应的存储区在内存里互相重叠
    • 联合成员变量开始的地址都一样
  • 联合变量的大小就是它占用空间最大的成员变量大小
  • 联合变量可以当作多种不同类型变量使用

#include<stdio.h>
int main(){
    typedef union{
        char a;
        short b;
        int c;
    }A_t;
    A_t data = {.c = 0x12345678};
    printf("0x%hhd",data.a);	//输出0x78
    printf("0x%hd",data.b);		//0x5678
    printf("0x%d",data.c);		//0x12345678
    return 0;
}

/*数据传输,计算机接收和发送数据*/
union msg{
	unsigned char msg[48];
    struct cmd{
        unsigned char head[4];
        unsigned char data[40];
        unsigned char tail[4];
    }cmd_info;
}
/*可以用msg来接收数据,然后用cmd_info来读取数据*/

枚举

枚举是一个有限整型常量的列表,每个枚举值都是一个符号常量

默认从0开始,向后依次加一

enum COLOR{RED , GREEN , BLUE , YELLOW};
printf("%d,%d,%d,%d\n",RED,GREEN,BLUE,YELLOW);
/*输出结果为0,1,2,3*/

可以通过赋值改变枚举的值,没有赋值的枚举值 = 前一个枚举值 + 1

enum COLOR{RED , GREEN = 200 , BLUE , YELLOW};
printf("%d,%d,%d,%d\n",RED,GREEN,BLUE,YELLOW);
/*输出结果为0,200,201,202*/

枚举的作用是提高代码可读性

标签:struct,int,联合体,char,对齐,变量,结构
From: https://www.cnblogs.com/one-ten/p/18590586

相关文章

  • 数据结构——图(遍历,最小生成树,最短路径)
    目录一.图的基本概念二.图的存储结构1.邻接矩阵2.邻接表三.图的遍历1.图的广度优先遍历2.图的深度优先遍历四.最小生成树1.Kruskal算法2.Prim算法五.最短路径1.单源最短路径--Dijkstra算法2.单源最短路径--Bellman-Ford算法3.多源最短路径--Floyd-Warshall算法......
  • C:数据类型、控制结构
    基本语法概述C语言程序里大括号可以用来代表函数(函数可以看作一组语句)C语言里每个函数都必须有名字,不同函数的名字不能相同C语言程序必须包含一个叫做main的函数,这个函数叫做主函数(入口函数)程序从主函数的第一条语句开始执行,当主函数里最后一条语句结束后整个程序结束函......
  • 南科大龚欣课题组在ABCA蛋白结构和转运机制模型领域的研究进展
    研究背景ABC转运蛋白(ATP-bindingcassettetransporter)是一类ATP驱动泵,在人类基因组已发现48种,分为7个亚家族(A-G)。ABC转运蛋白由两个跨膜结构域(TMD)和两个胞质侧ATP结合域(NBD)组成。TMD通过构象变化实现分子跨膜转运,NBD结合或水解胞浆中的ATP,确保转运底物所需能量。而在ABCA亚......
  • js的循环结构有哪些?
    JavaScript提供了多种循环结构,用于重复执行代码块。以下是几种常见的循环类型:for循环:这是最常用的循环结构,它允许你根据计数器或条件重复执行代码块。for(leti=0;i<10;i++){console.log(i);//输出0到9}//for循环的三个部分://1.初始化:leti......
  • 【唐叔学算法】第一天:Java常见数据结构
    工欲善其事必先利其器。虽然算法本身是不区分语言的,但是作为专注于Java开发的唐叔,那么善于使用Java自带的已实现的数据结构,将有利于在更短的时间内快速通关具体的算法题。而今天我们就来学习Java中的数据结构实现。善用这些API将有助于我们更有效地存储和处理数据。数组(Ar......
  • 11C++循环结构-for循环(1)——教学
    一、for语句(第27课老狼老狼几点钟)参考1引出问题:当需要重复执行某一语句时,使用for语句。for语句最常用的格式为:for(循环变量赋初值;循环条件;循环变量增值)语句;注:“语句;”就是循环体,可以是一个简单的语句,也可以是一个用“{}”括起来的复合语句。它的执行过程如图示:编......
  • GESP一级必刷题 分支结构 P5713 洛谷团队系统
    【深基3.例5】洛谷团队系统题目描述在洛谷上使用团队系统非常方便的添加自己的题目。如果在自己的电脑上配置题目和测试数据,每题需要花费时间555分钟;而在洛谷团队中上......
  • 深基坑监测位移裂缝水压土压水位降雨量支护结构、锚杆及土钉内力数据采集
    深基坑监测位移裂缝水压土压水位降雨量支护结构、锚杆及土钉内力数据采集基坑监测系统方案监测系统的意义:基坑是基础建设的核心组成部分,它的稳定安全直接关系到上层建筑的稳固性。然而,基坑变形引发的灾害事件时有发生,因此对基坑进行监测和预警变得越来越重要。河北稳控科技充分......
  • 数据结构——编程实现中缀表达式转成后缀表达式
    中缀表达式:运算符在操作数中间例如3+4,3*4后缀表达式:运算符在操作数的后面例如34+,34*计算机在运算时,要把中缀表达式转成前缀表达式(波兰式)或后缀表达式(逆波兰式),因为计算机遍历中缀表达式时的时间复杂度太大举例:3+4*2-2/(1+1)+5=3+8-1+5=15转成后缀表达式为:342*+211......
  • 数据结构实验一
    数据结构实验一2024.12.5采用递增有序的顺序表表示集合,求解两个集合的交集、并集和差集(1)定义顺序表的存储结构;(2)实现存储递增有序集合的顺序表的建立、求交集、并集和差集等运算;(3)要求算法的时间性能在线性时间复杂度内;(4)和采用无序顺序表所表示的集合的有关运算的时间性能......