Menu Close

预处理命令概述 – C语言

前面各章中,已经多次使用过#include命令。使用库函数之前,应该用#include引入对应的头文件。这种以#号开头的命令称为预处理命令。

C 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理。我们将把 C 预处理器(C Preprocessor)简写为 CPP。

所有的预处理器命令都是以井号(#)开头。它必须是第一个非空字符,为了增强可读性,预处理器指令应从第一列开始。

下面列出了所有重要的预处理器指令:

C语言代码要经过编译和链接才能生成可执行程序:

编译是针对单个源文件(.c 文件)的,有多少个源文件就生成多少个目标文件,并且在生成过程中不受其他源文件的影响。也就是说,每个源文件都是独立编译的。

链接器的作用就是将这些目标文件拼装成一个可执行程序,并为代码(函数)和数据(变量、字符串等)分配好虚拟地址,这和搭积木的过程有点类似。

编译的原理比较复杂,涉及到大量的算法和正则表达式,我们这门课不涉及C语言的编译。

在实际开发中,有时候在编译之前还需要对源文件进行简单的处理。例如,我们希望自己的程序在 Windows 和 Linux 下都能够运行,那么就要在 Windows 下使用 VS 编译一遍,然后在 Linux 下使用 GCC 编译一遍。

但是现在有个问题,程序中要实现的某个功能在 VS 和 GCC 下使用的函数不同(假设 VS 下使用 a(),GCC 下使用 b()),VS 下的函数在 GCC 下不能编译通过,GCC 下的函数在 VS 下也不能编译通过,怎么办呢?

这就需要在编译之前先对源文件进行处理:如果检测到是 VS,就保留 a() 删除 b();如果检测到是 GCC,就保留 b() 删除 a()。

这些在编译之前对源文件进行简单加工的过程,就称为预处理(即预先处理、提前处理)。

预处理主要是处理以#开头的命令,例如#include <stdio.h>等。预处理命令要放在所有函数之外,而且一般都放在源文件的前面。

预处理是C语言的一个重要功能,由预处理程序完成。当对一个源文件进行编译时,系统将自动调用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入对源程序的编译。

编译器会将预处理的结果保存到和源文件同名的.i文件中,例如 main.c 的预处理结果在 main.i 中。和.c一样,.i也是文本文件,可以用编辑器打开直接查看内容。

C语言提供了多种预处理功能,如宏定义、文件包含、条件编译等,合理地使用它们会使编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。

#include命令

#include 是文件包含命令,主要用来引入对应的头文件。#include 的处理过程很简单,就是将头文件的内容插入到该命令所在的位置,从而把头文件和当前源文件连接成一个源文件,这与复制粘贴的效果相同。

#include有两种使用方式:

#include <stdio.h>
#include "myHeader.h"

使用尖括号< >和双引号” “的区别在于头文件的搜索路径不同,包含标准库的头文件建议用尖括号,包含自定义的头文件建议用双引号。

使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的),而不在源文件目录去查找;使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中去查找。

用户编程时可根据自己文件所在的目录来选择某一种命令形式。

说明:

  • 一个 #include 命令只能包含一个头文件,多个头文件需要多个 #include 命令;
  • 文件包含允许嵌套,也就是说在一个被包含的文件中又可以包含另一个文件。

不同的头文件下包含不同的库函数

不同的头文件下的库函数

C 头文件 描述
<assert.h> 程序断言函数
<ctype.h> 字符类型函数
<locale.h> 本地化功能
<math.h> 数学函数
<setjmp.h> 跳转功能函数
<signal.h> 信号处理函数
<stdarg.h> 可变参数处理函数
<stdio.h> 标准输入输出函数
<stdlib.h> 标准实用功能函数
<string.h> String handling functions
<time.h> 时间日期函数

程序断言函数 – 断言函数,用于在调试过程中捕捉程序的错误。

“断言”在语文中的意思是“断定”、“十分肯定地说”,在编程中是指对某种假设条件进行检测,如果条件成立就不进行任何操作,如果条件不成立就捕捉到这种错误,并打印出错误信息,终止程序执行。

assert() 会对表达式expression进行检测:

  • 如果expression的结果为 0(条件不成立),那么断言失败,表明程序出错,assert() 会向标准输出设备(一般是显示器)打印一条错误信息,并调用 abort() 函数终止程序的执行;
  • 如果expression的结果为非 0(条件成立),那么断言成功,表明程序正确,assert() 不进行任何操作

在大部分编译器下,assert() 是一个宏;在少数的编译器下,assert() 就是一个函数。我们无需关心这些差异,只管把 assert() 当做函数使用即可。

assert() 的用法很简单,我们只要传入一个表达式,它会计算这个表达式的结果:如果表达式的结果为“假”,assert() 会打印出断言失败的信息,并调用 abort() 函数终止程序的执行;如果表达式的结果为“真”,assert() 就什么也不做,程序继续往后执行。

例1.

#include <stdio.h>
#include <assert.h>
int main(){
    int m, n, result;
    scanf("%d %d", &m, &n);
    assert(n != 0);  //写作 assert(n) 更加简洁
    result = m / n;
    printf("result = %d\n", result);
    return 0;
}
断言函数
断言函数

Standard Utility Functions (stdlib.h) (选修)

  • abort – Abnormal termination of a program
  • abs – Integer absolute value (magnitude)
  • assert – Macro for Debugging Diagnostics
  • atexit – Request execution of functions at program exit
  • atof – String to double or float
  • atoi – String to integer
  • bsearch – Binary search
  • calloc – Allocate space for arrays
  • div – Divide two integers
  • ecvtbuf – Double or float to string of digits
  • ecvt – Double or float to string of digits (malloc result)
  • __env_lock – Lock environment list for getenv and setenv
  • gvcvt – Format double or float as string
  • exit – End program execution
  • getenv – Look up environment variable
  • labs – Long integer absolute value (magnitude)
  • ldiv – Divide two long integers
  • malloc – Allocate memory
  • realloc – Reallocate memory
  • free – Free previously allocated memory
  • mallinfo – Get information about allocated memory
  • __malloc_lock – Lock memory pool for malloc and free
  • mbstowcs – Minimal multibyte string to wide string converter
  • mblen – Minimal multibyte length
  • mbtowc – Minimal multibyte to wide character converter
  • qsort – Sort an array
  • rand – Pseudo-random numbers
  • strtod – String to double or float
  • strtol – String to long
  • strtoul – String to unsigned long
  • system – Execute command string
  • wcstombs – Minimal wide string to multibyte string converter
  • wctomb – Minimal wide character to multibyte converter

例1.计算一个数的平方根

#include <stdio.h>
#include <math.h>
int main()
{
   float num, root;
   printf("Enter a number: ");
   scanf("%f", &num);

   // Computes the square root of num and stores in root.
   root = sqrt(num);

   printf("Square root of %.2f = %.2f", num, root);
   return 0;
}

结果

Enter a number: 12
Square root of 12.00 = 3.46

 

除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

Leave the field below empty!

Posted in C语言教程

Related Posts