文章目录
  1. 1. 预处理
    1. 1.1. 与处理器指令
    2. 1.2. 宏定义
  2. 2. #运算

Grand theft dora-静香

预处理

预处理流程图
预处理的大户如是一个C语言程序,程序可能包含指令。预处理会执行这个邪指令,并在处理过程中删除这些指令。

与处理器指令

  1. 宏定义:#define指定一个宏,#undef指令删除一个宏定义。
  2. 文件包含: #include指令导致一个吻指定文件的内容包含到程序中。
  3. 条件编译:#if、#ifdef、#elif、#else#endif指令可以根据预处理器可以测试的条件来确定是将一段文本块包含到程序中还是排除在程序外。
  4. 特殊指令:#error、#line、#pragma

注意:

  • 指令都以#开始

  • 指令的符号之间可以插入任意数量的空格或水平制表符。例如:

    1
    #     define      N   100
  • 指令总是在第一个换行符出结束,除非明确的指令要延续。

    如果想在下一行延续指令,我i门必须在当前使用\字符。例如

1
2
3
4
#define DISK_CAPACITY (SIDES *              \
TRACKS_PER_SIDE * \
SECTORS_PER_TRACK * \
BYTES_PER_SECTOR)
  • 指令可以出现在程序中任何地方。

    通常将#define和#include指令放在文件开始,其他指令则放在后面,甚至可以放在函数的定义的中间。

宏定义

  1. 简单的宏

    1
    [#define指令  (简单的宏) ]                  #define         标示符          替换列表
  2. 带参数的宏
    带参数的宏(也称为函数式宏)的定义有如下格式:
    带参数的宏
    当与处理器遇到带参数的宏时,会将宏定义存储起来以便后面使用。

    在后面的程序中,如果任何地方出现了标识符号()格式的宏调用(其中是一系列记号),预处理会使用替换列表替换——使用替换 , 替换 ,以此类推。

例如:

1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
#define TOUPPER(c) ('a'<=(c)&&(c)<='z'?(c)-'a'+'A':(c))

int main(void)
{
char a;
scanf("%c", &a);
printf("原本的:%c\t转化为TOUPPER :%c\n", a, TOUPPER(a));
return 0;
}

这个宏检测字符是否在`a`与`z`\之间。

如果在的话这个宏会用c的值减去`a`在加上`A`\,从而计算c所对应的大写字母。如果c不再这个范围内则返回原来的c 。

又如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
#define MAX(x,y) ((x)>(y)?(x):(y))
#define IS_EVEN(n) ((n)%2==0) /*如果能被2整除则返回 1 ,为偶数*/
int main(void)
{
int x, y, n;
scanf("%d%d%d", &x, &y, &n);
printf("\n%d与%d中,最大的是:%d\n", x,y,MAX(x, y));

if (IS_EVEN(n) == 1)
printf("\n%d is even!\n\n",n);
else printf("\n%d is odd\n\n ", n);
return 0;
}

注意:

  • 与处理器仅知道少量C语言问题。因此,在执行指令时有可能会产生非法的错误。可能原始程序没有问题,查找错误非常困难。所以要先确保预处理程序没有问题。
  • 最好避免使用带有副作用的参数,因为宏运运算可能会产生副作用(它可能会不止一次地计算它的参数)。如:MAX的一个参数会产生副作用。
    1
    n=MAX(i++,j);
    预处理结果后
    1
    n=((i++)>(j)?(i++):(j));

    如果i大于j,那么i可能会被(错误)增加2次,同时n可能会被赋予错误的值。

#运算

文章目录
  1. 1. 预处理
    1. 1.1. 与处理器指令
    2. 1.2. 宏定义
  2. 2. #运算