用C语言写程序,总是免不了要定义全局变量,不过总是出现被多次定义的问题,比如如下我的代码:
laolang@laolang:~/code/c/test/HelloWorld$ tree
.
├── include
│ └── sum.h
├── Makefile
└── src
├── sum.c
└── test.c
2 directories, 4 files
laolang@laolang:~/code/c/test/HelloWorld$ cat include/sum.h //头文件,全局变量也在此文件中定义
1 #ifndef _SUM_H_
2 #define _SUM_H_
3 int sum_times = 0;//全局变量
4 int sum( int a, int b );
5 #endif
laolang@laolang:~/code/c/test/HelloWorld$ cat src/sum.c
1 #include"../include/sum.h"
2 #include<stdio.h>
3 int sum(int a, int b ){
4 extern int sum_times;//引用全局变量
5 printf("the time is %d\n",sum_times);
6 sum_times++;
7 return a + b;
8 }
laolang@laolang:~/code/c/test/HelloWorld$ cat src/test.c //主文件
1 #include"../include/sum.h"
2 #include<stdio.h>
3 int main(void){
4 int a = 0;
5 int b = 0;
6
7 puts("input two integer numbers:");
8 scanf("%d %d",&a,&b);
9 printf("%d + %d = %d\n",a,b,sum(a,b));
10 return 0;
11
12 }
laolang@laolang:~/code/c/test/HelloWorld$
我的Makefile:
laolang@laolang:~/code/c/test/HelloWorld$ cat Makefile
1
2
3 CC=gcc
4
5 CFLAGS=-Wall
6
7 RM=rm -rf
8
9 vpath %.h include
10 vpath %.c src
11
12 SOURS:=$(shell cd src;ls *.c)
13 OBJS:=$(patsubst %.c,%.o,$(SOURS))
14
15
16 PROGRAM=app
17
18 all:$(PROGRAM)
19
20 rebuild:clean all
21
22 $(PROGRAM):$(OBJS)
23 $(CC) -o $@ $^
24
25 test.o:sum.h
26
27 sum.o:sum.h
28
29 .PHNOY:clean run list
30
31 clean:
32 -$(RM) $(OBJS) $(PROGRAM)
33
34 run:
35 ./$(PROGRAM)
36
37 list:
38 @echo $(SOURS)
39 @echo $(OBJS)
40
laolang@laolang:~/code/c/test/HelloWorld$
以下是编译结果:
laolang@laolang:~/code/c/test/HelloWorld$ make
gcc -Wall -c -o sum.o src/sum.c
gcc -Wall -c -o test.o src/test.c
gcc -o app sum.o test.o
test.o:(.bss+0x0): `sum_times'被多次定义
sum.o:(.bss+0x0):第一次在此定义
collect2: error: ld returned 1 exit status
make: *** [app] 错误 1
laolang@laolang:~/code/c/test/HelloWorld$
编译结果说 sum_times被多次定义,参考了网上的说明,说是形成了多个标识符,当然如果你所有的代码都在一个文件中,那么是没有这个问题的,不过在实际项目中,这是不可能的。网上的方法就是建立一个.h文件,先引用一下所有的全局变量,所有的全局变量都在一个.c文件中,如:gloab.h,gloab.c,
.h和.c文件的文件名只有后缀不同,然后每个使用到全局变量的文件,包含gloab.h即可
于是我的代码结构是:
laolang@laolang:~/code/c/test/HelloWorld$ tree
.
├── include
│ ├── gloab.h//存放所有全局变量的第一次extern
│ └── sum.h
├── Makefile
└── src
├── gloab.c//所有全局变量的声明
├── sum.c
└── test.c
2 directories, 6 files
laolang@laolang:~/code/c/test/HelloWorld$ cat include/gloab.h
1 #ifndef _GLOAB_H_
2 #define _GLOAB_H_
3 extern int sum_times;
4 #endif
laolang@laolang:~/code/c/test/HelloWorld$ cat include/sum.h
1 #ifndef _SUM_H_
2 #define _SUM_H_
3 int sum( int a, int b );
4 #endif
laolang@laolang:~/code/c/test/HelloWorld$ cat src/gloab.c
1 #include"../include/gloab.h"
2 int sum_times = 1;
laolang@laolang:~/code/c/test/HelloWorld$ cat src/sum.c
1 #include"../include/sum.h"
2 #include"../include/gloab.h"
3 #include<stdio.h>
4 int sum(int a, int b ){
5 extern int sum_times;
6 printf("the time is %d\n",sum_times);
7 sum_times++;
8 return a + b;
9 }
laolang@laolang:~/code/c/test/HelloWorld$ cat src/test.c
1 #include"../include/sum.h"
2 #include<stdio.h>
3 int main(void){
4 int a = 0;
5 int b = 0;
6 int i = 0;
7
8 for( i = 0; i < 5; i++ ){
9 printf("%d + %d = %d\n",a,b,sum(a,b));
10 a += 2;
11 b += a;
12 }
13
14 return 0;
15
16 }
laolang@laolang:~/code/c/test/HelloWorld$
我的执行结果{
Makefile没有任何修改}:
laolang@laolang:~/code/c/test/HelloWorld$ make
gcc -Wall -c -o gloab.o src/gloab.c
gcc -Wall -c -o sum.o src/sum.c
gcc -Wall -c -o test.o src/test.c
gcc -o app gloab.o sum.o test.o
laolang@laolang:~/code/c/test/HelloWorld$ make run
./app
the time is 1//第一次输出
0 + 0 = 0
the time is 2//第二次输出
2 + 2 = 4
the time is 3
4 + 6 = 10
the time is 4
6 + 12 = 18
the time is 5
8 + 20 = 28
laolang@laolang:~/code/c/test/HelloWorld$