使用assert宏
定义
#include <assert.h>
void assert (int expression);
功能
当expression为假时,它向stderr打印一条出错信息,然后调用abort来中止程序运行。
注意
assert的缺点是调用频繁会极大地影响程序执行速度。解决方法,在前面加一个NODEBUG宏,来禁用assert的调用。
#include <stdio.h>
#define NDEBUG
#include <assert.h>
把NDEBUG定义为任何值都没关系,只要对它定义就能禁用assert的调用。但同时有可能会对assert中的表达式产生影响。所有要使用如下的方法:
p = malloc( sizeof(char)*100);
assert(p);
使用预编译
_FUNCTION_
gcc预先定义了该变量为当前函数(控制流程当前所在的位置)的名字。在调试程序时只要插入使用这一变量的printf语句就能缩小出现问题的范围。
例子:
#include <stdio.h>
void foo (void);
int main(void)
{
printf(“The current function is %s/n”,_FUNCTION_);
foo();
retrun 0;
}
void foo (void)
{
printf(“The current function is %s/n”,_FUNCTION_);
}
该程序的输出为:
The current function is main
The current functionis foo
_LINE_
C标准定义的宏。可替代行号。
_FILE_
C标准定义的宏。可替代文件名。
例子:
/****** fileopen.h ********/
#ifndef FILEOPEN_H_
#define FILEOPEN_H_
int open_file(FILE **fp,char *fname,char *mode,int line,char *file);
#endif
/*为避免头文件在同一项目中多个编译单元中出现编译错误或警告,用#ifdef语句将open_file函数的声明包含起来,以确保编译器只能遇到一次声明。*/
/******** fileopen.c ********/
#include <stdio.h>
#include “fileopen.h”
int open_file(FILE **fp,char *fname,char *mode,int line,char *file)
{
if((*fp = fopen(fname,mode)) ==NULL)
{
fprintf(stderr,”[%s:%d] open_fiel() failed!/n,file,line);
return 1;
}
return 0;
}
/*line和file分别是_LINE_和_FILE_的占位符,这两个宏将由调用函数传入*/
/******** test.c ********/
#include <stdio.h>
#include <stdlib.h>
#include “fileopen.h”
int main(void)
{
FILE *fp;
if(open_file(&fp,”foo_bar”,”w”,_LINE_,_FILE_))
{
exit(EXIT_FAILURE);
}
}
/*编译之前,预编译器会把_LINE_换成它所在的那一行的行号(调用它的函数里的行号),把_FILE_ 换成源码文件的名字test.c。如果我们在open_file()中调用它们,作用就不大了*/
标准库函数
errno
声明
#include <errno.h>
int errno;
使用它时,为了避免出现虚假的出错情况,最好在调用一个可能设置errno变量的库函数之前先把errno清零。
abort
声明
#include stdlib.h
void abort (void);
使程序异常中止,且被中止前不能进行一些常规的清理工作。
exit
声明
#include <stdlib.h>
void exit (int status);
完成清理工作后中止程序。status是exit饭后给系统的退出值。
atexit
声明
#include <stdlib.h>
int atexit (void (*function) (void));
登记在程序正常中止时要调用的函数。不是由exit调用就是由main返回来调用。若执行abort,则不会调用它。若function登记成功,则返回0,否则返回1。
perror
声明
#include <stdio.h>
void perror (const char *s);
perror首先打印字符串s,后面是一个冒号和一个空格,然后是对于的errno错误信息。
以下两行代码是等价的:
perror (“exp”);
printf(“exp:%s/n”,strerror(errno));
strerror
声明
#include <string.h>
char *strerror (int errnum);
与error配合使用很不错,可以得到可读的提示信息。
p = strerror (errno);