五分钟搞懂C++结构体、联合体、枚举的用法和区别

一、 结构体的声明

1.结构的基础知识

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。

2.结构的声明

struct tag
{
member-list;
}variable-list;

例如描述一个学生:
typedef struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
}Stu;//分号不能丢

3.结构成员的类型

结构的成员可以是标量、数组、指针,甚至是其他结构体。

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

struct Point
{
int x;
int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//初始化:定义变量的同时赋初值。
struct Point p3 = {x, y};
struct Stu //类型声明
{
char name[15];//名字
int age; //年龄
};
struct Stu s = {“zhangsan”, 20};//初始化
struct Node
{
int data;
struct Point p;
struct Node* next;
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

二、结构体成员的访问

结构体变量访问成员
结构变量的成员是通过点操作符 . 访问的。点操作符接受两个操作数。
struct S s;
strcpy(s.name, “zhangsan”);//使用.访问name成员
s.age = 20;//使用.访问age成员
结构体指针访问指向变量的成员
有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针。
struct Stu
{
char name[20];
int age;
};
void print(struct Stu* ps)
{
printf(“name = %s age = %d\n”, (*ps).name, (*ps).age); //使用结构体指针访问指向对象的成员
printf(“name = %s age = %d\n”, ps->name, ps->age);
}
int main()
{
struct Stu s = {“zhangsan”, 20};
print(&s);//结构体地址传参
return 0;
}

三、 结构体传参

struct S
{
int data[1000];
int num;
};
struct S s = {{1,2,3,4}, 1000};
//结构体传参
void print1(struct S s)
{
printf(“%d\n”, s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
printf(“%d\n”, ps->num);
}
int main()
{
print1(s); //传结构体
print2(&s); //传地址
return 0;
}
如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。
结论: 结构体传参的时候,要传结构体的地址。

二、联合体

联合体的声明和结构体类似,但他的行为却和结构体不同。联合体所有成员引用的是内存中相同位置。当你想在不同时刻把不同东西存在同一个位置时可以使用联合体。
看一个简单的例子。

union {
	float f;
	int i;
}fi;

fi.f = 3.14159;
printf("fi.i = %d\n", fi.i);

在一个浮点型和整形都是32位的机器上,变量fi只占据内存中一个32位字,当f被使用时,这个字就作为浮点型值被访问;单i被使用时,这个字就作为整形值被访问。简单说就是同一块内存,被翻译成不同类型的数据,如何翻译取决于定义的数据类型。
上面程序运行结果。

fi.i = 1078530000
联合体的作用
为什么使用联合体,当你只想看浮点型数如何存储在一种特定的机器上,但对其他类型不感兴趣时,联合体可能适合你。看一个例子。

BASIC需要记住程序使用的变量值,他提供了几种不同类型的变量。每个变量的类型必须和他的值一起存储。这里定义了一个结构用来存储这种信息,但是效率并不高。

struct VARIABLE{
	enum {INT, FLOAT,STRING} type;
	int   int_value;
	float  float_value;
	char    *string_value;
};

当BASIC程序中一个变量被创建时,就创建一个这种类型的结构用来记录变量的类型,根据变量的类型,把变量的值存储在三个字段中的一个。这个结构的低效之处在于,每次都有两个字段被浪费,因为一个变量只有一种数据类型。
联合可以减少这种浪费,把三个字段存储在同一块内存区域并不会产生冲突,在某个时刻,联合中只有一个字段会被使用。

struct VARIABLE {
	enum { INT, FLOAT, STRING} type;
	union {
		int    i;
		float  f;
		char   *s;
	}value;
};

如果联合体的各个成员具有不同的变量,联合的长度等于最长成员的长度。

在一个成员长度不同的联合体里,分配给联合体的内存数量取决于最大成员长度。如果这些成员长度相差悬殊,当存储长度较短成员时会浪费内存,在这种情况下更好的方法是在联合体重存储指向不同成员的指针,而不是存储成员本身。所有指针的长度都是相同的,这样就解决内存浪费的问题。当决定存储那个成员时,分配正确数量的内存来存储该成员。

联合的初始化
联合变量可以被初始化,但这个初始值必须是联合的第一个成员的类型,而且它必须位于一对花括号内。例如,

union {
int a;
float b;
char c[4];
}x = {5};
x.a 初始化为5.
我们不能把这个变量初始化为一个浮点型或者字符值。如果给出的类型是任何其他类型的值,会被强制转化为整型并赋值给x.a。

枚举类型

一、 基本概念

枚举enum就是英文enumerate的缩写,也就是列举、排列说明的意思。枚举类型是C语言中的一种特殊类型,枚举类型可以让我们的程序使用一些固定长度和固定数值的变量值范围。定义枚举类型:enum 枚举类型 {枚举值列表};

二、枚举类型的使用

1、定义枚举类型

//枚举颜色
enum color{red=1, oreange=2, yellow=3, green=4, ching=5, blue=6, purple=7};

//枚举一个星期的每一天
enum week
{
Su, Mo, Tu, We, Th, Fr, Sa
};

//枚举每一个月
enum month
{
January, February, March, April, May, June, July, August, September, October, November, December
};
这样枚举出来的都是一推变量,引用时:

printf(“%-3d %-3d %-3d %-3d %-3d %-3d %-3d”, red, oreange, yellow, green, ching, blue, purple);
也就是直接使用,会直接输出对应的值。

2、定义枚举类型的变量

enum week a, b, c;
a = Su;
b = Mo;
c = Tu;

enum month d, e, f;
d = January;
e = February;
f = March;

3、调用枚举类型变量

每周的日期和每月份的输出也是这样:

enum week a, b, c;
a = Su;
b = Mo;
c = Tu;
printf(“%d %d %d\n”, a, b, c);
enum month d, e, f;
d = January;
e = February;
f = March;
printf(“%d %d %d\n”, d, e, f);

4、如果在定义枚举类型时指定元素的值,也可以改变枚举元素的值

例如:
enum weekday{sun=7,mon=1,tue,wed,thu,fri,sat}day;
这时,sun 为 7,mon 为 1,以后元素顺次加 1,所以 sat 就是 6 了。

5、枚举值可以用来作判断

例如:
if (day==month) {…}
if (day>month) {…}
枚举值的比较规则是:按其在说明时的顺序号比较,如果说明时没有人为指定,则第一个枚举元素的值认作 0。

6、一个整数不能直接赋给一个枚举变量,必须强制进行类型转换才能赋值

三、枚举案例

#include <stdio.h>
void main()
{
enum weekday {sun,mon,tue,wed,thu,fri,sat} day;
int k;
printf(“请输入0到6的数:”);
scanf(“%d”,&k);
day=(enum weekday)k;

switch(day) 
{ 
	case sun: printf("sunday\n");break; 
	case mon: printf("monday\n");break; 
	case tue: printf("tuesday\n");break; 
	case wed: printf("wednesday\n");break; 
	case thu: printf("thursday\n");break; 
	case fri: printf("friday\n");break; 
	case sat: printf("satday\n");break; 
	default: printf("input error\n");break; 
} 

}
输入0-6中的一个数字,能够输出对应的星期。

总结

结构体,联合体(共用体),枚举类型在c++开发中用到的不多,毕竟c++是面向对象,直接就用类对象了;这三种自定义类型用的多的地方就是我们学嵌入式的同学们啦,当我们配置一些外设的时候,不都是先定义一个结构体吗 ,具体的属性就要用到共用体和枚举类型了,对于内存有限的MCU我们就要考虑内存的问题了,这就是共用体和枚举类型的优势了;

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中,有多种数据类型可以用来存储不同类型的数据。以下是一些常见的C++数据类型及其用法: 1. 整数类型: - `int`:用于存储整数值,通常占用4个字节。例如:`int num = 10;` - `short`:用于存储短整数值,通常占用2个字节。例如:`short age = 25;` - `long`:用于存储长整数值,通常占用4个字节。例如:`long population = 1000000L;` - `long long`:用于存储更长的整数值,通常占用8个字节。例如:`long long bigNum = 1234567890LL;` 2. 浮点数类型: - `float`:用于存储单精度浮点数值,通常占用4个字节。例如:`float pi = 3.14f;` - `double`:用于存储双精度浮点数值,通常占用8个字节。例如:`double distance = 10.5;` - `long double`:用于存储扩展精度浮点数值,占用字节数较大。例如:`long double price = 9.99L;` 3. 字符类型: - `char`:用于存储单个字符,通常占用1个字节。例如:`char letter = 'A';` - `wchar_t`:用于存储宽字符,根据实现不同可能占用2或4个字节。例如:`wchar_t ch = L'中';` 4. 布尔类型: - `bool`:用于存储布尔值,只有两个取值true和false。例如:`bool isTrue = true;` 5. 空类型: - `void`:表示没有值,常用于函数返回类型。例如:`void printMessage() { ... }` 此外,C++还支持指针、数组、结构体联合体枚举等派生数据类型,可以根据需要选择合适的数据类型。要正确使用这些数据类型,可以进行变量的声明和初始化,并根据需要进行相应的操作和运算。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值