开发者社区> 问答> 正文

C/C++头文件声明变量的问题

a.h:

#ifndef _KNIFE_ADT_H
#define _KNIFE_ADT_H

enum Color{red, greed, blue};

typedef struct a{
    int    a;
    double b;
    Color  c;
}A_type;

A_type A_array[1024];//    (1)
int    Count;

void func(A_type A, Color color_type)

#endif
a.c:

#include "a.h"

Count = 0;//    (2)

void func(A_type A, Color color_type){
    ;
}
main.c:

#include "a.h"

int main(){
    Count = 0;

    return 0;
}
问题:
如上文件结构,编译会报重复定义的错误。在VS中,会报错.obj重定义。怎样处理最好?
另外如(2),如果想要给.h文件中变量初始化,最合适的方法是?

补充:
1.将声明写在.C文件中,.h文件中只有enum枚举常量与结构体的声明,所有变量定义放在.c文件中:
c1.h:

#ifndef _KNIFE_ADT_H
#define _KNIFE_ADT_H

enum Color{red, greed, blue};

struct a;
typedef struct a A_type;

void func(A_type A, Color color_type);

#endif
c1.c:

#include "c1.h"

struct a{
    int    a;
    double b;
    Color  c;
};

A_type A_array[1024];//    (1)
int    Count;

void func(A_type A, Color color_type){
    ;
}
main.c:

#include "c1.h"

int main(){
    Count = 0;

    return 0;
}

VS2012编译信息:
1>c:testtest_filec1.cpp(4): error C2380: “a”前的类型(构造函数有返回类型或是当前类型名称的非法重定义?)
1> 正在生成代码...
1> 正在编译...
1> main.cpp
1>c:testtest_filemain.cpp(4): error C2065: “Count”: 未声明的标识符

在头文件中声明int Count, 即可消除最后一条编译错误信息。
另外,在头文件中声明int Count后又在源文件中加上extern int Count, 有什么作用呢?具体用在哪些情景下?

展开
收起
a123456678 2016-06-06 14:04:56 3555 0
4 条回答
写回答
取消 提交回答
  • 最开始的时候最好保证,头文件声明,源文件实现

    2020-08-03 20:09:45
    赞同 展开评论 打赏
  • 软件开发,安全加密

    在头文件中声明int Count后又在源文件中加上extern int Count,
    头文件总声明,源文件中使用extern导入,全局变量都是这样使用

    2019-07-17 19:28:30
    赞同 展开评论 打赏
  • 乐于学习与分析

    文件太乱,能不能说清楚每个文件内容是什么

    2019-07-17 19:28:30
    赞同 展开评论 打赏
  • A_type A_array[1024];
    int Count;
    在头文件中,分别被2个c文件包括,这样相当于在2个c文件中定义了2次,这样在最后把这2个c文件生成的obj文件链接到一个可执行文件的时候,会导致有重复的定义。一般的做法是把变量的定义放到一个c文件中去,如果其他的c文件需要访问定义在其他c文件中的变量,使用extern关键字来声明这个变量定义在其他的c文件中。
    又做了些功课,发现还有些意思。我用的是llvm5.1,其他的平台可能不同。
    a.c文件的汇编结果中,数据是这样的

    .globl _Count
    .comm _A_array, 24576,4
    main.c 文件中是这样的

    1. .comm _Count, 4, 2
    2. .comm _A_array, 24576, 4

    .comm 的符号可能会和其他编译单元中的符号合并,也就是说2个.c中的_Count和_A_array被合并成一个,这样不会有符号冲突。
    但是如果在a.h中加入int k = 0;
    在生成的2个.s文件中都是 .globl _z,这样在链接的时候就会出现符号冲突。
    所以我觉得,楼主还是把出错信息贴出来的好。

    根据楼主提供的更新

    好吧,原来是用c++编译器编译的,和c不一样。对于第一个错误,我认为,struct在c++中有类似class的作用,你的变量a和struct的名字a相同,会被当作这class的constructor,但是constructor是没有返回值的,所以报错。但是由于没有ms的编译器,无法确认。你可以把int a改成另外一个变量名字。
    第2个错误是Count=0已经属于赋值了,但是Count没有声明或者定义过,所以出错。未声明变量默认为int适用于全局变量,并且这个默认在c99中已经取消了,所以,还是在定义的时候给出确定的类型。
    如果在头文件中声明,最好加上extern,如果另外一个c文件包括了这个头文件并且用到Count变量,编译器知道这个变量被定义在其他的文件中,具体地址由linker最后进行解析,这样就不会报错。 所以你最好定义在c文件中,然后如果其他c文件也需要访问这个变量,用extern关键词来表示这个变量在其他部分定义过了。

    2019-07-17 19:28:30
    赞同 展开评论 打赏
问答分类:
C++
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
使用C++11开发PHP7扩展 立即下载
GPON Class C++ SFP O;T Transce 立即下载
GPON Class C++ SFP OLT Transce 立即下载