C标准库第一章assert .h学习笔记
一.在开始之前先顺便复习一下C语言的预处理指令
#define 定义一个宏
#undef 取消一个宏定义
#include 包含指定的源文件
#if 根据常量表达式的值,有条件包含文本
#ifdef 测试宏是否定义, 有条件包含一些文本
#ifndef 与#ifdef相反
#else 前面的测试条件失败,就包含一些文本
#line 指定行号和文件名
#elif 前面的测试失败,根据另一个常量表达式值有条件的包含一些文本
defined 测试一个宏是否定义, 若已定义返回1,否则返回0
宏参数字符串化
## 宏参数连接,组合成单个标记
#progma 指定依赖编译器信息
#error 用指定的信息产一个编译器错误
预定义的宏
__FILE__ 源文件名称
__func__ 函数名,GCC支持
__LINE__ 行号
__DATE__ 编译日期
_TIME__ 时间
__STDC__ 标准实现
常用惯例法
1. 定义宏代替magic number ,提高程序可读性,如:
#define BUFSIZE 4096
2.包括头文件
#ifndef _FILE_H
#define _FILE_H
/* content*/
#endif
3.带参数宏
#define ADD(x, y) (x) + (y)
4. 宏替换包含语句
#define FUNC(x, y) do{ /*implement*/} while{0}
二.assert.h 提供一个断言,如果断言失败, 返回类似
Assertion Failded: exp, filexxx, linexxx 信息,
Assert受宏NDEBUG控制,如果某编译单元有该宏定义,则忽略断言检查,
书上提供的源代码如下,
头文件Assert.h
#undef assert
#ifdef NDEBUG
#define assert(test) ((void) 0)
#else
void _Assert(char *);
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define assert(test) ((test) ? (void)0 \
: _Assert(__FILE__ ":" _STR(__LINE__) "" #test))
#endif
实现xassert.c
#include "assert.h"
#include <stdio.h>
#include <stdlib.h>
void _Assert(char *mesg)
{
fputs(mesg, stderr);
fputs(" -- assertion failed\n",stderr);
abort();
}
测试代码tassert.c
#define
NDEBUG
#include "assert.h"
#include signal.h>
#include <stdio.h>
#include <stdlib.h>
static nt val = 0;
static void field_abort(int sig)
{
if (val == 1)
{
puts("SUCCESS testing assert.h>");
exit(EXIT_SUCCESS);
}
else
{
puts("FAILUR testing <asssert.h>");
exit(EXIT_FAILURE);
}
}
static void dummy()
{
int i = 0;
assert(i == 0);
assert(i == 1);
}
#undef
NDEBUG
#include "assert.h"
int main(void)
{
assert(signal(SIGABRT, &field_abort) != SIG_ERR);
dummy();
assert(val == 0);
++val;
fputs("Sample assertion failure message --\n", stderr);
assert(val == 0);
puts("FAILURE testing <assert.h>");
return (EXIT_FAILURE);
}
学到2招:
1. 通过两个宏定义转换预定义的__LINE__ 为字符串
2. 写测试代码时最好给出一个总的结果说明测试是成功或失败