C语言n番战--共用体和枚举(八)

嵌入式之路,贵在日常点滴

                                                                ---阿杰在线送代码

目录

一、共用体

共用体的声明以及访问 

如何理解“共用体的所有成员占用同一段内存” 

共用体的暂用空间的大小

用途:

二、枚举 

三、typedef关键字 


一、共用体

共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。-----菜鸟教程 

结构体和共用体的区别在于:

  • 结构体的各个成员会占用不同的内存,互相之间没有影响;
  • 共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员,具体的理解会在文章后面(如何理解“共用体的所有成员占用同一段内存”)详细解释。 
  • 结构体元素互不影响
  • 共用体赋值会导致覆盖 

共用体的声明以及访问 

先说共用体是怎么声明以及使用的,其实共用体和结构体的定义以及访问方式是一样的,访问共用体的成员,我们使用成员访问运算符(.)。 

如,定义一个名为Test的共用体 

union Test {
    int a;
    double pi;
    char str[20];
};
  • 定义一个共用体变量,与结构体一样可以在定义的时候就直接声明,如声明共用体变量union_a,union_b 
union Test {
    int a;
    double pi;
    char str[20];
}union_a,union_b;
  • 也可以在定义了共用体类型Test后,直接定义一个共用体变量,如 
union Test a,b

如何理解“共用体的所有成员占用同一段内存” 

#include "stdio.h"

struct TestT
{
	int idata;
	char cdata;
	int ddata;
};

union TestU
{
	int idata;
	char cdata;
	int ddata;
};

int main()
{
	struct TestT t1;
	union  TestU u1;
	
	printf("结构体t1的大小是:%d\n",sizeof(t1));
	printf("联合体u1的大小是:%d\n",sizeof(u1));
	
	printf("结构体t1idata:%p\n",&t1.idata);
	printf("结构体t1cdata:%p\n",&t1.cdata);
	printf("结构体t1ddata:%p\n",&t1.ddata);
	
	printf("联合体u1idata:%p\n",&u1.idata);
	printf("联合体u1cdata:%p\n",&u1.cdata);
	printf("联合体u1ddata:%p\n",&u1.ddata);
	
	return 0;
}

结构体t1的大小是:12
联合体u1的大小是:4
结构体t1idata:000000000061FE14
结构体t1cdata:000000000061FE18
结构体t1ddata:000000000061FE1C
联合体u1idata:000000000061FE10
联合体u1cdata:000000000061FE10
联合体u1ddata:000000000061FE10

共用体的暂用空间的大小

共用体的暂用的空间一般稍大于共用体中暂用空间最大的成员所暂用的空间,有一点小绕口,如下面的例子,共用体Test中,成员a暂用4个字节,成员pi暂用8个字节,而成员str暂用20个字节,所以共用体暂用空间应该稍大于成员str的暂用空间,最后通过程序结果可以看到暂用空间为24个字节。对于共用体具体要暂用多少的空间,目前笔者还没用对他进行深入的了解,需要了解的朋友可以查阅其他的资料。

#include <stdio.h>

union Test {
    int a;
    double pi;
    char str[20];
};

int main()
{
    union  Test test;
    printf("sizeof test = %d\n", sizeof(Test));
    return 0;
}

输出结果:sizeof test = 24 

用途:

在数据处理中,需要对同一空间安排不同的用途,使用共同体比较方便

    例:有若干个人员的数据,其中有学生和教师。学生的数据中包括:姓名、号码、性别、职业、班级。教师的数据包括:姓名、号码、性别、职业、职务。要求用同一表格来处理。

    可以看出:学生和老师的数据的项目大多数是相同的,只有一个不同,学生的班级,教师的职位。

#include "stdio.h"

struct Person
{
	char name[32];
	int age;
	char zhiye;
	char addr[32];
	union{
		int class;
		char kemu[12];
	}mes;
};

int main()
{
	struct Person p[2];
	int i;
	
	for(i=0;i<2;i++)
	{
		printf("请输入职业:t代表老师,s代表学生\n");
		scanf("%c",&(p[i].zhiye));
		
		if(p[i].zhiye == 's')
		{
			printf("请输入学生班级:\n");
			scanf("%d",&(p[i].mes.class));
			printf("请输入学生名字:\n");
			scanf("%s",p[i].name);
		}
		else
		{
			printf("请输入老师的科目:\n");
			scanf("%s",p[i].mes.kemu);
			printf("请输入老师名字:\n");
			scanf("%s",p[i].name);
		}
		getchar();
	}
	
	for(i=0;i<2;i++)
	{
		if(p[i].zhiye == 's'){
			printf("学生的名字是:%s,班级是%d\n",p[i].name,p[i].mes.class);
		}
		else{
			printf("老师的名字是:%s,职业是%s\n",p[i].name,p[i].mes.kemu);
		}
	}
	
	return 0;
}

请输入职业:t代表老师,s代表学生
t
请输入老师的科目:
语文
请输入老师名字:

请输入职业:t代表老师,s代表学生
s
请输入学生班级:
3
请输入学生名字:

老师的名字是:周,职业是语文
学生的名字是:李,班级是3 

二、枚举 

  • 枚举是C语言中一种基本数据类型,它可以让数据简洁和易读
  • 定义格式为:
enum 枚举名{元素1,元素2};
  • 为什么要用枚举?
#define MON  1
#define TUE  2
#define WED  3
#define THU  4
#define FRI  5
#define SAT  6
#define SUN  7

例如以上这些代码,看起来很多很复杂,如果用枚举的方式:

enum DAY{MON=1,TUE,WED, THU, FRI, SAT, SUN};

注意:第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。我们在这个实例中把第一个枚举成员的值定义为 1,第二个就为 2,以此类推 

enum nums{a,b,c,d=5,e};

没有指定值的枚举元素,其值为前一元素加1 

  • 枚举变量的定义
enum DAY{MON=1,TUE,WED,THU,FRI};
enum DAY day;
  • 实例
#include <stdio.h>

enum DAY
{
     	 MON=1, TUE, WED, THU, FRI, SAT, SUN
};

int main()
{
    enum DAY day;
    day = WED;
    printf("%d",day);
    return 0;
}

运行结果:

  • 枚举在实例中的运用
#include <stdio.h>
#include <stdlib.h>

int main(){
    enum color { red=1, green, blue };
    enum  color favorite_color;
    printf("请输入你喜欢的颜色: (1. red, 2. green, 3. blue): ");
    scanf("%u", &favorite_color);
    
	switch (favorite_color)
	{
		case red:
			printf("你喜欢的颜色是红色");
			break;
		case green:
			printf("你喜欢的颜色是绿色");
			break;
		case blue:
			printf("你喜欢的颜色是蓝色");
			break;
		default:
			printf("你没有选择你喜欢的颜色");
    }
    return 0;
}

请输入你喜欢的颜色: (1. red, 2. green, 3. blue): 1
你喜欢的颜色是红色 

  • 遍历枚举类型
#include <stdio.h>

enum DAY{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

int main()
{
    // 遍历枚举元素
    for (day = MON; day <= SUN; day++) {
        printf("枚举元素:%d \n", day);
    }
	
	return 0;
}

运行结果:

枚举元素:1
枚举元素:2
枚举元素:3
枚举元素:4
枚举元素:5
枚举元素:6
枚举元素:7 

如果像以下枚举类型不连续,则无法进行遍历 

enum{
    day1,
    day2 = 10,
    day3
};
#include<stdio.h>

enum DAY{MON=1, TUE, WED, THU=6, FRI, SAT, SUN}day;

int main()
{
    for(day=MON;day<=SUN;day++)
	{
        printf("%d\t",day);
    }
    
	return 0;
}

1       2       3       4       5       6       7       8       9 

三、typedef关键字 

给已经有的变量类型起名字 

#include "stdio.h"

typedef unsigned int u8;
typedef int u16;
typedef int arr[10];

struct Test
{
	int data;
	int data2;
};

typedef struct Test T;

typedef struct
{
	int data1;
	int data;
}Demo;

void printInfo(T t)
{
	printf("%d\n",t.data);
}

int main()
{
	arr a;
	a[0] = 10;
	printf("%d\n",a[0]);
	
	struct Test t1;
	t1.data = 100;
	printf("%d ",t1.data);
	
	T t2;
	t2.data = 1000;
	printInfo(t2);
	
	Demo d;
	d.data1 = 999;
	printf("%d ",d.data1);
	
	return 0;
}

10
100 1000
999 

#include "stdio.h"

typedef struct
{
	int num;
	char name[32];
	char sex;
}Person,*pPerson;

void printInfo(Person p)
{
	printf("%d号姐姐:%s %c\n",p.num,p.name,p.sex);
}

void printInfo2(Person *p)
{
	printf("%d号姐姐:%s %c\n",p->num,p->name,p->sex);
}

void printInfo3(pPerson pp)
{
	printf("%d号姐姐:%s %c\n",pp->num,pp->name,pp->sex);
}

int main()
{
	Person p1 = {1,"莉莉",'g'};
	Person p2 = {2,"美美",'g'};
	printInfo(p1);
	printInfo(p2);
	
	pPerson pp1 = &p1;
	pPerson pp2 = &p2;
	printInfo2(pp1);
	printInfo2(pp2);
	
	Person *pp3 = &p1;
	Person *pp4 = &p2;
	printInfo3(pp3);
	printInfo3(pp4);
	
	return 0;
}

1号姐姐:莉莉 g
2号姐姐:美美 g
1号姐姐:莉莉 g
2号姐姐:美美 g
1号姐姐:莉莉 g
2号姐姐:美美 g  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值