c-用于2D阵列的包装器



我的目标是有一个结构,它包含一个指向2D无符号字符数组的指针及其宽度和高度,这样我就可以正确地从中检索数据。

#include <stdio.h>
struct wrapper {
    unsigned short width;
    unsigned short height;
    unsigned char ***data;
};
inline unsigned char retrieveValue(struct wrapper *wrapper, unsigned short x, unsigned short y) {
    typedef unsigned char (*myCast)[wrapper->height][wrapper->width];
    return (unsigned char)((*(myCast)(wrapper->data))[y][x]);
}
unsigned char testWrapperData[2][2] = { {0, 1}, {2, 3} };
struct wrapper wrapper = {
    2,
    2,
    (unsigned char ***)testWrapperData,
};
int main(void) {
    printf("%d", retrieveValue(&wrapper, 1, 0));
    return 1;
}

这就是我目前使用的,它有效,但我很确定我做错了一些事情(不确定它是否应该只是无符号字符**而不是无符号字符*)。

此外,我想删除myCast的typedef,这样我就可以在一行中拥有所有内容。

三重指针不是必需的,您可以使用unsigned char*void*。但这几乎是无关紧要的,因为您无论如何都不打算使用声明的指针类型。在任何一种情况下,都不涉及多个级别的指针,存储在wrapper->data中的地址就是2D数组中第一个unsigned char的地址。2D数组的访问是通过臭名昭著的数组指针衰减进行的纯指针运算。

您可以尝试用几种方法清理代码("尝试"是因为其中一些方法的效果是有争议的)。

  1. retrieveValue()中删除对unsigned char的强制转换,以便编译器可以检查(myCast)是否使用了正确的类型。

  2. 使用testWrapperData衰变为的类型。这将从铸造中移除外部阵列层,并移除铸造类型的使用。这与您发布的代码完全等效,因为数组的地址与其第一个元素的地址相同,它只是具有不同的类型,从而导致指针衰减的程度增加。

    inline unsigned char retrieveValue(struct wrapper *wrapper, unsigned short x, unsigned short y) {
        typedef unsigned char (*myCast)[wrapper->width];
        return ((myCast)wrapper->data)[y][x];
    }
    struct wrapper wrapper = {
        2,
        2,
        (void*)testWrapperData,
    };
    
  3. 你也可以内联演员阵容,但这实际上是一个品味问题:

    inline unsigned char retrieveValue(struct wrapper *wrapper, unsigned short x, unsigned short y) {
        return ((unsigned char (*)[wrapper->width])wrapper->data)[y][x];
    }
    
  4. 您可以将转换封装到宏中:

    #define getWrapperData(wrapper) ((unsigned char (*)[(wrapper)->width])(wrapper)->data)
    inline unsigned char retrieveValue(struct wrapper *wrapper, unsigned short x, unsigned short y) {
        return getWrapperData(wrapper)[y][x];
    }
    
#include <stdio.h>
struct wrapper {
    unsigned short width;
    unsigned short height;
    void *data;
};
inline unsigned char retrieveValue(struct wrapper *wrapper, unsigned short x, unsigned short y) {
    typedef unsigned char (*myCast)[wrapper->height][wrapper->width];
    return (*(myCast)wrapper->data)[y][x];
}
unsigned char testWrapperData[2][2] = { {0, 1}, {2, 3} };
struct wrapper wrapper = {
    2,
    2,
    &testWrapperData,
};
int main(void) {
    printf("%d", retrieveValue(&wrapper, 1, 0));
    return 1;
}

相关内容

  • 没有找到相关文章

最新更新