关于C语言结构体重复定义的问题

我有3个cpp源文件,每个都用到了我在supply.h里定义的结构体,所以每个源文件都包含了supply.h,但连接时并没有出现结构体重复定义的问题,这时候,我在main.cpp中再次定义了一个已经在supply.h的结构体(main.cpp已经包含了supply.h),在编译阶段就出现了重复定义,难道说结构体重复定义的问题只会出现在编译阶段,而不会出现在连接阶段嘛?

你所谓的结构体定义只是个声明,编译的时候并不会分配实际空间。只有在用它去定义一个变量的时候才会有具体的空间。类似一个概念,没有实体。所以在不同的文件中包含头文件,链接的时候不会有什么问题。但是你在main.cpp里又声明了一个同样名字的结构,就有冲突了,同一个名字有不同的内容,这个是不允许的。追问

但我如果在supply.h中定义一个函数就会出现重定义的问题,定义函数也没有分配空间啊

追答

#include语句,你可以认为是直接把文件里的内容复制一份过来,可以include任何文件
但是最终执行编译的时候,会把所有include的文件拼成最终的文件做编译
如果你觉得写到源文件里会有问题,那写到头文件里去include也会有同样的问题

另外,函数定义当然需要分配空间保存,要不你觉得这些信息去哪里了?
只是函数数据比较特殊,会保存在特别的代码空间用于执行。

另外的另外,再重申一次,声明和定义是两码事
声明不会占用任何空间,只是个概念,所以只要名字不冲突,可以任意地被包含。
而只有定义才会分配实际空间,所以,除非有特殊要求,被包含的头文件里最好只放声明。

追问

还是回到最初的问题,既然是声明,为什么在同一个cpp源文件中不能声明两次,而把它写进头文件并在不同cpp源文件中包含该头文件却可以编译,即使各cpp是单独编译,在连接的时候不也相当于声明了多次?

追答

为什么不能声明两次,举个例子吧,如果把struct demo { int a; } 和 struct demo { char a; }放到同一个文件里编译,你让编译器如何是好?
另外,声明只是在编译阶段有效的,编译完后也已经没有所谓的结构了,全部是不同大小的带名字的数据段,所以c语言可以任意cast指针,只要你知道自己在干嘛。因为每段数据都有自己的名字,所以定义的变量或是函数不能重名,否则,链接器如何是好?比如说,你叫张三,那谁谁也叫张三,那让要找张三的人怎么办?

温馨提示:答案为网友推荐,仅供参考
第1个回答  2019-08-05
我见过这样的题,没看懂你的意思,不过我看这样说吧,
struct
a
{...
}b;
我打。。。的地方表示你可以在那里添加所有的数据形式的定义,比如,int
a;char
a[10];等等;
而b表示变量名。就如同int
a的a一样,只是一个变量标示符,他就是一个结构体变量了。当你使用typedef使,它表示的是枚举类型,功能如同宏定义一样,
使用他的时候方法如下:
首先
写出你要表示的变量类型。列如:int
a;然后在int的前面加上typedef,
typedef
int
a;然后把变量名a
改变成你要使用的表示符如
pp;
现在就变成
typedef
int
pp;
当你要在定义其他的变量是int型的时候,你就可以这样定义了
pp
b;
这里的b就是变量名了。注意枚举类型它并不产生新的变量类型,只是一种替代作用。我在给你举个列子吧
typedef
struct
a{
int
s;
char
p[10];
}
num;
num
n;
这时候n就是
struct
a
类型的结构体变量了。不知道你懂没有。。。
相似回答