【编程基础】聊聊C语言-兵马未动粮草先行(2)

上一篇我们讲了C语言预处理阶段的宏定义,知道了C语言中宏定义的处理和使用。现将上篇关于宏的问题的答案公布如下:

  1. 用宏定义一个字符串常量 #define str "abc"
  2. 用带参数的宏实现求两个数的最小值 #define MAX(a,b)((a)<(b)?(a):(b))
  3. 用带##的宏实现两个字符串的连接 #define FUN(a,b) ##_##

我们这篇讲讲预处理阶段的文件包含和条件编译。

一.文件包含

什么是文件包含?

文件包含的格式如下:

#include"文件名"

通常,该文件是后缀名为"h""的头文件。文件包含命令把指定头文件插入该命令行位置取代该命令行,从而把指定的文件和当前的源程序文件连成一个源文件。简单的说就是直接粘贴到本文件中。

文件包含的作用

在程序设计中,文件包含是很有用的。一个大程序可以分为多个模块,而程序中的有些公用的符号常量或宏定义等可单独组成一个文件,在其它文件的开头用包含命令包含该文件即可使用。这样可避免在每个文件开头都去书写那些公用量,从而节省时间,并减少出错。

文件包含需要注意的

  • 包含命令中的文件名可用双引号括起来,也可用尖括号括起来,如#include"myhead.h"和#include<myhead.h>。这两种形式的区别是:使用尖括号表示在系统指定的包含头文件的路径中查栈,不在当前目录下查找;使用双引号则表示先在当前目录中查找,若未找到才到系统指定的目录下查找。一般系统提供的头文件我们用尖括号,自己书写的头文件我们用双引号。
  • 一个include命令只能指定一个被包含文件,若有多个文件要包含,则需用多个include命令。
  • 文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。

二.条件编译

条件编译的作用

通常我们编写的源文件中的代码都参加编译。但有时我们需要在满足一定的条件下再去编译一部分,不满足则编译另一个部分,这就是“条件编译”。

条件编译功能可按不同的条件去编译不同的程序部分,从而产生不同的目标代码文件。在程序的移植和调试中我们经常用到。

条件编译的形式

1.#ifdef形式

#ifdef 标识符 (或#if defined标识符)

程序段1

#else

程序段2

#endif

如果标识符已被#define定义过,则对程序段1进行编译;否则对程序段2进行编译。如果没有程序段2(它为空),#else可以没有,即可以写为:

#ifdef 标识符 (或#if defined标识符)

程序段

#endif

2.#ifndef形式

#ifndef 标识符(或#if !(defined 标识符))

程序段1

#else

程序段2

#endif

如果标识符未被#define命令定义过,则对程序段1进行编译,否则对程序段2进行编译。这与#ifdef形式的功能正相反。

3.#if形式

#if 常量表达式

程序段1

#else

程序段2

#endif

如果常量表达式的值为真(非0),则对程序段1 进行编译,否则对程序段2进行编译。

到此C语言中常用到的预处理功能我们就介绍完毕了。大家有什么不明白的或者有什么意见可以关注下面的微信公众号,我们一起在线讨论。下面是针对这篇小编为留的练习题,请回答如下关于文件包含和条件编译的问题答案会在下一篇公布:

  1. 为了避免从当前目录下查找头文件我们文件包含时应该用尖括号还是双引号?
  2. 实现条件编译中形式一的一个例子

原文发布于微信公众号 - 程序员互动联盟(coder_online)

原文发表时间:2015-07-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从零开始学 Web 前端

从零开始学 Web 之 Ajax(二)PHP基础语法

浏览器是不识别 PHP 文件的,用浏览器发开 PHP 文件,只会显示 PHP 的源代码,所以 PHP 文件必须在服务器中执行。其实 apache 服务器也识别不...

1082
来自专栏深度学习之tensorflow实战篇

pycharm 或者其他Python IDE不支持中文编码的解决方案

Python的自带编辑器IDLE或者Python Shell在默认情况下都不支持中文编码,若在脚本程序中出现中文,则会出现一定的错误。 原因: 因为Python...

2844
来自专栏程序员互动联盟

android apk 防止反编译技术第二篇-运行时修改字节码

上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/3...

35611
来自专栏奔跑的蛙牛技术博客

synchronized 详解

那到底使用synchronized关键字是不是就是一个监视器? 不懂,理解的话可以向我发邮件gaomengjie_1@163.com,我虚心求教

593
来自专栏爱撒谎的男孩

struts核心配置文件详解(package)

3276
来自专栏互联网杂技

前端异步代码解决方案实践(一)

小程序框架提供丰富的原生API,可以方便调起微信提供的能力,如获取用户信息,本地存储,支付功能等。但大多数API为异步调用,需要传递成功或失败回调函数,例如wx...

1303
来自专栏技术博客

Asp.Net MVC对类HtmlHelper的自定义扩展方法以及如何调用

c# 扩展方法出来已久,介绍扩展方法的文章也很多,此处就不多介绍,如有不懂当然可以百度,google一下,园子当中也有超级多的讲解。

891
来自专栏编程

Golang中defer 的五个坑-第三部分

译注:全文总共有四篇,本文为同系列文章的第三篇 本文将侧重于讲解使用 defer 的一些技巧 如果你对 defer 的基本操作还没有清晰的认识,请先阅读这篇文章...

2015
来自专栏腾讯NEXT学位

Express进阶:从一个例子看路由分组机制

2715
来自专栏静晴轩

使用lua小技巧

Lua之sleep函数的实现 一个不幸的消息是Lua中没有内置sleep函数,我们需要DIY。有4种方法可以实现sleep函数,如下: 方法1 –在一个死循环中...

4524

扫码关注云+社区