`
silentpassing
  • 浏览: 6558 次
  • 性别: Icon_minigender_1
  • 来自: 冰岛
最近访客 更多访客>>
社区版块
存档分类
最新评论

第一章 <assert.h>

阅读更多

2011年 03月 03日 星期四 12:36:51 CST

0.标准头文件的特点:具有幂等性、相互独立性、和文件级别的声明等同。
    库中的每一个可见函数都占据着单独的C源文件;
    每个隐藏的名字都以一个下划线和一个大写字母开头;
    库中隐藏的函数和数据对象通常占据以x开头命名的C源文件;
    在一个库的可见函数定义中,函数名被一对括号括住,所有这样的函数声明都会被相应的头文件中的宏定义所掩盖,所以这对括号阻止了翻译程序识别和展开宏。

1. 头文件<assert.h>唯一的目的就是提供宏assert的定义。

2.可以通过在程序的某些地方定义宏NDEBUG来改变assert的展开方式,如果NDEBUG在包含了<assert.h>d的源文件中某处被定义为宏名,那么宏assert就被直接定义为:#define assert(ignore) ((void) 0)

3.宏assert应该作为一个宏而不是一个实际的函数来实现。如果为了访问一个实际函数而禁止宏定义,那么这种行为是未定义的。

4.源文件的名字和源文件的行数分别是预定义的宏_FILE_和_LINE_的值。

5.宏assert没有任何返回值。


6.对<assert.h>来说,每次包含它的时候它的行为都会发生变化。该头文件会改变assert的定义来适应NDEBUG当前的定义状态。

7.要打开断言可以这样写:
#undef NDEBUG
#include <assert.h>

要关闭断言,可以这样写:
#define NDEBUG
#include <assert.h>

8.宏NDEBUG可以重定义,这是良性重定义。

9.宏不能直接调用库的任何输出函数(为了保证库头文件之间的独立性)。

10.一个程序如果不包含某个头文件,就可以定义宏来对该头文件中的任意名字重新命名。

11.宏必须能扩展为一个void类型的表达式。

12.宏应该可以扩展为一个有效并且紧凑的代码。

13.预处理运算符
    #(单井号) ——字符串化运算符(后边没有参数时就是空指令,它没有任何作用)
    ##(双井号) ——连接运算符
    #@ ——字符化运算符

14.内置宏__LINE__没有扩展成字符串字面量,它变成了一个十进制常量。把它转换成适当的形式需要一个额外的处理层。那要通过向头文件中添加两个隐藏的宏_STR和_VAL来实现。其中一个宏用它的十进制常量扩展来取代__LINE__,另一个是把十进制常量转化为一个字符串字面量。忽略其中任一个都会得到字符串字面量"__LINE__",而不是你想要的结果。

15.当宏参数是另一个宏的时候 ,需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开. (对于理解"_VAL(__LINE__)"是很重要的!!!)

PS:宏_VAL和_STR的命名可以是任意的。

 

0
2
分享到:
评论

相关推荐

    C语言基础教程TXT

    B.6 诊断:&lt;assert.h&gt; B.7 变量变元表:&lt;stdarg.h&gt; B.8 非局部跳转:&lt;setjmp.h&gt; B.9 信号处理:&lt;signal.h&gt; B.10 日期与时间函数:&lt;time.h&gt; B.11 由实现定义的限制:&lt;limits.h&gt;和 &lt;float.h&gt; 附录C 变更小结

    c语言设计Brian W. Kernighan Dennis M. Ritchie

    B.6 诊断:&lt;assert.h&gt; B.7 变量变元表:&lt;stdarg.h&gt; B.8 非局部跳转:&lt;setjmp.h&gt; B.9 信号处理:&lt;signal.h&gt; B.10 日期与时间函数:&lt;time.h&gt; B.11 由实现定义的限制:&lt;limits.h&gt;和 &lt;float.h&gt; 附录C 变更小结

    C程序设计语言(第2版·新版)

    B.6 诊断:&lt;assert.h&gt; B.7 变量变元表:&lt;stdarg.h&gt; B.8 非局部跳转:&lt;setjmp.h&gt; B.9 信号处理:&lt;signal.h&gt; B.10 日期与时间函数:&lt;time.h&gt; B.11 由实现定义的限制:&lt;limits.h&gt;和 &lt;float.h&gt; 附录C 变更小结

    C程序设计语言 很适合初学者和再学者学习和复习

    B.6 诊断:&lt;assert.h&gt; B.7 变量变元表:&lt;stdarg.h&gt; B.8 非局部跳转:&lt;setjmp.h&gt; B.9 信号处理:&lt;signal.h&gt; B.10 日期与时间函数:&lt;time.h&gt; B.11 由实现定义的限制:&lt;limits.h&gt;和 &lt;float.h&gt; 附录C 变更小结

    c程序设计语言入门基础 @精品@ 花我一年才从众书中筛选出的

    B.6 诊断:&lt;assert.h&gt; B.7 变量变元表:&lt;stdarg.h&gt; B.8 非局部跳转:&lt;setjmp.h&gt; B.9 信号处理:&lt;signal.h&gt; B.10 日期与时间函数:&lt;time.h&gt; B.11 由实现定义的限制:&lt;limits.h&gt;和 &lt;float.h&gt; 附录C 变更小结

    C语言精典版本C程序设计语言

    B.6 诊断:&lt;assert.h&gt; B.7 变量变元表:&lt;stdarg.h&gt; B.8 非局部跳转:&lt;setjmp.h&gt; B.9 信号处理:&lt;signal.h&gt; B.10 日期与时间函数:&lt;time.h&gt; B.11 由实现定义的限制:&lt;limits.h&gt;和 &lt;float.h&gt; 附录C 变更小结 ...

    C语言程序设计标准教程

    #include&lt;stdio.h&gt; main() { FILE *fp; char ch; if((fp=fopen("e10_1.c","rt"))==NULL) { printf("Cannot open file strike any key exit!"); getch(); exit(1); } ch=fgetc(fp); while (ch!=EOF) { putchar(ch); ...

    從新手到高手C++全方位學習

    第2章 做一個最簡短的C++程序 2.1 簡單的屏幕輸出小程序 2.2 輸出語句的使用 2.3 std::介紹 2.4 iostream與iostream.h的區別 2.5 重名問題 2.6 註釋 第3章 初步了解函數 3.1 一個簡單的函數 3.2 函數的傳參 3.3 函...

    C语言解析教程(原书第4版)(美) 凯利.pdf

    第0章 从零开始 0.1 为什么要用c 0.2 ansi c标准 0.3 从c到c++ 0.4 从c和c++到java 第1章 c语言概述 1.1 编程和预备知识 1.2 程序输出 1.3 变量、表达式和赋值 1.4 使用#define和#include 1.5 使用printf()和scanf...

    C++MFC教程

    +-- 第一章 VC入门 |------ 1.1 如何学好VC |------ 1.2 理解Windows消息机制 |------ 1.3 利用Visual C++/MFC开发Windows程序的优势 |------ 1.4 利用MFC进行开发的通用方法介绍 |------ 1.5 MFC中常用类,宏,函数...

    你必须知道的495个C语言问题

    1.28 文件中的第一个声明就报出奇怪的语法错误,可我看没什么问题。这是为什么? 1.29 为什么我的编译器不允许我定义大数组,如doublearray[256][256]? 命名空间 1.30如何判断哪些标识符可以使用,哪些被保留了...

    《你必须知道的495个C语言问题》

    1.28 文件中的第一个声明就报出奇怪的语法错误,可我看没什么问题。这是为什么? 15 1.29 为什么我的编译器不允许我定义大数组,如double array[256][256]? 15 命名空间 15 1.30 如何判断哪些标识符可以使用,...

Global site tag (gtag.js) - Google Analytics