Unix C 编程问题精粹( 三 )


^^^^
使用#符号插入.make将忽略#之后的任何内容以及其后的RETURN键.变量.
^^^^
make允许定义与SHELL变量类似的有名变量.比如,你定义了SOURCES=prog.c,那么该变量的值$(SCOURES)就包含了源文件名.依赖关系.
^^^^^^^^
左边是目标模块,后接一冒号.再接与该模块有依赖关系的模块.命令.
^^^^
以TAB键开始(即使用相同数量的空格也不能代替它).
[]Makefile示例
下面介绍一个简单的示例来说明make的用法.假设你的程序有两个源文件main.c和myc.c,一个位於子目录include下的头文件myhead.h,一个库由三个源文件myrout1.c,myrout2.c,myrout3.c产生.
其makefile文件为:
#一个基本的MAKEFILE文件.
#其中包括个人的头文件和个人库.
HEADERS=include/myhead.h
SOURCES=main.c myc.c
PRODUCT=$(HOME)/bin/tool
LIB=myrout.a
LIBSOURES=myrout1.c myrout2.c myrout3.c
CC=cc
CFLAGS=-g
all:$(PRODUCT)
$(PRODUCT):$(SOURCES)
$(CC)$(CFLAGS) -o $(PRODUCT)$(SOURCES)
lint:$(PRODUCT)
lint $(SOURCES)$(LIBSOURCES)
哈哈,挺象SHELL编程的.如果你与我一样使用LINUX下的gcc,那么只要把上面的CC=cc改为CC=gcc即可.怎么样,想来一个更复杂点的吗?[]一个更为复杂的Makefile
你是否注意到,在上例中,只要启动make,就会重新编译所有源代码.
如果你能看懂以下的makefile,恭喜恭喜,你通关了.
#一个更为复杂的makefile
HEADERS=include/myhead.h
SOURES=main.c myc.c
OBJECTS=main.c myc.c
PRODUCT=$(HOME)/bin/tool
LIB=myrout.a
LIBSOURCES=myrout1.c myrout2.c myrout3.c
LIBOBJECTS=$(LIB)(myrout1.o)$(LIB)(myrout2.o)$(LIB)(myrout3.o)
INCLUDE=include
CC=cc
CFLAGS=-g -Xc
LINT=lint
LINTFLAGS=-Xc
all:$(PRODUCT)
$(PRODUCT):$(OBJECTS)$(LIB)
$(CC)(CFLAGS)-o$(PRODUCT)$(OBJECTS)$(LIB)
.c.o: $(HEADERS)
$(CC)$(CFLAGS) -c I$(INCLUDE)$<
$(LIB):$(HEADERS)$(LIBSOURCES)
$(CC) $(CFLAGS) -c $(?:.o=.c)
ar rv $(LIB) $?
rm $?
.c.c:;
lint: $(PRODUCT)
$(LINT)$(LINIFLAGS)$(SOURCES)$LIBSOURCES)第六章:优质无错编程
亲爱的,检查一下,你是否注意到了以下的细节?也就是说,你是否是一个合格的,能编写优质无错代码的程序员?要永远记住,编写无错代码是程序员的责任,而不是测试员.(摘录于本人的"细节页",因此本节将永远不会保持完整,欢迎您来充实她)[]所有程序员至少出现过的一个错误:
if(a=3){......}如果a等于3,那么......
你至少要养成这样的习惯:当判断一个变量与一个常量是否相等时,将常量写在前面.这样即使你一不小心写成这样:if(3=a){......}在cc 之前就可以很容易发现它.
[]老调重弹:逻辑操作符的优先权.
我不愿多嘴.总之,如果你一定要编写如下代码时:
if(a&0x1&&b&0x2){......}
你的手头最好有一本详尽的指南.或者你是这方面的专家.[]尽量不使用int数据类型.
这仅是一个忠告.你大可使用char,short,long数据类型.若干年以后,当你成长为高手之时,你会发现此时我的良苦用心.[]对于非整型函数一定要完整定义.
如 long float jisuan(char chArr[],int chNum)
{ long float lMydata;
...
...
return(lMydata); }[]对于非整型函数的输入要当心.
如 long float lfNum;
...
...
scanf("%lf",&lfNum);[]float 型的有效数字为7位.当多于7位时,第8位及以后的位将不准确,可以将其定义为long float型.[]文件的输入出尽量采用fread fwrite函数.只有当另有用途时才用fprintf fscanf 函数.[]对于数组及字符串的比较操作时要确认以""结束.
第七章:调试技术
调试技术在本文中不太好说,之所以将其独立成章是想套用M$的老话:"在下一版本中将会做得更好":-((.其实这类文章在全国各大BBS上满天飞.在此我只想说说程序员的应尽职责之一:在程序中使用断言.
~~~~
[]既要维护程序的交付版本,又要维护程序的调试版本,这时可以利用断言补救.[]要使用断言对函数参数进行确认.[]要从程序中删除无定义的特性,或者在程序中使用断言来检查出无定义特性的非法使用.[]不要浪费别人的时间,详细说明不清楚的断言.[]消除所做的隐式假定,或者利用断言检查其正确性.[]利用断言来检查不可能发生的情况.

推荐阅读