c语言指针延迟到不完整类型,在C中使用typedef结构时,取消引用指向不完整类型错误的指针...

这是命名混乱.

由于typedef,node == struct data.

但是node!= struct node.它们是两种不同的类型.并且尚未定义struct节点.

遗憾的是,C标准允许这种令人困惑的结构,甚至没有被编译器标记为警告.但这就是今天定义C的方式,所以我们必须忍受它.

我的建议:不要对struct和typedef使用相同的名称.创建自己的约定,例如struct thing_s和typedef struct thing_s thing_t; .这样可以避免命名这样的混淆.

解决方案现在非常明显.

替换:

typedef struct data {int num; struct node * link; } node;

通过

typedef struct data {int num; struct data * link; } node;

而有问题的printf现在可以工作了.

但你的问题是:为什么你的程序在没有这个printf的情况下完全有效?

现在这是一个有趣的.

让我们回到最初的定义.

正如我们所说,struct node不存在,因此是不完整的.

为了更好地遵循我们要解释的内容,我们将其称为struct incomplete_s.现在,节点变为:

typedef struct data {int num; struct incomplete_s * link; } node;

没有有问题的printf它仍然可以工作.

原因是,节点已正确定义.它是一种已知尺寸和类型的结构.因为struct incomplete_s不完整并不重要,因为链接被定义为指向它的指针.你也可以定义void * link;它仍然有效.

void *或struct incomplete_s *或者其他*具有相同的大小:它们都是指针.因此可以正确地创建托管它们的结构.

在你的主循环中,你的程序会:

while(e!=NULL)

{

printf("%d\n",e->num);

e=e->link;

}

即e,它是一个指针节点*,取e-> link的值,这是一个指针struct incomplete_s *.

请注意,两个指针都应该指向不同的类型.

但它们都是指针,所以是的,这项任务在技术上是可行的并且由标准授权.

现在一个更谨慎的编译器可能会在这里发出警告,因为你不应该混合使用不同类型的指针.这是一个静默类型转换,这是未来错误的一个配方.

我不知道你使用哪个编译器,但是你可以增加它的警告级别(对于Visual使用“警告级别4”,或者对于gcc使用-Wall -Wextra),它可能不会喜欢this = operation.

更明确的类型转换将解决(*):

e =(节点*)(e->链接);

现在这不再是沉默,程序员负责,警告将消失.

e->链接肯定存在,因此编译器可以获取此值.

但是s-> link-> num不存在,因为s-> link是struct incomplete_s *,我们不知道它是什么,所以我们不知道它是否有一个num成员.

(*)过度补充:在更高的优化级别,这仍然不好:strict aliasing可能会妨碍.因此,将指针类型解引用到另一个指针类型仍然是一个危险的操作.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值