第十四章 预处理器





我跳过了先进的指针主题的章节。

太多的技巧,太学科不适合今天的我。但我真的读,读懂。假设谁读了私下能够交流一下。有的小技巧还是非常有意思。

预处理器这一章的内容。大家肯定都用过。什么#include,#define #ifdef #undef这些,可是绝对用的不多。作为全面了解学C,还是应该都看一看。

预处理器使用方法非常讲究,用不好会失误,用好了会大大加快执行时速度(不是编译速度)。





总结:

C程序的第一个步骤就是预处理。预处理器共包括下面几个符号:

1、#define

定义宏,替换作用。

它把一个符号名与随意的字符序列联系在一起。

比如,这些字符可能是一个字面值常量、表达式或者程序语句。这个语句到末尾结束,不须要;

假设过长的话能够用一个反斜杠,如:

#define PRINT(FORMAT,VALUE) \

printf("The value of " #VALUE
\

" is " FORMAT "\n", VALUE)

...

PRINT("%d", X+3);

output: The value of x+3 is 25.

这里面#VALUE相当于把一个宏參数转换为一个字符串。

有些能够用函数实现的也能够用宏实现。宏的长处就在于它与类型无关。

并且宏的运行速度快于函数。由于他不存在函数调用返回的开销,在编译的时候就已经弄好了。

缺点就是使代码过长。同一时候具有不可预測的副作用,函数在这方面更easy预測。比方可能会运行多次(意料之外),可能会涉及优先级的问题。

两者不同也在于。命名约定也不同。比方max(a,b);和MAX(a,b);





2、#ifdef #undef #endif

属于条件编译,#undef指令能够使一个原来定义好的名字被忽略。





3、#if #elif #else

这三者也属于条件编译。各自是这样。假设(#if),当满足什么条件就如何(#elif),假设都不成立就(#else)。

功能较#ifdef这组更加强大,有点儿像switch case语句。





4、#include 

实现文件包括 。

常常有这两种形式#include "XXX.h"或者#include <XXX.h>,差别在于,""是在源文件路径下的头文件,<>是库文件路径下的头文件。

文件包括能够嵌套。可是不要超过两层。

由于会造成多次包括同一个文件的危急。

有人说这个easy。添加个:

#ifdef _HEADERNAME_H

#define _HEADERNAME_H

...

#endif

这个常常出如今大型程序中,可是会添加编译速度。





5、#error,#line,#progma

#error,在编译的过程中会产生一条错误信息,新信息中包括的是你所选择的文本。

#line,告诉编译器下一输入的行号。

#progma,语法因特性而异。





警告:

1、不要在一个宏定义的末尾加上分号。

2、在宏定义中使用參数,但忘了在他们周围加上括号。

编程原则上。宏定义參数须要各种加括号的。

3、忘了在整个宏定义的两边加上括号。

2和3均会由于优先级的问题造成不可预知的错误。





编程提示:

1、避免用#define指令定义能够用函数实现的非常长序列的代码。

程序的长度会极大极大的增长!



2、在那些对表达式求值的宏中,每一个宏參数出现的地方都应该加上括号。而且在整个宏定义的两边也要加上括号。

3、避免使用#define宏创建一种新语言。

创建以后可能终于连你都不知道这样的语言是什么了。

4、採用命名约定,使程序猿非常easy看出某个标识符是否为#define宏。

5、仅仅要合适就应该使用文件包括。不必操心它的额外开销。

这个开销真的非常小,并且仅仅存在与编译中。执行中是没有的。

6、头文件仅仅应该包括一组函数或者数组的声明。

7、把不同集合的声明分离到不同的头文件里能够改善信息隐藏。

8、嵌套的#include文件使我们非常难推断源文件之间的依赖关系。

所以尽量降低#include文件的嵌套。





问题:

1、#define与字面值常量的长处。

可读性好。能够给常量起个自己能看懂的名字。

假设想改动常量的数值,仅仅须要改动define的内容即可,方便。

2、编写一个用于调试的宏,打印出随意的表达式。它被调用时应该接受两个參数。第1个是printf格式码,第2个是须要打印的表达式。

#define DEBUG_PRINT(format, value)  printf("File %s, line %d: %s = " format "\n",\

__FILE__, __LINE__, #value, value);

版权声明:本文博主原创文章,博客,未经同意不得转载。

C和指针 (pointers on C)——第十四章:预处理器的更多相关文章

  1. C和指针 第十四章 预处理器 头文件

    编写一个C程序,第一个步骤称为预处理,预处理在代码编译之前,进行一些文本性质的操作,删除注释.插入被include的文件.定义替换由#define定义的符号,以及确定代码的部分内容是否应该按照条件编译 ...

  2. 《Linux命令行与shell脚本编程大全》 第十四章 学习笔记

    第十四章:呈现数据 理解输入与输出 标准文件描述符 文件描述符 缩写 描述 0 STDIN 标准输入 1 STDOUT 标准输出 2 STDERR 标准错误 1.STDIN 代表标准输入.对于终端界面 ...

  3. JavaScript高级程序设计:第十四章

    第十四章 一.表单的基础知识 在HTML中,表单是由<form>元素来表示的,而在javascript中,表单对应的则是HTMLFormElement类型.HTMLFormElement继 ...

  4. C++ Primer Plus学习:第十四章

    第十四章 C++中的代码重用 包含对象成员的类 将类的对象作为新类的成员.称为has-a关系.使用公有继承的时候,类可以继承接口,可能还有实现(纯虚函数不提供实现,只提供接口).使用包含时,可以获得实 ...

  5. 【C++】《C++ Primer 》第十四章

    第十四章 重载运算与类型转换 一.基本概念 重载运算符是具有特殊名字的函数:由关键字operator和其后要定义的运算符号共同组成.也包含返回类型.参数列表以及函数体. 当一个重载的运算符是成员函数时 ...

  6. perl 第十四章 Perl5的包和模块

    第十四章 Perl5的包和模块 by flamephoenix 一.require函数  1.require函数和子程序库  2.用require指定Perl版本二.包  1.包的定义  2.在包间切 ...

  7. Gradle 1.12 翻译——第十四章. 教程 - 杂七杂八

    有关其它已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或訪问:http://gradledoc.qiniudn.com ...

  8. CSS3秘笈复习:十三章&十四章&十五章&十六章&十七章

    第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮 ...

  9. C#语言和SQL Server第十三 十四章笔记

    十三章  使用ADO.NET访问数据库 十四章使用ADO.NET查询和操作数据库 十三章:                                                       ...

随机推荐

  1. java学习笔记07--日期操作类

    java学习笔记07--日期操作类   一.Date类 在java.util包中定义了Date类,Date类本身使用非常简单,直接输出其实例化对象即可. public class T { public ...

  2. Android 的Google+平台

    Google+是谷歌推出的身份服务和社交网站.也是Google各种服务社交层面的补强.是世界上第二大的社交网站.一旦用户登录到Google,你就可以按照自己的需要定制服务和使用你的应用程序.

  3. KMP算法的Next数组详解(转)

    转载请注明来源,并包含相关链接. 网上有很多讲解KMP算法的博客,我就不浪费时间再写一份了.直接推荐一个当初我入门时看的博客吧: http://www.cnblogs.com/yjiyjige/p/3 ...

  4. ImportError: No module named _sqlite3 - 代码分享

    ImportError: No module named _sqlite3 - 代码分享 ImportError: No module named _sqlite3 作者:86市场网       点击 ...

  5. Java程序猿之从菜鸟到职场高手的必看

    J2SE之入门引导            Java基础系列之初识JAVA                                           Java基础系列之Java语法       ...

  6. 第一章. ActionScript 语言基础

    第一章. ActionScript 语言基础 1.0. ActionScript 3.0 Cookbook 概述 1.1. 新建一个 ActionScript project 1.2. 自己定义应用程 ...

  7. 深入java并发Lock一

    java有像syncronized这种内置锁,但为什么还须要lock这种外置锁? 性能并非选择syncronized或者lock的原因,jdk6中syncronized的性能已经与lock相差不大. ...

  8. 【译】ASP.NET MVC 5 教程 - 4:添加模型

    原文:[译]ASP.NET MVC 5 教程 - 4:添加模型 在本节中,我们将添加一些管理电影数据库的类,这些类在ASP.NET MVC 应用程序中扮演“Model”的角色. 我们将使用.NET F ...

  9. Oracle 最简单的随系统自己主动启动

    Oracle 最简单的随系统自己主动启动 俗话说用户是上帝,他们有时候提出一个问题很的简单,就仅仅须要一句话,一分钟就完事了.可是拿到我们DBA来说,可能至少得半个小时甚至半个月才干满足他的一句话.有 ...

  10. openstack学习笔记一 虚拟机启动过程代码跟踪

    openstack学习笔记一 虚拟机启动过程代码跟踪 本文主要通过对虚拟机创建过程的代码跟踪.观察虚拟机启动任务状态的变化,来透彻理解openstack各组件之间的作用过程. 当从horizon界面发 ...