【问题标题】:Wrapper for 2D arrays二维数组的包装器
【发布时间】:2014-05-27 14:50:36
【问题描述】:

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

#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 以便我可以将所有内容放在一行中。

【问题讨论】:

  • 你可以拥有你想要的,但初始化会有所不同。
  • 我的初始化有什么问题?
  • 你有不兼容的类型。

标签: c arrays pointers multidimensional-array


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:
    #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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-09
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      相关资源
      最近更新 更多