关于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
类型的结构体变量了。不知道你懂没有。。。

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

C语言的重定义错误,求解
你的问题可能是函数或者全局变量的定义在整个程序中重复了。检查头文件中是否有全局变量定义(没有加extern的就是定义),有的话试试添加关键字static,或者吧定义写在.c文件里。从你的图片上来看,头文件里包含了几个指针变量定义,在这些指针变量定义前面添加关键字extern(如果有初始式去掉初始式)强制...

关于C语言里面一个因函数重复包含而产生的重定义问题。。请高手解决_百...
B、C、D都分别建一个头文件a.h, b.h, c.h,a.h形如:ifndef _a_h_define _a_h_……endif 这样能够避免重复包含,并且函数原型,结构体定义都写在头文件里面,头文件一定不要写函数主体

C语言头文件中定义结构体的问题
C语言程序设计中,为防止头文件在同一编译单元被重复引用,常引入#ifndef宏来进行保护,如:头文件my_head.h ifndef _MY_HEAD_H_ \/\/如果没有定义宏_MY_HEAD_H_#define _MY_HEAD_H_ \/\/则,定义该宏名\/\/以下是被保护的代码区\/\/进行相应的全局变量和结构体类型定义typedef struct stu { ...

C#中使用结构体,在结构体的定义中又包含另一个结构体的数组,该怎么定义...
注:结构体内的变量最好加public 关键词。即:struct b{public int id;public a[] suba;} struct a { public int start; public int end; } struct b { public int id; public a[] suba; } static void Main(string[] args) { b newb; newb.id = 1; newb.suba = new a[10]; newb.suba...

C语言,已经在别处定义过的结构体,在这里为什么还要再说一句,这属于什 ...
在别处定义的那是结构体的形势,这里定义的是结构体的实体,打个比方,你在别处定义了int,但是int并不是一个变量,你还得在定义int i,i才是实体,才能用!

C语言为什么我定义了一个结构体指针,然后我传入参数,还要再定义一个新...
指向指针的指针是可以满足你的需求。void List_HeadInsert(LinkList **L)然后函数里面的L, 统一换成(*L),最后不用返回 L

c语言程序问题:为什么我把stu结构体重命名为stud之后还能用stu定义结构...
你对typedef理解错了,说法也就错了,对代码的解析也就出问题了。typedef是对“已有的类型起一个别名”而不是“重新命名”。既然是“别名”,当然原来的名字还是有效的,新名字也是有效的,这就像一个人有两个以上的名字,叫哪一个名字都指的是同一个人。

C语言中能否在一个结构体内在定义一个结构体
当然可以,但是你这个结构体的定义域只在父结构体当中,外面没办法用这个结构体的定义做任何事情。比如:struct A { struct B { };struct B b;};这样用是可以的,但是到了结构之外就不能用struct B来定义数据了。

c语言结构体问题
核心三个函数:compare函数,按学号查找学生信息,返回位置;modifyStuInfoByIndex函数,修改指定位置学生信息;noRepeated函数,判断学号是否重复。题主看明白这三个函数就可以了。 已赞过 已踩过< 你对这个回答的评价是? 评论 收起 其他类似问题 2012-09-16 C语言里结构体的问题。结构体定义指针类型是怎么回事? 113 ...

相似回答