全局变更使用及编译

全局变更使用及编译

最近在弄自已的一个库文件,里面有一个函数用到几个全局变量。

编译时,老是放重定义的错误,调试花了我不了时间。

这是很基础的问题,自己没有重视。回到最初的起点,重新理解一下基础的问题。

一般来说,声明放在.h头文件里面,而定义放在cpp文件里。

有必要弄清楚声明和定义间的区别:

变量的声明就是告诉编译器有这么一个变量,声明是不分配存储空间。如externint x说明 x在另外一个地方有定义,这里声明使用。

而定义要给这个变量分配存储空间的。如int i =0;这时编译器要给变量分配地址空间的。

一般地:

在使用全局变量时一般将全局变量的定义放在.cpp文件中,全局变量的声明放在.h文件中,若将全局变量的定义放在一个.h文件中容易出现重复定义的情况,具体使用方法如下:
1
、在主函数所在的C文件里定义变量(可以初始化,也可不初始化),然后在H文件中,用extern声明,(注意:不能初始化了)。其他需要用到这个变量的C文件,在程序之前include对应H文件就OK.
2
、在特定的一个C文件里定义变量(可以初始化,也可不初始化),然户,在H文件中,用extern声明,(注意:不能初始化了)。其他需要用到这个变量的C文件,在程序之前include对应H文件就OK

多次强调不要初始化,因为初始化是要分配内存。这就不是声明。

全局变量是可以多次声明的,但定义只有一次

如在test1.h中:

externint i;

test2.h

externint i;

test.cpp中:

#include"test1.h"

#include"test2.h"

inti=0;

intmain(){

printf("i:%d\n",i);

}

这样使用是没有问题的。

其实编译器是要记你声明和定义过的变量,只有声明或定义过的变量才能使用。

编译器是先在同一个编译单元里编译生成中间文件的,编译器会检查每一个变量。

testA.cpp

int i=0;

testB.c

intmain(){

printf("i:%d\n",i);

}

gcc -otestA.o  testA.c没有问题

gcc -otestB.o  testB.c就会报错。因为找不到i变量。这是因为编译器的还未进行全局的查找,只是在同一个文件中进行检查变量。

这时需使用extern int i;声明来显示告诉编译器,在另外一个文件(编译单元有这么一个变量。)这样,编译器就可以放行。单元编译没有问题。

另一个情况:

testA.c文件中:

int i=0;

testB.c:文件中:

intmain(){

printf("i:%d\n",i);

}

gcc -otestA.o  testA.c没有问题

gcc -otestB.o testB.c 没有问题。

再进行链接生成执行文件:

Gcc –o testtestA.o testB.o链接时就会报错,因为变量i重复定义了。变量只有定义一次。

解决这个问题的办法是在testA.h中声明I变量。在testA中,定义这个i变量。而在testAinclude“testA.h”头文件,就可以使用了i变量。

 

注意,条件编译并不能解决这个问题:

如代码:test1.h

#ifndef __A__H__
#define __A__H__
int i =0;
void myprint();
#endif

test1.c文件:

#include <stdio.h>
#include "test1.h"
void myprint(){
    printf("%d\n",i);
    printf("hello world\n");
}

在main.c中

#include <stdio.h>
#include "test1.h"
int main(){

     myprint();

编译语句:

gcc -o test1.o -c test.c 没有问题。

gcc -o test  main.c test1.o 就会重复定义的错误。

ld: 0711-224 WARNING: Duplicate symbol: i
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.

上面的文件关系是这样的:

       int i

    /          \

test1.o      main.o

    \          /

      test

通过在同一个文件编译生成test1.o ,  同样main.o也是在同一个文件中编译生成的。之间都有全局变量 i.

通过链接阶段就会发现有重复的变量。解决办法上面已经说过了。

 

  

虽然有条件编译条件,但编译条件并不能解决这个问题的。

如果文件的关系是这样:

       A

    /      \

 C     D

  \   /

    B

上面的文件有关系,C中包含A,D中包含A。 B中要包括C和D,这样条件编译就可把在预处理阶段去掉重复包含文件A。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值