当前位置: 首页 > news >正文

东莞网上做公司网站深圳做网站公司哪家好

东莞网上做公司网站,深圳做网站公司哪家好,安卓系统app开发,建设网站 安全事项文章目录 #undef指令从C预处理器角度看已定义条件编译1.#ifdef、#else和#endif指令 #ifndef指令#ifndef指令通常用于防止多次包含一个文件程序使用#ifndef避免文件被重复包含 #if和#elif指令条件编译还有一个用途是让程序更容易移植 参考 程序员可能要为不同的工作环境准备C程序…

文章目录

  • #undef指令
  • 从C预处理器角度看已定义
  • 条件编译
    • 1.#ifdef、#else和#endif指令
  • #ifndef指令
    • #ifndef指令通常用于防止多次包含一个文件
    • 程序使用#ifndef避免文件被重复包含
  • #if和#elif指令
    • 条件编译还有一个用途是让程序更容易移植
  • 参考

程序员可能要为不同的工作环境准备C程序和C库包。不同的环境可能
使用不同的代码类型。预处理器提供一些指令,程序员通过修改#define的值
即可生成可移植的代码。#undef指令取消之前的#define定义。#if、#ifdef、
#ifndef、#else、#elif和#endif指令用于指定什么情况下编写哪些代码。#line
指令用于重置行和文件信息,#error指令用于给出错误消息,#pragma指令用
于向编译器发出指令。

#undef指令

#undef指令用于“取消”已定义的#define指令。也就是说,假设有如下定义:

#define LIMIT 400

然后,下面的指令:

#undef LIMIT

将移除上面的定义。现在就可以把LIMIT重新定义为一个新值。即使原
来没有定义LIMIT,取消LIMIT的定义仍然有效。如果想使用一个名称,又
不确定之前是否已经用过,为安全起见,可以用#undef 指令取消该名字的定
义。

从C预处理器角度看已定义

处理器在识别标识符时,遵循与C相同的规则:标识符可以由大写字
母、小写字母、数字和下划线字符组成
且首字符不能是数字。当预处理器
在预处理器指令中发现一个标识符时,它会把该标识符当作已定义的或未定
义的。这里的已定义表示由预处理器定义。如果标识符是同一个文件中由前
面的#define指令创建的宏名,而且没有用#undef 指令关闭,那么该标识符是
已定义的。如果标识符不是宏,假设是一个文件作用域的C变量,那么该标
识符对预处理器而言就是未定义的。

已定义宏可以是对象宏,包括空宏或类函数宏:

#define LIMIT 1000 // LIMIT是已定义的
#define GOOD // GOOD 是已定义的
#define A(X) ((-(X))*(X)) // A 是已定义的
int q; // q 不是宏,因此是未定义的
#undef GOOD // GOOD 取消定义,是未定义的

注意,#define宏的作用域从它在文件中的声明处开始,直到用#undef指
令取消宏为止,或延伸至文件尾(以二者中先满足的条件作为宏作用域的结
束)。

另外还要注意,如果宏通过头文件引入,那么#define在文件中的位置
取决于#include指令的位置。

稍后将介绍几个预定义宏,如__DATE__和__FILE__。这些宏一定是已
定义的,而且不能取消定义。

条件编译

可以使用其他指令创建条件编译(conditinal compilation)。也就是说,
可以使用这些指令告诉编译器根据编译时的条件执行或忽略信息(或代码)
块。

1.#ifdef、#else和#endif指令

我们用一个简短的示例来演示条件编译的情况。考虑下面的代码:

#ifdef MAVIS#include "horse.h"// 如果已经用#define定义了 MAVIS,则执行下面的指令#define STABLES 5
#else#include "cow.h" //如果没有用#define定义 MAVIS,则执行下面的指令#define STABLES 15
#endif

这里使用的较新的编译器和 ANSI 标准支持的缩进格式。如果使用旧的
编译器,必须左对齐所有的指令或至少左对齐#号,如下所示:

#ifdef MAVIS
#	include "horse.h" // 如果已经用#define定义了 MAVIS,则执行下面的指令
#	define STABLES 5
#else
#	include "cow.h" //如果没有用#define定义 MAVIS,则执行下面的指令
#	define STABLES 15
#endif

#ifdef指令说明,如果预处理器已定义了后面的标识符(MAVIS),则
执行#else或#endif指令之前的所有指令并编译所有C代码(先出现哪个指令
就执行到哪里)。如果预处理器未定义MAVIS,且有 #else指令,则执行
#else和#endif指令之间的所有代码。

#ifdef #else很像C的if else。两者的主要区别是,预处理器不识别用于标
记块的花括号({}),因此它使用#else(如果需要)和#endif(必须存在)
来标记指令块。这些指令结构可以嵌套。也可以用这些指令标记C语句块

ifdef.c程序

/* ifdef.c -- 使用条件编译 */
#include <stdio.h>
#define JUST_CHECKING
#define LIMIT 4
int main(void){int i;int total = 0;for (i = 1; i <= LIMIT; i++){total += 2 * i*i + 1;#ifdef JUST_CHECKINGprintf("i=%d, running total = %d\n", i, total);#endif}printf("Grand total = %d\n", total);return 0;
}

编译并运行该程序后,输出如下:

i=1, running total = 3
i=2, running total = 12
i=3, running total = 31
i=4, running total = 64
Grand total = 64

如果省略JUST_CHECKING定义(把它放在C注释中,或者使用#undef指
令取消它的定义)并重新编译该程序,只会输出最后一行。可以用这种方法
在调试程序。

定义JUST_CHECKING并合理使用#ifdef,编译器将执行用于
调试的程序代码,打印中间值。调试结束后,可移除JUST_CHECKING定义
并重新编译。如果以后还需要使用这些信息,重新插入定义即可。这样做省
去了再次输入额外打印语句的麻烦。

#ifdef还可用于根据不同的C实现选择合适的代码块。

#ifndef指令

#ifndef指令与#ifdef指令的用法类似,也可以和#else、#endif一起使用,
但是它们的逻辑相反。#ifndef指令判断后面的标识符是否是未定义的,常用
于定义之前未定义的常量。如下所示:

/* arrays.h */
#ifndef SIZE
#define SIZE 100
#endif

(旧的实现可能不允许使用缩进的#define)

通常,包含多个头文件时,其中的文件可能包含了相同宏定义。#ifndef
指令可以防止相同的宏被重复定义。在首次定义一个宏的头文件中用#ifndef
指令激活定义,随后在其他头文件中的定义都被忽略。
#ifndef指令还有另一种用法。假设有上面的arrays.h头文件,然后把下面
一行代码放入一个头文件中:

#include "arrays.h"

SIZE被定义为100。
但是,如果把下面的代码放入该头文件:

#define SIZE 10
#include "arrays.h"

SIZE则被设置为10。这里,当执行到#include "arrays.h"这行,处理
array.h中的代码时,由于SIZE是已定义的,所以跳过了#define SIZE 100这行
代码。鉴于此,可以利用这种方法,用一个较小的数组测试程序。测试完毕
后,移除#define SIZE 10并重新编译。这样,就不用修改头文件数组本身
了。

#ifndef指令通常用于防止多次包含一个文件

#ifndef指令通常用于防止多次包含一个文件。也就是说,应该像下面这
样设置头文件:

/* things.h */
#ifndef THINGS_H_
#define THINGS_H_
/* 省略了头文件中的其他内容*/
#endif

假设该文件被包含了多次。当预处理器首次发现该文件被包含时,
THINGS_H_是未定义的,所以定义了THINGS_H_,并接着处理该文件的其
他部分。当预处理器第2次发现该文件被包含时,THINGS_H_是已定义的,
所以预处理器跳过了该文件的其他部分。

为何要多次包含一个文件?

最常见的原因是,许多被包含的文件中都包含着其他文件,所以显式包含的文
件中可能包含着已经包含的其他文件。

这有什么问题?

在被包含的文件中有某些项(如,一些结构类型的声明)只能
在一个文件中出现一次。C标准头文件使用#ifndef技巧避免重复包含。

但是,这存在一个问题:
如何确保待测试的标识符没有在别处定义。通常使用这些方法
解决这个问题:

用文件名作为标识符、使用大写字母、用下划线字符代替文件名中的点字符、
用下划线字符做前缀或后缀(可能使用两条下划线)。

例如,查看stdio.h头文件,可以发现许多类似的代码:

#ifndef _STDIO_H
#define _STDIO_H
// 省略了文件的内容
#endif

你也可以这样做。但是,由于系统标准库使用下划线作为前缀,所以在自
己的代码中不要这样写,避免与标准头文件中的宏发生冲突。

程序使用#ifndef避免文件被重复包含

names.c程序

// names.h --修订后的 names_st 头文件,避免重复包含
#ifndef NAMES_H_
#define NAMES_H_
// 明示常量
#define SLEN 32
// 结构声明
struct names_st
{char first[SLEN];char last[SLEN];
};
// 类型定义
typedef struct names_st names;
// 函数原型
void get_names(names *);
void show_names(const names *);
char * s_gets(char * st, int n);
#endif

下面程序测试该头文件没问题,但是如果把#ifndef保护删除后,程序就无法通过编译。
doubincl.c程序:

// doubincl.c -- 包含头文件两次
#include <stdio.h>
#include "names.h"
#include "names.h" // 不小心第2次包含头文件
int main(){names winner = { "Less", "Ismoor" };printf("The winner is %s %s.\n", winner.first,winner.last);return 0;
}

#if和#elif指令

#if指令很像C语言中的if#if后面跟整型常量表达式,如果表达式为非
零,则表达式为真。可以在指令中使用C的关系运算符和逻辑运算符:

#if SYS == 1
#include "ibm.h"
#endif

可以按照if else的形式使用#elif(早期的实现不支持#elif)。例如,可
以这样写:

#if SYS == 1
#include "ibmpc.h"
#elif SYS == 2
#include "vax.h"
#elif SYS == 3
#include "mac.h"
#else
#include "general.h"
#endif

较新的编译器提供另一种方法测试名称是否已定义,即用

#if defined(VAX)

代替

#ifdef VAX

这里,defined是一个预处理运算符,如果它的参数是用#defined定义
过,则返回1;否则返回0。
这种新方法的优点是,它可以和#elif一起使用。

下面用这种形式重写前面的示例:

#if defined (IBMPC)
#include "ibmpc.h"
#elif defined (VAX)
#include "vax.h"
#elif defined (MAC)
#include "mac.h"
#else
#include "general.h"
#endif

如果在VAX机上运行这几行代码,那么应该在文件前面用下面的代码定
义VAX:

#define VAX

条件编译还有一个用途是让程序更容易移植

条件编译还有一个用途是让程序更容易移植。改变文件开头部分的几个
关键的定义,即可根据不同的系统设置不同的值和包含不同的文件。

参考

《C Primer Plus》

http://www.yidumall.com/news/55385.html

相关文章:

  • 深圳网站建设网牛天下整站seo技术
  • 网站建设总结报告b2b平台免费推广网站
  • 西安品牌网站建设大庆网络推广
  • 网站qq客服不添加好友搜索引擎广告优化
  • 做影视网站代理犯法吗怎么弄一个自己的网址
  • 软文营销的案例百度关键词排名优化
  • 个人怎么注册网站网络营销方案ppt
  • c 中怎么用html5做网站丹东网站seo
  • 无锡专业网站营销容易被百度收录的网站
  • 西宁手机网站建设百度竞价点击一次多少钱
  • 自己做网站选什么好企业seo顾问服务阿亮
  • 艺术公司网站定制中心网站开发需要的技术
  • 网站别人帮做的要注意什么东西app广告投放价格表
  • wordpress中如何添加面包屑信阳网站seo
  • 镇江企业网站制作全球新冠疫情最新消息
  • 2022年网络热点事件舆情案例seo技术培训广东
  • 免费的国际网站建设google搜索首页
  • 为朋友做的网站深圳百度推广
  • 建设旅游网站财务分析网站首页面设计
  • 宝安做棋牌网站建设哪家服务好中国万网域名注册官网
  • 做网站有什么关于财务的问题百度助手app下载安装
  • 国内家居行业网站开发网络seo营销推广
  • 微网站开发商惠州百度seo地址
  • 建立石墨碳素网站怎么做百度开户公司
  • 哪里有零基础网站建设教学北京seo全网营销
  • 鹤山市住房和城乡建设局网站网络营销产品策略
  • 拥有自己的网站 如何做推广今日新闻网
  • wordpress第三方源码沈阳seo关键字优化
  • 手机网站 数据库中文域名交易网站
  • 做网站和易语言整站排名服务