c - c中的通用数据类型

标签 c generics unions

我正在用 C 开发一个小型图像处理库。

我想将图像表示为可以具有不同类型的像素数组:uint8_t(对于最大值不超过 255 的像素)、uint16_t(相同但最大值为 65535)、uint32_t..

我暂时要这样做:

typedef struct img8_t {
    unsigned int width, height, depth;
    size_t dsize;
    uint8_t *data;
}img8_t;

typedef struct img16_t {
    unsigned int width, height, depth;
    size_t dsize;
   uint16_t *data;
}img16_t;

typedef struct img32_t {
    unsigned int width, height, depth;
    size_t dsize;
    uint32_t *data;
}img32_t;

dsize 包含像素数据类型的大小

我有相同数量的函数来分配/取消分配和处理这些图像。

有没有一种方法可以定义一个通用的“unsigned int”类型来处理 8 位、16 位等值,而无需为每种情况创建结构/函数?

我应该使用 union 吗?

感谢您的帮助!

最佳答案

Is there a way to define a generic "unsigned int" type that can handle values on 8-bits, 16-bits etc.. without creating a struct/function for each case ?

不,这不符合您的目的。每个完整的 C 数据类型都有一个特定的表示,只有当你有一个完整的类型时,你才能读取或写入对象的值。您当然可以定义一个可以容纳不同大小整数的 union :

union uint_any {
    uint8_t  u8;
    uint16_t u16;
    uint32_t u32;
};

...但是该类型的对象都具有相同的大小,足以容纳最大的成员。因此,一个光栅,比如说,没有任何填充的 16 位像素与 union uint_any 的数组不匹配,至少如果你想通过 u16 成员。


可以使用void * 来指向您的数组,以避免每个像素大小的单独结构,并且您的函数可以在内部对其进行排序,以便每个目的你只需要一个功能。此外,如果您有足够复杂的图像处理函数来保证它,那么您可能会受益于使用宏来减少或消除代码重复。这是一个比可能需要这样处理的更简单的例子:

struct img {
    unsigned int width, height, depth;
    size_t dsize;
    void *data;
};

uint32_t get_pixel(struct img *image, unsigned x, unsigned y) {
    // Warning: evaluates its first argument twice:
    #define GET_PIXEL(i,t,x,y) (((t*)((i)->data))[(x)*((i)->width)+(y)])
    switch (img.dsize) {
        case 8:
            return GET_PIXEL(image, uint8_t, x, y);
        case 16:
            return GET_PIXEL(image, uint16_t, x, y);
        case 32:
            return GET_PIXEL(image, uint32_t, x, y);
        default:
            // handle error ...
    }
    #undef GET_PIXEL
}

关于c - c中的通用数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47781740/

相关文章:

C printf缩进问题

c - C语言中的if else语法错误

generics - 完整、高效的 NumericLiteral 模块实现

JavaFX 绑定(bind)到嵌套列

c - 在c中打开文件并打印到文件

c - 如何修改已传递给 C 函数的指针?

generics - 硬编码与通用编码 : Where to draw the line?

c++ - 使用位域和 union 的意外行为

c++ - 从mat C openCV获取数据

通过 typedef 定义 C++ 新类型