2014-04-13 47 views
0

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

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

这是我目前使用的,它的工作原理,但我敢肯定,我做错了一些事情(不知道是否应该仅仅是无符号的char **,而不是无符号的字符*) 。

另外我想删除myCast的typedef,这样我就可以把它全部放在一行上。

+0

你可以拥有你想要的,但初始化会有所不同。 – this

+0

我的初始化有什么问题? – Jimmay

+1

您有不兼容的类型。 – this

回答

0

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

您可以尝试以几种方式清理您的代码(“尝试”),因为其中某些方法的效果存在争议。

  1. retrieveValue()取出投地unsigned char,让你的编译器可以检查是否(myCast)使用正确的类型。

  2. 使用testWrapperData衰变成的类型。这将从Cast中删除外部阵列层以及铸造类型的用法。这与您发布的代码完全相同,因为数组的地址与其第一个元素的地址相同,只是具有不同的类型,导致更多级别的指针衰减。

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