[C 语言笔记--Day07] 如何用 C 语言实作一个泛型物件

大纲

  • 目标
  • 什麽是 union
  • 什麽是 enum
  • 实作一个泛型物件
  • 参考资料

目标

做出一个物件,其可能是 int 或是 double

什麽是 union

unionstruct 的语法非常像,但他们代表的是不一样的意义
考虑以下 C 语言程序码:

union {
    int i;
    double d;
} u;
struct {
    int i;
    double d;
} s;

union ustruct s 在记忆体中的存放方式为:

      s(Structure)                    u(Union)
  +-- +--------+                +--  +--------+ --+   
  |   |        |                |    |        |   |   
  |   +--------+                |    +--------+   |   
  |   |        |                |    |        |   |   
i |   +--------+              i |    +--------+   |   
  |   |        |                |    |        |   |   
  |   +--------+                |    +--------+   |   
  |   |        |                |    |        |   |
  +-- +--------+ --+            +--  +--------+   | d
      |        |   |                 |        |   |
      +--------+   |                 +--------+   |
      |        |   |                 |        |   |
      +--------+   |                 +--------+   |
      |        |   |                 |        |   |
      +--------+   |                 +--------+   |
      |        |   |                 |        |   |
      +--------+   | d               +--------+ --+   
      |        |   |
      +--------+   |
      |        |   |
      +--------+   |
      |        |   |
      +--------+   |
      |        |   |
      +--------+ --+   

union 只可以放 id 择一放一个
例如:

u.i = 82;

这时候 i 的位置就放了 82 进去,而这时候再写:

u.d = 74.8;

原本 i 的值就被盖掉了,整个 u 都被拿来放 74.8
利用这个特性就可以做出泛行的效果,但还必须要用 enum 来纪录他是 int 还是 double 才行

什麽是 enum

enum SUIT {
    CLUBS,
    DIAMONDS,
    HEARTS,
    SPADES
};

其实就跟

#define SUIT        int
#define CLUBS       0
#define DIAMONDS    1
#define HEARTS      2
#define SPADES      3

有一样的效果

实作一个泛型物件

typedef struct {
    enum (INT_KIND, DOUBLE_KIND) kind;
    union {
        int i;
        double d;
    } u;
} Number;

想塞 (int) 82 时:

Number n;
n.kind = INT_KIND;
n.u.i = 82;

想塞 (double) 74.8 时:

Number n;
n.kind = DOUBLE_KIND;
n.u.i = 74.8;

想 print 出来时:

void print_number(Number n)
{
    if (n.kind == INT_KIND)
        printf("%d", n.u.i);
    else if (n.kind == INT_KIND)
        printf("%g", n.u.d);
}

参考资料

C Programming: A Modern Approach, 2/e


<<:  资料呈现与运算处理

>>:  Day 16: 利用Portainer方便管理Docker

Day-12 Multilevel Cache

Multilevel Cache tags: IT铁人 两层以上的城墙 上一次我们提到了Set As...

Day 2 调整照片亮度

调整照片亮度 教学原文参考:调整照片亮度 这篇文章会介绍在 GIMP 使用「亮度 / 对比」、「曝光...

[ 卡卡DAY 6 ] - React Native style 必懂之 Flexbox 弹性盒子(上)

在手机装置中, Flexbox 弹性盒子是一个重点样式 倘若你不懂,就只能躺着被打 orz Rea...

python ModuleNotFoundError

python中引用不同文件夹下面的函数的时候,使用了__init__.py依然没有用,後来发现原因:...

【左京淳的JAVA WEB学习笔记】第四章 转发、重定向、steam输出

转发、重定向与域的概念 之前的章节使用转发(RequestDispatcher),将使用者送往下一个...