C语言预处理及特殊函数介绍(extern/exit/atexit/volatile/static/calloc/realloc等)PART ONE

来源:互联网 发布:上海地铁客流量数据 编辑:程序博客网 时间:2024/06/08 11:10

1).#include 预处理命令

#include 命令有如下两种形式:

#include <filename>#include "filename"


它们的差别在于查找欲包含文件的起始位置不同。

用引号括起来:预处理程序就会从待编译文件所在待编译目录里开始查找欲包含的文件,这种方法通常用于包含程序员定义的头文件。

用<>:用于标准函数库的头文件,预处理程序就会按照一种依赖于系统实现的方式,通常是在预先指定的编译器和系统目录中进行查找。


2).条件编译

条件编译使用户能够控制预处理命令的执行以及对程序代码的编译。每一个条件预处理命令都要计算一个整型常量表达式的值。但是类型强转表达式、sizeof表达式及枚举常量的值不能再预处理命令中计算。

如下代码:

#if !defined(MY_CONSTANT)#define MY_CONSTANT 0#endif


首先判断MY_CONSTANT是否被定义了。如果定义了,则表达式defined(MY_CONSTANT)的值为1,否则为0.如果该表达式的值为0,则!defined(MY_CONSTANT)的值久为1,于是就定义MY_CONSTANT,否则#define预处理命令就被略过。

每个#if结构都以#endif来结束。预处理命令#ifdef和#ifndef是#if defined(name)和#if !defined(name)的缩写形式。对于多分枝的条件预处理结构,需使用命令#elif(等价于if语句中的else if)和#else(等价于if语句中的else)来测试。


3).#error和#pragma预处理命令

#error tokens的功能是:打印出包含命令中指定tokens(标记)的信息,信息的具体内容与系统的实现有关。标记是用空格分割的一个字符序列。

如:

#error 1 - Out of range error


包含了6个标记。当在系统中执行#error命令时,命令中的标记将被作为出错信息显示出来,然后终止预处理,并停止程序编译。


#pragma tokens的功能是:执行一个系统实现中已经定义好的操作。不能被系统实现识别出来的pragma将被忽略掉。


4).#和##运算符

#和##只在标准C中有效。其中,#运算符将替换文本中的标记转换成一个用引号引起来的字符串。如下

#define HELLO(x) printf("HELLO," #x "\n");/*当程序中出现HELLO(John)时,它将被展开成:*/printf(HELLO," "John" "\n");


#运算符必须用在一个带实参的宏中,因为#的操作数就是宏的实参。


##运算符用于将两个标记拼接在一起。如:

#define TOKENCONCAT(x,y) x##y


当程序中出现TOKENCONCAT时,它的两个实参将被拼接在一起并用来代替宏。##运算符必须有两个操作数。


5).I/O的重定向

如:事先存储输入数据的文件为input,命令行:

$ sum < input


就会从文件input中读取数据来执行程序sum。输入重定向符“<”表示文件input中的数据将被程序用作输入。


第二种实现输入重定向的方法是管道技术。一个管道符“|”将一个程序的输出重定向到一个程序的输入上。建设程序random输出的是一系列的随机整数,那么命令:


$ random | sum


使程序中random的输出通过“管道”直接“流进”程序sum的输入。这个程序的作用是计算由程序random产生的整数的总和。


程序的输出可以领用输出重定向符“>”来重定向到一个文件中。如命令:

$ random > out


将random的输出重定向到文件out中。


可利用添加输出符">>"将一个程序的输出添加到一个已有文件的末尾。如可以通过如下命令将程序random的输出添加到在上面那条命令中已创建的文件out的末尾:

$ random >> out


6).多个源文件组成的程序的编译问题

在所有函数定义之外生命的变量被默认为静态存储类型,并被视为全局变量。全局变量可以被同一个文件中位于变量声明之后定义的任何函数访问。全局变量还可以被其他文件中的函数访问,前提条件是:在使用全局变量 的每一个文件中,都必须对这些全局变量进行声明。

例如:一个文件若想使用另外一个文件中定义的全局整型变量flag,那么该文件必须在使用这个变量钱包含如下的声明语句:

extern int flag;


这个语句使用存储类型说明符extern来声明变量flag要么将在本文件的后面定义,要么是在另外一个文件中定义的。

函数原型也可以将它的作用于扩展到定义它的文件之外(在函数原型中并不需要extern说明符)。为了达到这一目的只需简单的将函数原型包含在每一个想调用它的文件里。


7).static关键字

在实际工作中可能需要讲一个全局变量或者一个函数的作用域限制在定义它的文件之内。将static类型说明符应用于全局变量或函数时,就可以阻止在被文件之外定义的函数访问它们。这杯成为内部链接。定义前面没有加上static的全局变量或者函数都是外部链接。例如:

static const double PI = 3.1415;


串讲了一个类型为double的常量PI,并将其初始化为3.1415,同时表明PI仅仅能够被定义它的文件中的函数所识别。

说明符static通常用在仅能被特定文件中的函数所调用的使用函数中。如果一个函数不需要再一个特定的文件之外使用,则应遵循最小权限原则对它加上static说明符.

0 0