c语言枚举变量作为函数参数,C语言enum枚举类型、struct结构体类型、union共用体类型用法总结...

本文介绍了C语言中的枚举(enum)、结构体(struct)和共用体(union)的用法。枚举用于定义一组具有命名的常量,结构体用于存储不同类型的数据项,共用体则允许在相同内存位置存储不同类型的值。枚举在STM32编程中常与typedef结合使用,增强可读性和移植性。结构体可以作为函数参数传递,通常使用指针方式提高效率。共用体虽然能节省内存,但需要注意同时赋值多个成员可能导致数据损坏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近日在学习stm32的过程中遇到一些问题,特重新学习了一下C语言关于枚举、结构体、共用体类型的用法,现总结如下>>>

目录

·C枚举类型

基本定义

在stm32中的应用

·C结构体类型

基本定义

初始化

作为函数参数

在stm32中的应用

·C共用体类型

基本定义

内存空间

共用

·C枚举类型

基本定义

首先,在谈enum的用法之前,要了解const的作用,我们知道const是一种定义常量的数据类型,即被定义的量不可改变数值 ,通常是用作为一些数值冠上一个名字,使得代码可读性更好,比如

const int true = 1;

const int false = 0;

switch(result)

{

case true: /* 写入对应函数*/

break;

case false: /*写入对应函数*/

break;

}

或者也可以用宏定义来给常量取名字,但此时常量并没有数据类型,关于const定义与#define宏定义详细的区别,可戳此处https://blog.youkuaiyun.com/just_mccc/article/details/108251183

#define true 1

#define false 0

而如果需要定义的常量数量大且种类繁多,就会显得冗余,代码移植性差,在stm32f10x标准库函数中,有大量不同种类的常量,这时候就需要用到enum枚举类型对常量进行归类。先看一个例子>>>

/*有多种定义形式*/

enum time

{hour, minute = 25, second}now;

enum

{hour, minute = 25, second}now;

enum time

{hour, minute = 25, second};

enum基本用法如上所示,可以有多种形式进行枚举类型定义。time作为枚举类型名字通常并不使用,用的是大括号中的枚举元素,且编译器会将这些元素当作整形常量处理,在数值方面,如果第一个元素没有赋值,会默认为0,后面没有被赋值的元素的数值为前一元素值加1,在取用枚举元素的值时就可以直接使用枚举元素。在赋值方面,枚举元素可以直接赋给int类型变量,但int类型常量不能直接赋给枚举类型变量,需要强制转换才能完成。

printf("The time is %02d : %02d : %02d", hour, minute, second);//直接使用枚举元素

>>>The time is 00 : 25 : 25

/***************************************************/

enum time

{

hour,

minute = 25,

second

};//定义枚举

enum time hour = (enum time)12;//定义一个枚举变量hour并给枚举类型变量赋值

int main(){

printf("hour = %d", hour);//输出结果

return 0;

}

>>>hour = 12;

在stm32中的应用

在stm32中,更多是typedef加枚举的应用,可见下图示例

typedef enum

{ GPIO_Mode_AIN = 0x0,

GPIO_Mode_IN_FLOATING = 0x04,

GPIO_Mode_IPD = 0x28,

GPIO_Mode_IPU = 0x48,

GPIO_Mode_Out_OD = 0x14,

GPIO_Mode_Out_PP = 0x10,

GPIO_Mode_AF_OD = 0x1C,

GPIO_Mode_AF_PP = 0x18

}GPIOMode_TypeDef;

GPIOMode_TypeDef GPIO_Mode;

GPIO_Mode = GPIO_Mode_IPU;

这里用了typedef数据类型定义,使得GPIOMode_TypeDef变成枚举数据类型,并且定义了一个枚举型变量GPIO_Mode,将枚举元素GPIO_Mode_IPU赋值给它,之后就可以直接对GPIO_Mode进行操作了,也是体现了库函数很好的可读性、可移植性。

·C结构体类型

基本定义

C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许存储不同类型的数据项。结构体的定义方法如下

struct tag {

member-list

member-list

member-list

...

} variable-list ;

tag:结构体类型名字(可选择)

member-list:(标准的变量定义)

variable-list:共用体变量(可选择)

也可以用typedef创建新类型,这里用simple1来声明新的结构体变量。

typedef struct

{

int a;

char b;

double c;

}simple1;

simple1 simple2;

初始化

struct结构体标识符 变量名 = {初始化值1,初始化值2…,初始化值n};

例如现在用一本书作为例子,一本书的信息包括书名、页数、作者、主题。于是有如下定义和初始化

struct books

{

int pages;

char author[10];

char subject[50];

};

struct books To_live = {194, "YuHua", "to live"};

作为函数参数

如果想要将一个结构传入函数,可以有以下两种方式实现,一个是传入普通的结构参量,然后再定义一个新的结构体复制传入的结构(与数组不同,两个结构变量可以相互赋值)。这个用法不常用,更多是用结构体指针来传入结构体变量。K&R曾经说过"if a large structure is to be passed to a function, it is generally more efficient to pass a pointer than to copy the whole structure"。由此可见,结构作为指针传入函数是最有效的。详细用法见下面实例

#include

struct books

{

int pages;

char author[10];

char subject[50];

};

/* 函数声明 */

void printBook( struct books *book );

int main( )

{

/* 声明 Book1,类型为 books */

struct books To_live = {194, "YuHua", "to live"};

/* 通过传 《活着》 的地址来输出 Book1 信息 */

printBook( &To_live );

return 0;

}

void printBook( struct books *book )

{

printf( "To_live pages : %d\n", book->pages);//取用结构体成员时,用标识符”->“

printf( "To_live author : %s\n", book->author);

printf( "To_live subject : %s\n", book->subject);

}

输出结果

7bfabaa3f8cfa3a350b2e336cec23079.png

在stm32中的应用

在stm32f10x固件库中,更多的是结构体与枚举的综合运用,下面是关于GPIO模式配置的部分代码

typedef enum

{ GPIO_Mode_AIN = 0x0,

GPIO_Mode_IN_FLOATING = 0x04,

GPIO_Mode_IPD = 0x28,

GPIO_Mode_IPU = 0x48,

GPIO_Mode_Out_OD = 0x14,

GPIO_Mode_Out_PP = 0x10,

GPIO_Mode_AF_OD = 0x1C,

GPIO_Mode_AF_PP = 0x18

}GPIOMode_TypeDef;

typedef struct

{

uint16_t GPIO_Pin;

GPIOMode_TypeDef GPIO_Mode;

}GPIO_InitTypeDef;

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

/*后面是对GPIO_Mode的一系列操作,使单片机执行指令*/

不难看出,这里枚举和结构都是用typedef 来定义一个数据类型定义,这也是为了用户取用代码方便,用户在主函数中定义了一个结构体变量GPIO_InitStructure,并且对结构体成员(也是一个枚举类型)GPIO_Mode进行赋值操作。

·C共用体类型

基本定义

C共用体是一种特殊的数据类型,与结构体类似,但不同的是允许用户在相同的内存位置存储不同的数据类型,我们可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种相同的内存位置的有效方式(即一个变量可以有多个数据类型)即可以赋值不同数据类型的数据,但一次只能赋值一个。首先是共用体的定义

union [union tag]

{

member definition;

member definition;

...

member definition;

} [one or more union variables];

union tag:共用体类型名字(可选择)

member definition:共用体元素(标准的变量定义)

one or more union variables:共用体变量(可选择)

访问公用体成员时需要访问运算符

union Data

{

int i;

char s[20];

double m;

}data;

strcpy(data.str, "Hello_World!");

printf("data.str = %s", data.str);

>>>Hello_World!

内存空间

共用体占用的内存应足够存储共用体中最大的成员。例如,在上面的实例中,Data 将占用 20 个字节的内存空间,因为在各个成员中,字符串所占用的空间是最大的。下面的实例将显示上面的共用体占用的总内存大小:

union Data

{

int i;

char s[20];

double m;

}data;

printf("memory size occupied by data is %d", sizeof(data));

>>>memory size occupied by data is 20

共用

共用体里的所有成员公用一个内存位置,只有在同一时间内只用到一个值,才不会出错

union Data

{

int i;

char s[20];

double m;

}data;

data.i = 10;

printf( "data.i : %d\n", data.i);

data.m = 984.5;

printf( "data.m : %f\n", data.m);

strcpy( data.s, "Hello_World!");

printf( "data.s : %s\n", data.s);

printf("\n");

printf( "data.i : %d\n", data.i);

printf( "data.m : %f\n", data.m);

printf( "data.s : %s\n", data.s);

代码运行结果如下

d15fead0d412cbb0261cc60c0e085ea5.png

可以发现第二次输出的结果有损坏,原因就在于data.s将共用体唯一 一个内存空间给占据了,所以只有data.s输出正确。

详细的共用体用途介绍

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值