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;
}


这是我当前正在使用的方法,它可以工作,但是我很确定自己做错了一些事(不确定是否应该只是unsigned char **而不是unsigned char *)。

另外,我想删除myCast的typedef,以便将它们全部放在一行上。

最佳答案

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

您可以尝试以几种方式清理代码(“尝试这样做”,因为其中某些效果是有争议的)。


unsigned char删除对retrieveValue()的强制转换,以便编译器可以检查(myCast)是否使用了正确的类型。
使用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,
};

您也可以内联演员表,但这确实是一个品味问题:

inline unsigned char retrieveValue(struct wrapper *wrapper, unsigned short x, unsigned short y) {
    return ((unsigned char (*)[wrapper->width])wrapper->data)[y][x];
}

您可以将演员表封装到一个宏中:

#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];
}

关于c - 2D阵列包装,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23046633/

10-09 06:49
查看更多