2D阵列的包装

时间:2014-04-13 18:28:14

标签: c arrays pointers multidimensional-array

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

#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,以便我可以将它全部放在一行。

2 个答案:

答案 0 :(得分:0)

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

您可以尝试以多种方式清理代码(“尝试”,因为其中一些影响是有争议的。)

  1. unsigned char移除强制转换为retrieveValue(),以便您的编译器可以检查(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];
    }
    

答案 1 :(得分:-1)

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