转自:http://blog.csdn.net/soloopin/article/details/8057721
偶然发现有很多自定义函数未经声明却能在主程序中被调用,这就奇怪了,连使用标准库函数printf()都要包括标准输入输出头文件
1、文件test1.cpp如下:
#include "stdafx.h" // stdafx.h: #include程序正常运行,因为Max()在被调用前已经定义。int Max(int x, int y) { return ((x > y ) ? x : y); } int main(int argc, char* argv[]) { int a = 300, b = 100; printf("Max(a, b): %d/n", Max(a, b)); return 0; }
#include "stdafx.h" // stdafx.h: #include编译时出错:int main(int argc, char* argv[]) { int a = 300, b = 100; printf("Max(a, b): %d/n", Max(a, b)); return 0; } int Max(int x, int y) { return ((x > y ) ? x : y); }
#include "stdafx.h" // stdafx.h: #include程序正常运行,因为Max()在被调用前已经定义。int Max(int x, int y); int main(int argc, char* argv[]) { int a = 300, b = 100; printf("Max(a, b): %d/n", Max(a, b)); return 0; } int Max(int x, int y) { return ((x > y ) ? x : y); }
1、文件test2.c如下:
#include用gcc编译:gcc -Wall -o test2 test2.c,通过。程序正常运行,因为Max()在被调用前已经定义。int Max(int x, int y) { return ((x > y ) ? x : y); } int main(int argc, char* argv[]) { int a = 300, b = 100; printf("Max(a, b): %d/n", Max(a, b)); return 0; }
#includeint main(int argc, char* argv[]) { int a = 300, b = 100; printf("Max(a, b): %d/n", Max(a, b)); return 0; } int Max(int x, int y) { return ((x > y ) ? x : y); }
用gcc编译:gcc -Wall -o test2 test2.c,出现警告:
warning: implicit declaration of function `Max'int Max(int x, int y) { return ((x > y ) ? x : y); }
int Min(int x, int y) { return ((x > y ) ? y : x); }
int Add(int x, int y) { return (x + y); }
Makefile:
#User defined library, by He Yaozhong CC=gcc HOME=/u01/work OS=$(HOME)/tools INCLUDE=$(HOME)/headfile -I$(HOME)/tools CSTARGETS=Max.o Min.o Add.o LIBS=$(HOME)/lib/tools.a all: $(LIBS) clean Max.o : Max.c $(CC) -I$(INCLUDE) -c $(CCFLAGS) Max.c Min.o : Min.c $(CC) -I$(INCLUDE) -c $(CCFLAGS) Min.c Add.o : Add.c $(CC) -I$(INCLUDE) -c $(CCFLAGS) Add.c $(LIBS) : $(CSTARGETS) cd $(OS); / ar ruv $(LIBS) $(CSTARGETS:$HOME/lib/=) clean: rm -f *.o
在/u01/work/tools目录中,使用make工具:
[root@node01 tools]# make
gcc -I/u01/work/headfile -I/u01/work/tools -Wall -c Max.c2、在/u01/work/test2目录中,编写2个文件:
test2.c:#includeint main(int argc, char* argv[]) { int a, b; printf("Please input 2 integer (a, b): /n"); scanf("%d", &a); scanf("%d", &b); printf("Max(a, b): %d/n", Max(a, b)); printf("Min(a, b): %d/n", Min(a, b)); printf("Add(a, b): %d/n", Add(a, b)); return 0; }
CC=gcc HOME=/u01/work INCLUDE=-I$(HOME)/headfile -I. CFLAGS= -L$(HOME)/lib LIBS=$(HOME)/lib/tools.a all : $(OBJS) test2 clean test2 : test2.c $(CC) $(INCLUDE) -Wall -o test2 test2.c $(CFLAGS) $(LIBS) clean : rm -f *.o
在/u01/work/test2目录中,使用make工具:
生成了/u01/work/test2/test2可执行文件。运行程序:
[root@node01 func_pointer]# ./test2一个好的程序员,应该养成严谨、规范的编程习惯,编译程序时应打开显示所有警告选项“-Wall”,并且对编译器提出的所有警告都要给予处理,仅以编译、连接通过为目标,这可能会有潜在的危害。
五、笔记
本篇博客的意义在第四部分的总结已经写得很详细了,我看这篇博客的时候,对于第三部分涉及到makefile的模块编译没有看懂,因为makefile的语法不太懂,回头有时间再试验一下;
这儿重点说下 -I(大写的i)参数,关于这个参数的使用在之前的博客中我有提到,见:Linux下编译多个不同目录下的文件以及静态库、动态库的使用,对于本篇文章,也提到了-I参数,和之前是同样的用法——指定编译器搜索头文件的路径。不同的是这儿在主函数中没有include应有的头文件,所以在编译的时候有warning。