iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言结构体,枚举,联合体如何使用
  • 915
分享到

C语言结构体,枚举,联合体如何使用

2023-07-02 18:07:45 915人浏览 薄情痞子
摘要

本篇内容介绍了“C语言结构体,枚举,联合体如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、匿名结构体struct{ &n

本篇内容介绍了“C语言结构体,枚举,联合体如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、匿名结构体

struct{    char name[20];    int age;}s1;

匿名结构体对象s1过了这一行即销毁。

二、结构体的自引用

1、声明时不要自己引用自己

struct node{ int data; struct Node next;//错误的,严禁自己引用自己};  struct Node{ int data; struct Node* next;//正确的引用方式};

2、结构体重命名时不能使用重命名

typedef struct{ int data; Node* next;//错误的,不要再重命名中使用重命名}Node; typedef struct Node{ int data; struct Node* next;//正确的}Node;

三、结构体内存对齐规则

第一个成员在与结构体变量偏移量为0的地址处。

后续成员变量要放到各自的对齐数的倍数上。对齐数 = 编译器默认对齐数与该成员类型大小的较小值。(vs中默认对齐数是8,GCc没有默认对齐数)

结构体最终大小为最大对齐数的整数倍。

如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

1、结构体内存计算

struct S1{    char c1;    int i;    char c2;};int main(){    printf("%d\n", sizeof(struct S1));    return 0;}

C语言结构体,枚举,联合体如何使用

char c1在结构体变量的零偏移量处分配内存

int i的对齐数为4,所以跳过3个字节,在4的整数倍地址处分配内存

char c2的对齐数为1,使用下一个字节空间即可

目前已使用9字节

由于该结构体中所有成员变量中最大的成员类型大小为4字节,所以最大内存对齐数为4字节,结构体总大小为最大对齐数的整数倍。所以该结构体内存为12字节。

可以使用宏offsetof来观察结构体成员在内存中的偏移量:

C语言结构体,枚举,联合体如何使用

2、结构体嵌套

struct S3//16{ double d; char c; int i;};struct S4//32{ char c1; struct S3 s3; double d;};

char c1在结构体变量的零偏移量处分配内存

struct S3 s3按照其最大内存对齐数(此处为8)进行对齐

double d按照其最大内存对齐数(8)进行对齐

S4的最大内存对齐数为8,所以结构体的最终大小为32

3、通过调整结构体成员顺序,压缩内存

通过上述例子可以发现,结构体成员之间有很大的空间浪费,哪怕是拥有相同结构体成员的两个结构体类型,其在内存中所占据的空间也不相同,所以为了空间的节省,在不影响数据结构的情况下,有目的的把字节占用小的成员变量放在一起,达到节省空间的目的。

四、存在内存对齐的原因

平台原因(移植原因)

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

性能原因(空间换时间)

数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

五、修改默认对齐数

#pragma pack(2)//把默认对齐数改成2struct S{    char c1;    int i;    short c2;};#pragma pack()//恢复默认对齐数为8int main(){    printf("%d\n", sizeof(struct S));    return 0;}#pragma pack(num)修改默认对齐数,该结构体的内存大小由12字节降低为8字节。

默认对齐数尽量为2的次方。

六、结构体传参

结构体传参要传地址。

传址调用优于传值调用的原因是地址占4/8个字节。

但是传值调用参数需要压栈,当结构体过大时,参数压栈的系统开销较大。

七、位段

位段是在结构体中实现的。

位段的成员可以是 int、unsigned int、signed int或者是char类型

位段的空间增长方式为每次增长4个字节(int)或1个字节(char)

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

1、位段在内存中的存储

1位段中char类型的存储方式(vs中舍弃剩余空间)

struct S//占用3个字节{    char _a : 3;    char _b : 4;    char _c : 5;    char _d : 4;};int main(){    printf("%d\n", sizeof(struct S));    struct S s= { 0 };    s._a = 10;//1010,截断为010    s._b = 12;//1100    s._c = 3;//0011    s._d = 4;//0100    return 0;}

C语言结构体,枚举,联合体如何使用

通过调用内存发现,&s中存储的16进制数字为62 03 04,那么可以发现s在内存中的存储方式如下图:

C语言结构体,枚举,联合体如何使用

在vs环境中,char成员变量在单个字节中是倒着存储的(有截断先发生截断),当该字节中剩余的比特位不足以存放下一个完整的成员变量时,会将剩余的比特位舍弃。

2位段中int类型的存储方式(vs中利用剩余空间)

struct A//占4个字节{    int a : 2;    int b : 3;    int c : 4;};int main(){    struct A s = { 0 };    s.a = 12;//1100,截断为00    s.b = 13;//1101,截断为101    s.c = 14;//1110    return 0;}

C语言结构体,枚举,联合体如何使用

通过调用内存发现,&s中存储的16进制数字为d4 01 00 00,那么可以发现s在内存中的存储方式如下图:

C语言结构体,枚举,联合体如何使用

在vs环境中,int成员变量在单个字节中是倒着存储的(有截断先发生截断),当该字节中剩余的比特位不足以存放下一个完整的成员变量时,会将继续存储,存不下的二进制位将存放至下一个字节的右侧。

注意:位段冒号后面的数字只能小于等于类型大小(例如char a:9是错误的)

2、位段的跨平台问题

int 位段被当成有符号数还是无符号数是不确定的。

位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机器会出问题。

位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。

当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位还是利用,这是不确定的。

八、枚举

1、枚举的定义

enum color{    RED,//枚举常量    BLUE,    YELLOW};

不赋值那么默认从0开始,后续枚举成员的值递增1

enum color{    RED=1,    BLUE,    YELLOW};

只需要对第一个成员进行赋值,后续枚举成员的值递增1

在写枚举成员的时候建议全大写,博主在写通讯录枚举了exit,使用时vs提示该命名和exit函数冲突。

2、枚举的优点

增加代码的可读性和可维护性

枚举使用时有类型检查,#define定义的标识符没有

防止了命名污染(封装)

便于调试(#define定义宏在预处理时是直接替换)

使用方便,一次可以定义多个常量

九、联合体(共用体)

联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块空间(所以联合也叫共用体)。

1、联合体大小的计算

#include <stdio.h>uNIOn un{    char arr[5];    int a;}u;int main(){    printf("%d", sizeof(u));//8    return 0;}

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

最大内存对齐数的整数倍要大于等于最大成员的大小。

(这里最大成员是arr,占5个字节,最大内存对齐数是4,所以需要为祖国联合体开辟8个字节空间)

2、使用联合体判断计算机的大小端字节序

#include <stdio.h>union un{    int m;    char n;}u;int check_sys(){    u.m = 1;    return u.n;} int main(){    int a = check_sys();    if (a == 1)        printf("小端存储\n");    else        printf("大端存储\n");    return 0;}

“C语言结构体,枚举,联合体如何使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: C语言结构体,枚举,联合体如何使用

本文链接: https://www.lsjlt.com/news/343636.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言结构体,枚举,联合体如何使用
    本篇内容介绍了“C语言结构体,枚举,联合体如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、匿名结构体struct{ &n...
    99+
    2023-07-02
  • C语言结构体,枚举,联合体详解
    目录1.什么是结构体、枚举、联合体2.定义结构体2.1 包含结构体成员变量、variable2.2 tag、结构体成员变量2.3 用结构体声名变量2.4 用typedef 创建新类型...
    99+
    2024-04-02
  • 详解C语言结构体,枚举,联合体的使用
    目录一、匿名结构体二、结构体的自引用1、声明时不要自己引用自己2、结构体重命名时不能使用重命名三、结构体内存对齐规则1、结构体内存计算2、结构体嵌套3、通过调整结构体成员顺序,压缩内...
    99+
    2024-04-02
  • C语言自定义类型详解(结构体、枚举、联合体和位段)
    目录前言一、结构体1、结构体类型的声明2、结构体的自引用3、结构体变量的定义和初始化4、结构体内存对齐5、结构体传参二、位段1、位段的定义 2、位段的内存分配3、位段的应用...
    99+
    2024-04-02
  • C语言自定义类型超详细梳理之结构体枚举联合体
    目录一、什么是结构体1.结构体实现2.匿名结构体类型3.结构体自引用4.结构体的内存对齐5.结构体位段 二、什么是枚举1.枚举类型的定义2.枚举的优点三、联合(共用体)1.什么是联合...
    99+
    2024-04-02
  • C语言枚举与联合体深入详解
    目录前言枚举枚举的定义枚举的使用枚举的优点联合(共用体)联合体的定义联合体的特点联合体大小的计算总结前言 在C语言中,有三个自定义类型——结构体,枚举,联合,...
    99+
    2024-04-02
  • C语言中联合体与共用体和枚举使用语法示例
    目录联合体/共用体-union枚举-enum联合体/共用体-union 声明联合体的语法格式typedef union 联合体名 {数据类型 成员名1;...
    99+
    2022-12-26
    C语言联合体 C语言共用体 C语言枚举
  • Android NDK开发(C语言--联合体与枚举)
    目录1.联合体1.1定义共用体1.2共用体占用的内存应足够存储共用体中最大的成员。1.3联合变量任何时刻只有一个变量存在,最后一次赋值有效1.4JNI头文件中的联合体2.枚举1.联合...
    99+
    2024-04-02
  • C语言自定义数据类型的结构体、枚举和联合详解
    结构体基础知识 首先结构体的出现是因为我们使用C语言的基本类型无法满足我们的需求,比如我们要描述一本书,就需要书名,作者,价格,出版社等等一系列的属性,无疑C语言的基本数据类型无法解...
    99+
    2024-04-02
  • c语言中如何自定义结构体、位段和枚举
    这篇文章主要介绍了c语言中如何自定义结构体、位段和枚举的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇c语言中如何自定义结构体、位段和枚举文章都会有所收获,下面我们一起来看看吧。结构体类型创建:struct St...
    99+
    2023-06-17
  • C语言中枚举和联合体的示例分析
    这篇文章主要介绍了C语言中枚举和联合体的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。枚举什么是枚举?顾名思义,就是一一列举,把所有的情况,所有的取值,一一列举出来。...
    99+
    2023-06-25
  • C语言中枚举与联合体的使用方法(enum union)
    目录enum的定义 enum对比#define宏常量的好处 union的定义 联合体大小的计算 联合体配合算大小端的问题 总结enum的定义 枚举顾名思义就是一一列举,把...
    99+
    2024-04-02
  • C语言深入探究自定义类型之结构体与枚举及联合
    目录1.结构体1.1结构体类型的声明1.2结构的自引用1.3结构体变量的定义和初始化1.4结构体内存对齐1.5结构体传参1.6结构体实现位段(位段的填充&可移植性)2.枚举2...
    99+
    2024-04-02
  • C语言中的自定义类型之结构体与枚举和联合详解
    目录1.结构体1.1结构的基础知识1.2结构的声明1.3特殊的声明1.4结构的自引用1.5结构体变量的定义和初始化1.6结构体内存对齐1.7修改默认对齐数1.8结构体传参2.位段2....
    99+
    2024-04-02
  • C语言超详细讲解结构体与联合体的使用
    目录结构体offsetof-宏位段枚举联合体(共用体)结构体 结构体内存对齐问题: 当我们在计算结构体的大小时,我们便需要清楚的知道结构体内存对齐是什么。 存在内存对齐的原因可细分为...
    99+
    2024-04-02
  • C++中的结构体和枚举怎么使用
    本篇内容主要讲解“C++中的结构体和枚举怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++中的结构体和枚举怎么使用”吧!1、结构体(struct)的使用使用struct定义一个结构:s...
    99+
    2023-06-17
  • 怎么在C语言中自定义结构体和枚举
    这篇文章将为大家详细讲解有关怎么在C语言中自定义结构体和枚举,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。C语言是什么C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发,使...
    99+
    2023-06-14
  • C语言结构体如何使用
    本文小编为大家详细介绍“C语言结构体如何使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言结构体如何使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。本质一些值的集合。简单使用#include ...
    99+
    2023-06-30
  • c语言结构体和联合体的区别是什么
    结构体和联合体在C语言中都是用来存储多个不同类型的数据的数据结构,但它们之间有一些重要的区别: 结构体(struct):结构体中的...
    99+
    2024-03-15
    c语言
  • C语言中结构体如何使用
    今天就跟大家聊聊有关C语言中结构体如何使用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、关于结构体在C语言中,结构体(struct)指的是一种数...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作