包含指向其他结构的指针的Struct

时间:2013-11-14 18:47:19

标签: c pointers struct

我试图创建一个结构,其中包含多个结构点,因为我有一个程序读取img文件,并且根据这个文件是16,24或32位,我想这样对待它。当我尝试使我的pixelpointer指向其他结构之一时出现问题(“当从类型'Pixel24'分配类型'Pixel'时,”不兼容的类型“)。我真的不知道如何使这项工作,所以我真的需要一些帮助。

我还想在打开文件时检查特定的文件扩展名,如果它是正确的文件扩展名我只想处理它,但我不知道如何做到这一点。

typedef struct pixel16 {
    uint8_t R, G, B;
}__attribute__((packed)) Pixel16;

typedef struct pixel24 {
    uint8_t R, G, B;
}__attribute__((packed)) Pixel24;

typedef struct pixel32 {
    uint8_t R, G, B, A;
}__attribute__((packed)) Pixel32;


typedef struct pixel{
    Pixel16 pixel16;
    Pixel24 pixel24;
    Pixel32 pixel32;
}__attribute__((packed)) Pixel;

typedef struct file{
    Header *imageHeader;
    Pixel *imageData;
}File

void something(File file){
   Pixel *pixelptr;

    if(file->imageHeader.pixelDepth == 16)
        *pixelptr = file->imageData->pixel16;
    else if(file->imageHeader.pixelDepth == 24)
        *pixelptr = file->imageData->pixel24;
    else
        *pixelptr = file->imageData->pixel32;
}

2 个答案:

答案 0 :(得分:1)

您可以使用联合:

typedef struct {
    int depth;
    union {
        Pixel16 p16;
        Pixel24 p24;
        Pixel32 p32;
    } data;
} Pixel;

if (pixel.depth == 16)
    pixel.data.p16 = ...;
else if (pixel.depth == 24)
    pixel.data.p24 = ...;
else if (pixel.depth == 32)
    pixel.data.p32 = ...;

联盟允许您访问其任何一个字段,同时仅占用最大成员的存储空间。

对于扩展部分,您可以使用strrpbrk()从结尾扫描字符串,直到第一个点或目录分隔符。

ext = strrpbrk(path, "./");

if (!ext || *ext != '.')
    ; /* No extension found. */

if (!strcmp(ext, ".png")
    ...
else if (!strcmp(ext, ".bmp")
    ...
else
    ... /* Unknown extension. */

答案 1 :(得分:0)

我会使用工会和结构的混合物:

typedef struct pixel16 {
    uint8_t R, G, B;
}__attribute__((packed)) Pixel16;

typedef struct pixel24 {
     uint8_t R, G, B;
}__attribute__((packed)) Pixel24;

typedef struct pixel32 {
     uint8_t R, G, B, A;
}__attribute__((packed)) Pixel32;


typedef union pixel {
    Pixel16 pixel16;
    Pixel24 pixel24;
    Pixel32 pixel32;
} Pixel;

typedef struct file{
    Pixel *imageData;
}File

然后您可以使用以下内容:

void something(File file){
Pixel *pixelptr;

    if(file->imageHeader.pixelDepth == 16)
        *pixelptr = file->imageData.pixel16;
    else if(file->imageHeader.pixelDepth == 24)
        *pixelptr = file->imageData.pixel24;
    else
        *pixelptr = file->imageData.pixel32;
}