目录

  • 1 第一章 C语言简介
    • 1.1 C语言前世今生
    • 1.2 主流开发环境介绍
    • 1.3 第一个小程序解析
    • 1.4 常见编译错误
    • 1.5 章节知识点小结
  • 2 算法基础
    • 2.1 算法-程序的灵魂
    • 2.2 算法的描述-流程图
  • 3 数据类型与运算符
    • 3.1 数据描述
    • 3.2 运算符和表达式1
    • 3.3 运算符和表达式2
    • 3.4 章节知识点小结
  • 4 顺序结构程序设计
    • 4.1 输入和输出
    • 4.2 顺序结构程序设计
    • 4.3 章节知识点小结
  • 5 选择结构程序设计
    • 5.1 关系运算符和关系表达式
    • 5.2 逻辑运算符和逻辑表达式
    • 5.3 if语句
    • 5.4 条件运算符
    • 5.5 switch语句
    • 5.6 章节知识点小结
  • 6 循环结构程序设计
    • 6.1 while循环结构
    • 6.2 do_while循环结构
    • 6.3 for循环结构
    • 6.4 循环的嵌套
    • 6.5 break语句和continue语句
    • 6.6 章节知识点小结
  • 7 数组
    • 7.1 一维数组
    • 7.2 二维数组
    • 7.3 字符数组
    • 7.4 章节知识点小结
  • 8 函数
    • 8.1 子程序设计
    • 8.2 函数定义
    • 8.3 函数的调用
    • 8.4 局部变量和全局变量
    • 8.5 参数传递
    • 8.6 函数递归调用
    • 8.7 章节知识点小结
  • 9 指针
    • 9.1 指针的基本概念
    • 9.2 指针变量的定义及引用
    • 9.3 通过指针引用数组元素
    • 9.4 指向多维数组的指针和指针变量
    • 9.5 用指向数组的指针作函数参数
    • 9.6 指针与字符串
    • 9.7 函数指针和指针函数
    • 9.8 章节知识点小结
  • 10 用户自己建立数据类型
    • 10.1 定义和使用结构体变量
    • 10.2 使用结构体数组
    • 10.3 结构体指针
    • 10.4 章节知识点小结
  • 11 编译预处理
    • 11.1 宏定义预处理
    • 11.2 文件包含预处理
    • 11.3 条件编译预处理
    • 11.4 章节知识点小结
  • 12 文件
    • 12.1 文件的基本知识
    • 12.2 文件的基本操作
    • 12.3 章节知识点小结
条件编译预处理

预处理器还提供了条件编译功能。在预处理时,按照不同的条件去编译程序的不同部分,从而得到不同的目标代码。  使用条件编译,可方便地处理程序的调试版本和正式版本,也可使用条件编译使程序的移植更方便

3.1使用#if


与C语言的条件分支语句类似,在预处理时,也可以使用分支,根据不同的情况编译不同的源代码段。


#if 的使用格式如下:

1
2
3
4
5
#if 常量表达式
   程序段
#else
  程序段
#endif

 

该条件编译命令的执行过程为:若常量表达式的值为真(非0),则对程序段1进行编译,否则对程序段2进行编译。因此可以使程序在不同条件下完成不同的功能。

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define DEBUG 1
int main()
{
   int i,j;
   char ch[26];
   for(i='a';j=0;i<='z';i++,j++)
   {
       ch[j]=i;
       #if DEBUG
          printf("ch[%d]=%c\n",j,ch[j]);
       #endif
   } 
   for(j=0;j<26;j++)
   {
       printf("%c",ch[j]);
   }
   return 0;
}

  

#if预编译命令还可使用多分支语句格式,具体格式如下:

1
2
3
4
5
6
7
8
9
10
#if 常量表达式 1
    程序段 1
#elif 常量表达式 2
    程序段 2
… …
#elif 常量表达式 n
    程序段 n
#else
    程序段 m
#endif

 

关键字#elif与多分支if语句中的else if类似。
举个例子

1
2
3
4
5
6
7
8
#define os win
#if os=win
    #include"win.h"
#elif os=linux
    #include"linux.h"
#elif os=mac
    #include"mac.h"
#endif

 

#if和#elif还可以进行嵌套,C89标准中,嵌套深度可以到达8层,而C99允许嵌套达到63层。在嵌套时,每个#endif,#else或#elif与最近的#if或#elif配对。
Eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#define MAX 100
#define OLD -1
int main()
{
int i;
#if MAX>50
    #if OLD>3
    {
        i=1;
    {
    #elif OLD>0
    {
        i=2; 
    }
    #else
    {
        i=3; 
    }
    #endif
}
#else
{ 
    #if OLD>3
    {
        i=4;
    }
    #elif OLD>4
    {
        i=5;
    }
    #else
    {
        i=6; 
    }
    #endif
}
#endif
return 0; 
}

 

3.2使用#ifdef和#ifndef
 
在上面的#if条件编译命令中,需要判断符号常量定义的具体值。在很多情况下,其实不需要判断符号常量的值,只需要判断是否定义了该符号常量。这时,可不使用#if命令,而使用另外一个预编译命令———#ifdef.

1
2
3
4
5
6
7
8
9
#ifdef命令的使用格式如下:
#ifdef 标识符
程序段 1
 
#else
 
    程序段 2
 
#endif

其意义是,如果#ifdef后面的标识符已被定义过,则对“程序段1”进行编译;如果没有定义标识符,则编译“程序段2”。一般不使用#else及后面的“程序2”。

而#ifndef的意义与#ifdef相反,其格式如下:

1
2
3
4
5
6
7
8
#ifndef 标识符
    程序段 1
 
#else
 
    程序段 2
 
#endif

其意义是:如果未定义标识符,则编译“程序段1”;否则编译“程序段2”


3.3使用#defined和#undef
 
与#ifdef类似的,可以在#if命令中使用define来判断是否已定义指定的标识符。例如:

1
2
3
4
#if defined 标识符
程序段 1 
 
#endif

 

与下面的标示方式意义相同。

1
2
3
4
#ifdef 标识符
    程序段 1
 
#endif

 

也可使用逻辑运算符,对defined取反。例如:

1
2
3
4
#if ! define 标识符
    程序段 1
 
#endif

 

与下面的标示方式意义相同。

1
2
3
4
#ifndef 标识符
    程序段 1
 
#endif

 

在#ifdef和#ifndef命令后面的标识符是使用#define进行定义的。在程序中,还可以使用#undef取消对标识符的定义,其形式为:

1
#undef 标识符  


举个例子:

1
2
3
4
5
#define MAX 100
 
……
 
#undef MAX

 

在以上代码中,首先使用#define定义标识符MAX,经过一段程序代码后,又可以使用#undef取消已定义的标识符。使用#undef命令后,再使用#ifdef max,将不会编译后的源代码,因为此时标识符MAX已经被取消定义了。