【问题标题】:Declaration of typedef with pointer用指针声明 typedef
【发布时间】:2016-11-21 06:18:12
【问题描述】:

这个周末学习 C ANSI 语言的特殊性是一个相当大的挑战。

在一个练习中,我有一个头文件,其中包含一些函数签名声明。

这个引起了我的注意:

typedef struct image * Image;

我在我的 .c 文件上试过这个:

typedef struct {
    char nbrMagique[10];
    unsigned long imgLarg;
    unsigned long imgHaut;
    unsigned long imgSeuilMax;
    unsigned long **imageMatrice;
} Image;

但是在编译的时候不断出错:

imagePGM.c:22:3: erreur: conflicting types for ‘Image’
 } Image;

所以我猜是因为我无法重新定义 .c 文件中的结构,也无法触摸标题。

并尊重“typedef struct image * Image;”在 .h 头文件中,我必须创建一个动态二维表并将指针 *image 指向它?

我是否在反思中遗漏了什么?

但是 .h 文件中 typdef 签名中的指针 * 是什么意思?

【问题讨论】:

  • 您对Image 做了两个不同的定义……一个是struct image * 的typedef,另一个是未命名结构的typedef。您只能 typedef 一个名称一次。也许你的意思是你的c文件中的struct image { ...... };
  • 我必须使用 struct image * Image;那肯定我不能使用第二个。但是打字机签名中的指针 * 是什么意思呢?
  • 添加一些关于此的信息。上下文很可能是试图创建一个指向不完整类型的指针,有时称为不透明指针。这是在 C 中实现真正私有封装的一种方法。如果是这种情况,最好不要将其定义为指针。最好做typedef struct image image 并强制调用者使用指针语法。

标签: c pointers syntax typedef


【解决方案1】:

来自typedef 的语义,第 §6.7.8 章,C11 文档,

在存储类说明符为typedef 的声明中,每个声明符定义一个 identifier 是 typedef 名称,表示为标识符指定的类型 [...]

所以,基本上,typedef 用于为给定类型创建一个别名

另外,为了进一步扩展,

typedef 声明没有引入新类型,只有一个 如此指定的类型的同义词。也就是说,在以下声明中:

typedef T type_ident;
type_ident D;

type_ident 定义为 typedef 名称,其类型由声明指定 T 中的说明符(称为T),D 中的标识符的类型为 ‘‘derived-declaratortype- 列出 T''

在您的代码中,您尝试将两种不同类型的typedef(即struct image * 和未命名的struct)设置为相同的别名,这就是问题的原因。

解决方案:你不需要在你的.c文件中typedef结构声明,使用简单的声明,比如

struct image {
    char nbrMagique[10];
    unsigned long imgLarg;
    unsigned long imgHaut;
    unsigned long imgSeuilMax;
    unsigned long **imageMatrice;
} ;   

也就是说,一般来说,typedef-ing 指针被认为是一种令人困惑的编码风格,这会降低可读性,恕我直言,请避免使用 typedef-ing 指针。


关于部分

但是typedef的签名中的指针*是什么意思呢?

这意味着,新的别名是指针类型。对于这种情况,

 typedef struct image * Image;

两者

 Image iPointer = NULL;

 struct image * againIPointer = NULL;

都是一样的。

【讨论】:

  • 我会尝试应用您的解决方案;但是打字机签名中的指针 * 是什么意思呢?
  • @Cyber​​flow 这意味着,别名是指针类型,让我解释一下我的答案以涵盖这一点。
  • 参见Is it a good idea to typedef pointers?,其简短回答是“不,除非它们是函数指针”。
  • @JonathanLeffler 只是确认一下先生,我们站在同一边,对吗? ;)
  • 我想是的;我的态度是“你不应该使用typedef struct WhatNot *WhatNotPtr;,否则会受到……辱骂和完全回避使用这种符号生成的代码的痛苦”。这不是一个绝对的禁令,但它非常接近它。 (例外情况可能是外部接口只将类型视为不透明类型,因此只使用指针并且从不需要访问内部,但即便如此仍然存在阻力/不情愿。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
  • 2011-07-15
  • 2021-06-27
  • 2015-05-02
相关资源
最近更新 更多