繁体   English   中英

2D阵列包装

[英]Wrapper for 2D arrays

我的目标是拥有一个包含指向无符号字符的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数组的访问是通过臭名昭著的数组指针衰减进行的纯指针算法。

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

  1. retrieveValue()删除对unsigned char (myCast) ,以便编译器可以检查(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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM