c语言里,怎样判断共用体union的数据类型?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言里,怎样判断共用体union的数据类型?相关的知识,希望对你有一定的参考价值。

比如我定义了一个共用体
typedef union
int n;
char c;
TElemType;

怎么判断某个TElemType里面的数据到底是int,还是char?

我刚好也在考虑此问题,答案给各位补充完整:

ps:<C语言程序设计现代方法第二版>,该书明确说明。要判断设置的是什么类型的值只有增加标识。

可以这样设计数据结构:

struct mydata
    int setflag;
    union 
        int state;
        char *msg;
     data;
;

mydata 自己设计得数据类型,setflag 标识设置的是哪个成员,从上到下可以从union的第一个成员开始:

如果第一个成员被设置,则setflag的最低位置1,其他位清零;

如果第二个成员被设置则,则setflag的倒数第二位置1,其他位清零;

以此类推,int一般是32位的,union最多可以有32个成员,成员多了可以再扩展标识变量(比如使用64位的long long 类型)。

然后写一套操作函数:初始化mydata,设置成员值,获取当前设置的成员值(可返回具体类型,union的每个成员需要对应一个get),判断当前某个成员被设置,判断当前是否设置过成员值。

自己实现的一套访问函数签名,如下:

//不知道编译器会在setflag中放啥值,这个函数用来把setflag初始化为0
void initiate(struct mydata *ptrdata);
//设置值得时候同时设置标识位
void set(const void *ptrval,int bit);
//成功返回0,失败返回-1,ptrintval指向预先分配的int地址空间
int getstate(int *const ptrintval);
//成功返回指向msg的指针,失败返回NULL
char *getmsg();
//判断当前设置的是哪个成员变量,取值1到32。如果给定的位被设置返回1,否则返回0
int issetmember(int flag);
//判断当前是否设置过成员,setflag=0说明没有设置过返回0,否则设置过返回1
int isset();

//initiate必须先调用,否则后面的判断会有问题。弄得有点像C++或java的类了。

参考技术A 共用体,故名思义,就是int n和char c共同这块内存,根本不存在区分,也无法区分。

比如TElemType t = 0x1234

那么
t.n = 0x1234

t.c = 0x4

程序里你可以用t.n,也可以用t.c

总之,不需要判断是何种类型,也没办法判断
参考技术B 我目前搞不清这样做的必要性和可行性,假设n=0x31,这时c=‘1’,
你说他是int 0x31也就十进制49, 还是字符1呢,显然共用体共用体就是兼而有之嘛,分开来违背了共用体的初衷。也许要从上下文判断吧。本回答被提问者采纳
参考技术C 无论是int还是char,在这个类型的变量中,都是存储了同样的值,这个值(二进制形式)是不区分类型的,只有在使用这些值时,才会进行类型转换。

C语言-枚举共用体

1. 共用体

前面章节学习了结构体,结构体里可以按顺序存放相同或者不同的数据类型,每个成员都有它对应的存储空间。
而共用体和结构体一样也可以按顺序存放相同或者不同数据类型,但是与结构体的区别是,共用体所有成员共用一个存储空间,存储空间由成员中存储空间最大的来决定。

定义共用体的关键字: union

下面通过结构体、共同体两个定义代码对比区别。

结构体定义示例:

struct app

    int a;
    char b;
;

结构体:每个成员是占用独立的空间,结构体成员之间会因为内存对齐产生间隙。

共用体定义示例:

union app

    int a;
    int b;
    char c;
;

**共用体:**也称为联合体,采用内存覆盖技术,每个成员共用一个内存空间,开空间是以最大的成员开空间。 在单片机、嵌入式设备里使用较多。共用体的语法和使用方法(定义、成员变量的访问形式等等)与结构体一样。

共同体案例代码:

#include <stdio.h>
#include <stdlib.h>

union app

    int a;
    int b;
    char c;
;

//匿名方式定义,只能在定义共用体的时候就定义变量
union

    int a;
    int b;
    char c;
a1,a2,a3;  //定义3个变量

union app2

    int a;
    int b;
    char c;
b1,b2;

typedef union app3

    int a;
    int b;
    char c;
c1;  //c1是新的数据类型--union app3的别名

int main()

    b1.a=65;
    b1.b=66;
    printf("%d\\n",b1.a); //66
    printf("%d\\n",b1.b); //66
    printf("%c\\n",b1.c); //66 
    return 0;

2. 枚举

C语言的枚举可以给一串有序的数字集合定义名字,特别是数量较多的整数需要定义名字时,比#define更加方便。特别是定义函数的返回值类型,特别方便,项目开发中,一般标准的函数返回值都有很多种情况,为了方便调用者判断错误类型,可以把这些错误值全部使用枚举定义,这样调用者就能清楚知道每个数值代表的含义。

枚举的定义语法:

enum 枚举名 枚举元素1,枚举元素2,……;

默认成员都是从0开始,如果某一个成员被赋了值,则该成员以后的元素都以此为基础递增。

枚举的定义及用法示例:

#include <stdio.h>
#include <stdlib.h>

#define DEF_VAL 100

//枚举类型
/*
枚举内部的是常量标识符,这些常量标识符就相当于全局变量(声明放在函数之外)
枚举常量只能整型。
默认情况下枚举值是从0开始的,依次递增。
*/
enum app

   a1='A',a2,a3,a4
;

typedef enum app2

   b1='A',b2,b3,b4
type_app2;

//枚举在程序开发中最常用的地方是:表示函数执行的状态值。

int main()

    printf("%d\\n",a1);
    printf("%d\\n",a2);
    printf("%d\\n",a3);
    printf("%d\\n",a4);
    return 0;


type_app2 func1()

    
    return b2;


enum app2 func2()

    return b3;

枚举应用案例2:

#include <stdio.h>
#include <stdlib.h>

//枚举类型
/*
枚举内部的是常量标识符,这些常量标识符就相当于全局变量(声明放在函数之外)
枚举常量只能整型。
默认情况下枚举值是从0开始的,依次递增。
*/
enum app

   a1=0,   //表示OK
   a2,   //第一次空间申请失败
   a3,   //表示第二次空间申请失败
   a4,
   a5,
   a6
;

//枚举在程序开发中最常用的地方是:表示函数执行的状态值。
enum app func();
int main()

    printf("%d\\n",func());
    return 0;


enum app func()

    int *p1=NULL;
    int *p2=NULL;
    p1=malloc(4);
    if(p1==NULL)
    
        return a2; //1
    

    p2=malloc(4);
    if(p2==NULL)
    
        return a3;//2
    
    return a1; //0

以上是关于c语言里,怎样判断共用体union的数据类型?的主要内容,如果未能解决你的问题,请参考以下文章

共用体(union)

C语言-枚举共用体

C语言-枚举共用体

零基础学C语言知识总结八:struct 结构体与 union 共用体

C语言基础:共用体

C语言中怎么判断两个字符串是相同的.