我的目标是拥有一个包含指向无符号字符的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/