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

Posted

技术标签:

【中文标题】包含指向其他结构的指针的结构【英文标题】:Struct containing pointers to other structs 【发布时间】:2013-11-14 18:47:18 【问题描述】:

我试图创建一个包含多个指向结构的结构,因为我有一个读取 img 文件的程序,并且根据这个文件是 16、24 还是 32 位,我想这样对待它。当我尝试使我的像素指针指向其他结构之一时出现问题(“从类型'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;

【问题讨论】:

稍微更新了我的代码,忘记添加我用来收集图像数据和标题信息的结构文件。 【参考方案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. */

【讨论】:

我在这里可能只是个白痴(以前从未使用过联合),但是当我尝试此操作时,我会收到“对某事物或结构或联合中的成员“数据”的请求”。 (虽然我不明白为什么它显然是我试图达到的工会) @UserQuestion 对不起,我的错。 data(字段名)应该放在最后。我已经在我的示例中更正了它。【参考方案2】:

我会混合使用联合和结构:

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;

【讨论】:

为了让它工作(有点)我必须调用:*pixelptr = file->imageData->pixel16; (a . 在 imageData 之后不工作),但随后我收到一个新错误:“从 Type Pixel16 分配给类型 Pixel 时类型不兼容”(我可能只是个白痴,但我无法让它工作) @UserQuestion 您正在尝试将Pixel16 存储在Pixel 中。联合允许您与所有类型共享相同的存储,但在处理数据时,您仍然需要使用正确的类型(即Pixel16)访问它。在我的回答中,depth 字段表示确定文件的像素深度后应该访问的联合成员。 啊,当然。但这是否意味着我以后不能使用单个 pixelptr 来完成所有工作?我必须在我以后要做的所有事情上使用什么 pixelptr 之后切换? @UserQuestion 像素深度可能存储在imageHeader 中,因此与其将像素深度存储在每个Pixel 结构中,不如使用标题中的深度来知道要使用哪个联合成员访问。 刮掉最后一个,我现在明白了。非常感谢您的耐心:)

以上是关于包含指向其他结构的指针的结构的主要内容,如果未能解决你的问题,请参考以下文章

返回指向结构的指针并访问其字段 C++

调用旧版 C API 时,如何在现代 C++ 中正确地将指向结构的指针转换为指向其他结构的指针?

HDF5:复合数据类型,用于写入包含指向另一个结构的指针的结构

包含相同类型的结构指针的结构指针的初始化

结构体里面包含指向本结构体的指针的写法

如何定义包含指向自身的指针的 typedef 结构?