C语言基础(十八)

news2024/11/16 9:18:54

1、共用体(Union)是一种特殊的数据类型,也被称为联合体,它允许在相同的内存位置存储不同的数据类型,每次只能存储其中一种类型的值。共用体是一种数据结构,多个不同类型的变量能够共享同一段内存空间。在C语言中,共用体通过关键字union定义。

主要用途
节省内存:当程序中需要存储多种类型的数据,但同一时间只使用其中一种类型时,可以使用共用体来节省内存空间。因为共用体的总长度等于其成员中最长数据类型的长度,而不是所有成员长度之和。
数据转换:共用体可以用于不同类型数据之间的快速转换,例如,可以将一个整数存储在一个共用体中,然后将其解释为浮点数或字符数组等。
特定场景下的高效操作:在需要处理多种数据类型但每次只处理一种的场景下,如硬件编程、网络通信协议解析等,共用体可以提供高效的数据处理方式。

特别之处
共享内存:共用体的所有成员共享同一段内存空间,在同一时刻,共用体只能存储其成员中的一种类型的数据。
长度特性:共用体的长度等于其成员中最长数据类型的长度。
赋值特性:对共用体中的任一成员赋值都会覆盖该内存位置上的旧值,因此共用体变量中起作用的成员是最后一次被赋值的成员。

定义与声明
共用体的定义和声明方式如下:

union 共用体名 {  
    类型1 成员名1;  
    类型2 成员名2;  
    ...  
    类型N 成员名N;  
};  
  
// 声明共用体变量  
union 共用体名 变量名;
 

测试代码:

#include "date.h"
#include <stdio.h>  
// 定义共用体  
union MyUnion {  
    char c;  
    short s;  
    int i;  
    long long ll;  
};  
  
int main() {
	
	int time = getTime();
	
    union MyUnion myUnion;  
  
    // 初始化共用体的 long long 成员  
    myUnion.ll = 0x123456789ABCDEF0LL;  
  
    // 打印 long long 成员的值,验证初始化  
    printf("long long ll: %lld (0x%llx)\n", myUnion.ll, myUnion.ll);  

    // 检查其他成员的值,它们共享同一段内存。  
    // 这些打印的值将取决于我们如何解释这段内存(即,作为 char、short、int 还是 long long)  
  
    // 打印 char 成员的值(只取最低字节)。  
    printf("char c: %c (0x%x)\n", myUnion.c, (unsigned char)myUnion.c);  
  
    // 打印 short 成员的值(取最低两个字节,注意字节序)。  
    // 假设系统是小端字节序  
    printf("short s: %d (0x%x)\n", myUnion.s, (unsigned short)myUnion.s);  
  
    // 打印 int 成员的值(取最低四个字节,注意字节序)。  
    // 假设系统是小端字节序 。 
    printf("int i: %d (0x%x)\n", myUnion.i, (unsigned int)myUnion.i);  
  
    // 内存布局,打印出每个成员的地址。  
    // 这些地址将是相同的(对于某些编译器和平台,偏移量将是内存对齐的倍数)。  
    printf("Addresses:\n");  
    printf("&myUnion.ll: %p\n", &myUnion.ll);  
    printf("&myUnion.c: %p\n", &myUnion.c);  
    printf("&myUnion.s: %p\n", &myUnion.s);  
    printf("&myUnion.i: %p\n", &myUnion.i);  
    // 由于是共用体的成员,所以它们的地址在逻辑上是相同的。  
    // 编译器会根据类型给出不同的指针类型(比如 char*、short*、int*、long long*)。  
    return 0;  
}

运行结果如下:

...........................................................................................................................................................

2、枚举(Enumeration)是用户定义的类型,允许程序员为整数指定一个更容易理解的名字。枚举类型是一组命名的整型常量,在逻辑上相关,通常用于表示状态、选项或其他类似的集合。

枚举类型的定义使用enum关键字,后跟枚举类型的名称和用花括号括起来的一组枚举常量。每个枚举常量都是一个整数,默认情况下,从0开始,每个后续常量递增1。也可以显式地指定某个枚举常量的值。

测试代码1:

#include "date.h"
#include <stdio.h>  
// 定义一个枚举。  
// 枚举成员的默认值是从0开始的整数序列,也可以在枚举定义中显式指定它们。 
enum days {  
    Sunday,  
    Monday,  
    Tuesday,  
    Wednesday,  
    Thursday,  
    Friday,  
    Saturday  
};  
  
int main() {  

    int time = getTime();
    enum days today;  
      
    // 使用枚举成员直接赋值。  
    today = Tuesday;  
    printf("Today is day %d of the week.\n", today);  
      
    // 直接将int赋给枚举变量,建议使用显式转换让代码更清晰。 
    int dayNumber = 3; // 3代表Wednesday  
    today = (enum days)dayNumber; // 显式转换  
    printf("This day with value %d is %d.\n", dayNumber, today);  
      
    // 直接使用枚举成员。  
    printf("Thursday is %d.\n", Thursday);  
      
    return 0;  
}

运行结果如下:

测试代码2:

#include "date.h"
#include <stdio.h>  
// 定义一个枚举 
enum days {  
    Sunday = 1,  // 显式指定Sunday的值为1  
    Monday = 2,  
    Tuesday = 3,  
    Wednesday = 4,  
    Thursday = 5,  
    Friday = 6,  
    Saturday = 7  
};  
  
int main() {  
    int time = getTime(); 
    enum days today = Wednesday; // today的值为4  
  
    // 打印today的值  
    printf("Today is day %d of the week.\n", today);  
  
    // 使用显式指定的值  
    enum days specialDay = (enum days)6; 
    printf("Special day is %d.\n", specialDay);  
  
    // 使用枚举成员直接比较  
    if (specialDay == Wednesday) {  
        printf("Yes, it's Wednesday!\n");  
    }  else{
    	printf("It's not Wednesday.\n");  
    }
  
    return 0;  
}

运行结果如下:

测试代码3:

#include "date.h" 
#include <stdio.h>  
#include <string.h>  
  
// 定义枚举类型 JobType,包含STUDENT和TEACHER两个值。  
typedef enum { STUDENT, TEACHER } JobType;  
  
// 定义结构体 Person,包含学号、姓名、工作类型、工作类别联合体,以及指向下一个Person结构的指针。  
struct Person {  
    int num;  
    char name[20];  
    JobType job;  
    union {  
        int clas;  
        char position[11]; // +1 for null terminator 。 
    } category; // union 是结构体 Person 的一个成员 。 
    struct Person* next;  
};  
// 定义初始化学生信息的函数 initStudent,设置学号、姓名、工作类型和班级信息,以及将下一个指针置为空。 
void initStudent(struct Person* person, int num, const char* name, int clas) {  
    person->num = num;  
    strcpy(person->name, name);  
    person->job = STUDENT;  
    person->category.clas = clas;  
    person->next = NULL;  
}  
// 定义初始化老师信息的函数 initTeacher,设置工号、姓名、工作类型和职位信息,以及将下一个指针置为空。 
void initTeacher(struct Person* person, int num, const char* name, const char* position) {  
    person->num = num;  
    strcpy(person->name, name);  
    person->job = TEACHER;  
    strcpy(person->category.position, position);  
    person->category.position[10] = '\0'; 
    person->next = NULL;  
}  
  
int main() {  
    int time = getTime();
    // 创建名为student和teacher的结构体实例。 
    struct Person student, teacher;
	// 调用initStudent和initTeacher函数初始化。  
    initStudent(&student, 1, "Alice", 3);  
    initTeacher(&teacher, 2, "Bob", "Professor");  
  
     // 使用条件语句检查学生和老师的工作类型,并打印相应的信息。 
    if (student.job == STUDENT) {  
        printf("Student #%d, Name: %s, Class: %d\n", student.num, student.name, student.category.clas);  
    }  
  
    if (teacher.job == TEACHER) {  
        printf("Teacher #%d, Name: %s, Position: %s\n", teacher.num, teacher.name, teacher.category.position);  
    }  
  
    return 0;  
}

运行结果如下:

测试代码4:

#include "date.h"
#include <stdio.h>  
#include <stdlib.h>  
#include <time.h>  
// 定义一个枚举类型Suit,表示扑克牌的花色 
typedef enum { CLUBS, DIAMONDS, HEARTS, SPADES } Suit;  
// 定义一个结构体Card,表示一张扑克牌,包括rank(点数)和suit(花色)两个成员变量。
typedef struct {  
    int rank;  
    Suit suit;  
} Card;  
// shuffle函数,对一副牌进行洗牌操作,通过随机交换牌的位置洗牌。 
void shuffle(Card deck[], int n) {  
    srand(time(0));  
    for (int i = 0; i < n; i++) {  
        int j = rand() % n;  
        Card temp = deck[i];  
        deck[i] = deck[j];  
        deck[j] = temp;  
    }  
}  
// printCard函数,打印一张扑克牌的点数和花色。 
void printCard(Card card) {  
    switch (card.rank) {  
        case 1:  
            printf("Ace");  
            break;  
        case 11:  
            printf("Jack");  
            break;  
        case 12:  
            printf("Queen");  
            break;  
        case 13:  
            printf("King");  
            break;  
        default:  
            printf("%d", card.rank);  
    }  
  
    switch (card.suit) {  
        case CLUBS:  
            printf(" of Clubs\n");  
            break;  
        case DIAMONDS:  
            printf(" of Diamonds\n");  
            break;  
        case HEARTS:  
            printf(" of Hearts\n");  
            break;  
        case SPADES:  
            printf(" of Spades\n");  
            break;  
    }  
}  
  
int main() {  
    int time = getTime();
    // 创建一个包含52张扑克牌的数组deck
    const int NUM_CARDS = 52;  
    Card deck[NUM_CARDS];  
    // for循环初始化每一张牌的点数和花色。
    for (int i = 0; i < NUM_CARDS; i++) {  
        deck[i].rank = (i % 13) + 1;  
        deck[i].suit = static_cast<Suit>(i / 13);  //显式类型转换。 
        // 打印洗牌前的点数和花色。 
		printCard(deck[i]); 
    }  
    printf("\n");
    // 调用shuffle函数进行洗牌
    shuffle(deck, NUM_CARDS);  
    // 循环打印洗牌后每张牌的点数和花色。 
    for (int i = 0; i < NUM_CARDS; i++) {  
        printf("Card %d: ", i + 1);  
        printCard(deck[i]);  
    }  
  
    return 0;  
}

运行结果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2076420.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenAI推出新功能:GPT-4o正式上线微调功能,限时免费!

GPT-4o正式上线微调功能&#xff0c;限时免费&#xff01; 每个组织每天可以免费获得多达100万个训练token&#xff0c;活动将持续到9月23日。 这意味着开发者们现在可以利用自定义数据集对GPT-4o进行微调&#xff0c;从而以较低的成本构建自己的应用程序。 据悉&#xff0c;G…

推荐3款在Windows系统上运行流畅、音质出众的音乐播放器

foobar2000 Foobar2000是一款由原Winamp开发公司的Peter Pawlowski开发的免费多功能音频播放器&#xff0c;具有高度定制化和丰富的功能。它支持多种音频格式&#xff0c;包括MP3、AAC、WMA、FLAC、WAV等&#xff0c;并且可以进行音频转码和格式转换。此外&#xff0c;Foobar20…

C盘满了,如何清理C盘

目录 磁盘清理删除休眠文件查看系统盘的存储占比卸载掉安装在系统盘的软件更改临时文件、文档等的存储位置 磁盘清理 选择自己的系统盘&#xff0c;我的是G盘。清理系统文件删除休眠文件 删除休眠文件 管理员打开cmd powercfg -h off 直接减少几个g的C盘占用 查看系统盘的存储…

世媒讯海外发稿:全球知名的中文媒体平台

新闻媒体网站专注于媒体行业中各类新闻的网站&#xff0c;也是网友最爱访问的网站类型之一。以下是一些知名的中文媒体平台&#xff0c;它们不仅提供华文内容&#xff0c;还具有较高的访问量和影响力。以下是十大可发布中文新闻稿的知名媒体&#xff0c;包括其月访问量、地区排…

【连续4届EI稳定检索】第五届计算机工程与智能控制学术会议(ICCEIC 2024,10月11-13)

第五届计算机工程与智能控制学术会议&#xff08;ICCEIC 2024&#xff09;将于2024年10月11日至13日在广州举办&#xff0c;聚焦计算机工程与智能控制前沿&#xff0c;涵盖网络安全、硬件系统、软件工程、嵌入式创新等多个核心议题及交叉学科研究。 ICCEIC 2024将计算机工程和智…

QT 程序直接崩溃The program has unexpectedly finished.

QT报错比较难处理&#xff0c;因为给出的控制台输出太宽泛甚至没有信息。 遇到当遇到这种直接崩溃的&#xff0c;试着把一些代码注释掉&#xff0c;慢慢试出出错的位置 。 这里有一种可能的原因是因为有些变量没有初始化&#xff0c;就直接使用。 如下图&#xff1a; 当我运…

【Java】/* 二叉树 - 底层实现*/

一、前序遍历 - 递归 /* 1. 前序遍历 - 递归 */public void preOrder(TreeNode root) {//1. 如果根节点为nullif (root null) {return;}//本意&#xff1a;打印树的根&#xff0c;左&#xff0c;右节点//2. 打印根节点的值System.out.print(root.val " ");//3. 如…

X86 PVE 下安装路由存储系统iStoreOS

简介 iStoreOS是一个比较易用的路由存储系统&#xff0c;它能让你获得更好的网络及 存储的体验。 系统本身开源免费&#xff0c;目前系统代码开源在&#xff1a;Github iStoreOS 下载固件 固件下载&#xff1a;https://fw.koolcenter.com/iStoreOS/x86_64/ istoreos-22.03.7…

数据结构——顺序表和单链表

数据结构 基本概念&#xff1a; 数据结构是一门研究如何有效组织数据&#xff0c;并提高数据处理效率的学科。通过研究各种数据内部的逻辑关系&#xff0c;使用某种特定的存储形式&#xff0c;并在此基础上对数据实施各种操作&#xff0c;这些工作被称为称为广义上的算法。 …

盈利47亿,快手的危机感却没消失

文丨郭梦仪 又是一年互联网大厂的半年报成绩单放榜时&#xff0c;一批主打下沉市场的公司也在从追求高增长&#xff0c;转向了高利润。 8月20日盘后&#xff0c;快手发布了“营利双增”的业绩报告&#xff0c;但显然营收增长远远低于利润的增长。 伴随着与抖音停战&#xff…

选择排序【详解】

本期介绍&#x1f356; 主要介绍&#xff1a;排序中的选择排序。 文章目录 1. 前言2. 选择排序3. 优化选择排序 1. 前言 相信只要接触过C语言的同学都或多或少了解排序问题&#xff0c;其中最基本&#xff0c;且最为人所熟知的排序是&#xff1a;选择排序。下面我会带着大家重新…

深入解读LLaMA-Factory

转自&#xff1a;老朱读AI 1、介绍 LLaMA-Factory是一个开源平台&#xff0c;旨在为研究人员和开发者提供便捷的大型语言模型微调环境。通过LLaMA-Factory&#xff0c;用户可以轻松地加载预训练模型&#xff0c;调整模型参数&#xff0c;并在特定数据集上进行训练&#xff0c…

【Python机器学习】NLP分词——利用分词器构建词汇表(六)——词汇表归一化

目录 大小写转换 词干还原 词形归并 使用场景 词汇表大小对NLP流水线的性能有很大的影响&#xff0c;有一种减少词汇表大小的方法是将词汇表归一化以便意义相似的词条归并成单个归一化的形式。这样做一方面可以减少需要再词汇表中保留的词条数&#xff0c;另一方面也会提高…

记录|Visual Studio中的Git上传下载使用

目录 前言一、前提准备Step1 仓库准备Step2. 本地仓库和远程仓库绑定当前效果展示 二、下载更新内容到本地仓库情形Step1. 下载 三、更新内容&#xff0c;上传文件到远程仓库情形Step1. 下载Step2. 上传当前效果展示 更新时间 前言 这部分是使用过程中的经验 一、前提准备 St…

【数模资料包】最新数模国赛word+latex模版|数模常用的算法python+matlab代码

【2024最全国赛研赛数模资料包】C君珍贵国一数模资料&#xff5c;最新数模国赛wordlatex模版&#xff5c;数模常用的算法pythonmatlab代码 国赛指&#xff1a;高教社杯全国大学生数学建模竞赛&#xff0c;研赛指&#xff1a;华为杯研究生数学建模竞赛。资料内容具体看文末卡片…

【C++算法/学习】位运算详解

✨ 忍能对面不相识&#xff0c;仰面欲语泪现流 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;算法学习 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &…

【Python 千题 —— 基础篇】面积计算(多种图形面积计算)

Python 千题持续更新中 …… 脑图地址 &#x1f449;&#xff1a;⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目描述 题目描述 编写一个面向对象的程序&#xff0c;定义一个基类 Shape 和两个派生类 Circle 和 Rectangle&#xff0c;用来计算不同图形…

原子操作与锁

1 原子性 1.1 CPU缓存 L1、L2&#xff1a;一级缓存、二级缓存&#xff0c;均为核心独有 L3&#xff1a;三级缓存&#xff0c;多个核心共用 多级缓存&#xff0c;弥补CPU与内存速度不匹配的问题 1.2 cache line 缓存进行管理的一个最小存储单元&#xff0c;缓存块 1.3 CPU读…

【xilinx】解决 I/O 时钟布局器错误:CLOCK_DEDICATED_ROUTE 异常示例

问题描述 设备&#xff1a; xcvm1102-sfva784-2HP-iS问题&#xff1a;尽管使用 GCIO 引脚作为时钟&#xff0c;但布局器返回 I/O 时钟错误 错误&#xff1a; <span style"background-color:#f3f3f3"><span style"color:#333333"><code&g…

《机器学习》 贝叶斯分类器 原理、参数讲解及代码演示

目录 一、贝叶斯算法 1、简介 2、贝叶斯算法具有以下特点&#xff1a; 二、贝叶斯原理 1、正向概率&#xff08;先验概率&#xff09; 例如&#xff1a; 2、逆向概率&#xff08;后验概率&#xff09; 3、公式 1&#xff09;实例1 2&#xff09;实例2 • 目标&#x…