test-1.0使用#ifndef只是防止了头文件被重复包含(其实本例中只有一个头件,不会存在重复包含的问题),但是无法防止变量被重复定义。

vi test.c


include
include “test.h”
extern i; 
 extern void test1(); 
 extern void test2();int main() 
 { 
 test1(); 
 printf(“ok\n”); 
 test2(); 
 printf(“%d\n”,i); 
 return 0; 
 }vi test.h
ifndef TEST_H
define TEST_H
char add1[] = “www.shellbox.cn\n”; 
 char add2[] = “www.scriptbox.cn\n”; 
 int i = 10; 
 void test1(); 
 void test2();endif
vi test1.c
include
include “test.h”
extern char add1[];
void test1() 
 { 
 printf(add1); 
 }vi test2.c
include
include “test.h”
extern char add2[]; 
 extern i;void test2() 
 { 
 printf(add2); 
 for (; i > 0; i–) 
 printf(“%d-“, i); 
 }Makefile

test: test.o test1.o test2.o
test1.o: test1.c
test2.o: test2.c
clean:
rm test test.o test1.o test2.o

错误:
test-1.0编译后会出现”multiple definition of”错误。

错误分析:
由于工程中的每个.c文件都是独立的解释的,即使头文件有

ifndef TEST_H

define TEST_H

….

enfif

在其他文件中只要包含了global.h就会独立的解释,然后每个.c文件生成独立的标示符。在编译器链接时,就会将工程中所有的符号整合在一起,由于文件中有重名变量,于是就出现了重复定义的错误。

解决方法
在.c文件中声明变量,然后建一个头文件(.h文件)在所有的变量声明前加上extern,注意这里不要对变量进行的初始化。然后在其他需要使用全局变量的.c文件中包含.h文件。编译器会为.c生成目标文件,然后链接时,如果该.c文件使用了全局变量,链接器就会链接到此.c文件 。

注解:c/c++就这么规定:不可以在.h里定义变量,因为就是会触发这个重复定义错误。你只能在.h里用extern bool a;这样声明变量。

全局变量的定义就应当放在C文件里。然后在H文件里,用extern做外部声明。在需要用这个变量的源文件里包含上面这个H文件。

因为#include 是把后面的文件展开 就是static了,展开后还是两份它为每个include它的文件生成一份数据,编译是对每个.cpp文件做的操作。

你这个重复定义可以通过编译, 但是在将多个.cpp编译出来的.obj文件链接成一个exe文件时就会有同一个变量在几个obj中都有定义, 这样就出错了, 链接器不知道到底该链接哪个定义的变量

ifndef GLOBAL_DEFINE
define GLOBAL_DEFINE
endif

// 这个只是用来防止Global.h被重复inlcude,在循环递归include中。只能防止你在一个源文件里,重复包含了头文件。

宏定义是局部有效的,就是在同一个编译单元中,也就是一个cpp文件。另外一个cpp文件再次判断#ifndef GLOBAL_DEFINE仍然会为TRUE。
你的情况是,有好几个源文件都各自包含了这个头文件,那么,当然,头文件里的变量就在几个源文件里都定义了
注解end

test-2.0
vi test.c
include
include “test.h”
int i = 10; 
 char add1[] = “www.shellbox.cn\n”; 
 char add2[] = “www.scriptbox.cn\n”; 
 extern void test1(); 
 extern void test2();int main() 
 { 
 test1(); 
 printf(“ok\n”); 
 test2(); 
 printf(“%d\n”,i); 
 return 0; 
 }vi test.h
ifndef TEST_H
define TEST_H
extern i; 
 extern char add1[]; 
 extern char add2[];void test1(); 
 void test2();endif
vi test1.c
include
include “test.h”
void test1() 
 { 
 printf(add1); 
 }vi test2.c
include
include “test.h”
void test2() 
 { 
 printf(add2); 
 for (; i > 0; i–) 
 printf(“%d-“, i); 
 }