C-study(十六)

预处理器

C标准:C语言+C预处理器+C标准库

在程序执行之前查看程序
根据预处理指令把符号缩写替换成表示的内容、转换文本
包含程序所需的其他文件、选择让编译器查看哪些代码

翻译

1、把源代码中出现的字符映射到源字符集、处理多字节字符和三字符序列
2、定位 \ +Enter换行、删除换行、把物理行转换为逻辑行

printf( "That's wond\
erful \n");// \ +Enter2个物理行
printf ( "That's wonderful\n ! ");//一个逻辑行 可以是多个物理行

3、文本划分为预处理记号序列、空白序列、注释序列
空格替换注释、除换行符外的空白字符序列

define

预处理器指令
#define 宏 替换体
:类对象宏(代表值)、类函数宏(可带参数)
宏名称中不能有空格、只能用字符数字和_、首字母不可以是数字、一般大写
替换字符串、参数列表可以有空格
圆括号括起宏的参数和替换体、可以大概率避免宏调用出错
宏展开:宏->替换文本、替换到没有宏结束

指令可以出现在源文件的任意位置、定义从指令出现到文件末尾有效
指令从#开始、到第一个换行符停止(逻辑行)
ANSI之后允许指令前中有空格、ANSI之前要求整条指令没有多余的空格
在这里插入图片描述

记号

记号:宏定义替换体中单独的词、空格分开

#define FOUR 2*2  //1个记号、记号序列:2*2
#define FOUR 2 * 2  //3个记号、记号序列:2 、*、2 

记号型字符串:空格是替换体中各记号的分隔符
字符型字符串:空格是替换体的一部分

重定义常量

ANSI只有新旧定义完全相同才允许重定义
相同定义:替换体记号相同、顺序也相同

#define SIX 2 * 3  
#define SIX 2 * 3//相同可重定义
#define SIX 2*3//不同、3个记号和1个记号、涉及到undef

define 带参数的类函数宏

在这里插入图片描述
类函数宏:生成内联代码、在程序中重复替换语句、不区分变量类型、嵌套循环中使用宏有助于提高效率
函数:只有一份函数副本、调用节省空间、函数跳转恢复浪费时间
内联函数

#运算符

在字符串中包含宏参数
字符串化:#x相当于"x"

##运算符

##:把2个记号组成一个记号

变参宏 …和__VA_ARGS__

#define LIMIT 20
const int LIM = 50;//C中不算常量
static int data1 [LIMIT];//有效
static int data2 [LIM];//无效、非自动数组大小:整型常量表达式、枚举常量、sizeof表达式
const int LIM2 = 2* LIMIT;//有效
const int LIM3 = 2 *LIM;//无效

/*preproc.c --简单的预处理示例*/
#include <stdio.h>
#define TWO 2//字符常量代替数字、清楚表达数字含义
/*可以使用注释*/
#define OW "Consistency is the last refuge of the unimagina\
tive. - Oscar wilde"
/*反斜杠把该定义延续到下一行、预处理开始前会把多行物理行处理为一行逻辑行、
第二行前不能有空格、要和第一行左对齐、从开始到"之间所有都算是字符串的一部分、包括空格
""定义字符串常量、存储在空字符'\0'结尾的数组中、预处理:字符串替换OW
''定义字符常量*/
#define FOUR TWO *TWO//宏包含宏、替换到没有宏结束、有编译器不支持嵌套
#define PX printf("X is %d. \n", x)
#define FMT "X is %d.\n"
//const char *fmt = "x is %d.\n";

#define SQUARE(X) X *X // SQUARE:宏标识符、X:宏参数  X*X:替换列表  X可由宏调用中的符号替代
#define PR(X) printf("The result is %d. \n", X)

#define PSQR(x) printf("The square of " #x " is %d.\n", ((x) * (x)))//#x->"x"

#define XNAME(n) x##n//##把两个记号组合成一个记号 x1
#define PRINT_XN(n) printf("x" #n " = %d\n", x##n);//#n相当于"n"、x##n相当于xn

#include <math.h>
#define PR(X, ...) printf("Message " #X ": " __VA_ARGS__)
/*  ...只能代替最后的宏参数、可变参数
__VA_ARGS__在替换部分代替省略号、前必须有空格、否则报错*/

int main(void)
{
    int x = TWO;//预处理器找到宏实例之后替换、int x=2;
    PX;//宏可以表示任何字符串、C表达式
    x = FOUR;//x=TWO*TWO;x=2*2;预处理器只做替换、不求值
    printf(FMT, x); // printf("X is %d.\n", x) printf(fmt, x);
    printf("%s\n", OW);
    printf("TWO: OW\n"); // 双引号之间的宏不做替换 printf("%d:%s\n",TWO, OW);


    x = 5;
    int z;
    printf("x = %d\n", x);
    z = SQUARE(x);
    printf("Evaluating SQUARE(x):"); // 5*5
    PR(z);
    z = SQUARE(2);
    printf("Evaluating SQUARE(2): "); // 2*2
    PR(z);
    printf("Evaluating SQUARE(x+2): ");
    PR(SQUARE(x + 2)); // 5+2*5+2 只做替换、不计算、可修改为#define SQUARE(x) (x)*(x)
    printf("Evaluating 100/SQUARE(2): ");
    PR(100 / SQUARE(2)); // 100/2*2 #define SQUARE(×)(x*×) 综合#define SQUARE(x) ((x)*(x))
    printf("x is %d\n", x);
    printf("Evaluating SQUARE(++x): ");
    PR(SQUARE(++x)); //++x*++x 49\42 自增自减避免做宏参数
    printf("After incrementing, x is %x.\n", x);

    int y = 5;
    PSQR(y);//"y"替换#x、"The square of y is %d.\n"
    PSQR(2 + 4);//"2 + 4"替换#x
 
    int XNAME(1) = 14; // 变成int xl = 14;
    int XNAME(2) = 20; // 变成int x2 = 20;
    int x3 = 30;
    PRINT_XN(1); // 变成printf("x1 = %d\n", xl);
    PRINT_XN(2); // 变成printf("x2 = %d\n", x2);
    PRINT_XN(3); // 变成 printf("x3 = %d\n", x3);

    double x = 48;
    double y;
    y = sqrt(x);
    PR(1, "x = %g\n", x); // #X展开为"1"、__VA_ARGS__展开为 "x = %g\n", x    print ( "Message 1: x= %g\n",×);
    PR(2, "x= %.2f, y =%.4f\n", x, y); //__VA_ARGS__展开为 "x= %.2f, y =%.4f\n", x, y
    getchar();
    return 0;
}

include

.h:头文件、预处理指令、宏函数、结构声明、函数原型
把被包含文件的全部内容输入到本文件
.c:源代码文件、包含头文件以使用头文件中的信息
头文件中的函数实现在name.c、函数调用在main.c、两个源代码文件需要编译和连接

#include <stdio.h>//尖括号、查找标准系统目录、部分开发环境可以配置标准系统目录
#include "hot.h"//双引号、查找当前工作目录、具体查找取决于编译器、未找到再查找标准系统目录
#include "/usr/biff/p.h"//查找/usr/biff目录

在这里插入图片描述

P553 待完善

相关推荐

  1. C++系列:类与对象

    2024-04-02 18:44:02       26 阅读
  2. C++系列:枚举

    2024-04-02 18:44:02       30 阅读
  3. C语言经典面试题目(

    2024-04-02 18:44:02       7 阅读
  4. C++经典面试题目(

    2024-04-02 18:44:02       6 阅读

最近更新

  1. Oracle语句深入了解Day02

    2024-04-02 18:44:02       0 阅读
  2. el-table-column叠加el-popover使用

    2024-04-02 18:44:02       0 阅读
  3. iOS隐私清单

    2024-04-02 18:44:02       0 阅读
  4. ES系列之相似度模型

    2024-04-02 18:44:02       0 阅读

热门阅读

  1. Webshell网络安全应急响应概述

    2024-04-02 18:44:02       8 阅读
  2. Linux关机命令

    2024-04-02 18:44:02       6 阅读
  3. 冥想第一千一百一十七天

    2024-04-02 18:44:02       6 阅读
  4. 在linux上设置nginx上自动启动

    2024-04-02 18:44:02       6 阅读
  5. 第一章设计模式概述

    2024-04-02 18:44:02       5 阅读
  6. 介绍几个AI相关的工具

    2024-04-02 18:44:02       5 阅读
  7. 【软考高项范文】论信息系统项目的进度管理

    2024-04-02 18:44:02       6 阅读
  8. WebRTC即时通讯核心协议-TRUN(RFC5766)

    2024-04-02 18:44:02       3 阅读
  9. 队列的顺序实现

    2024-04-02 18:44:02       3 阅读
  10. 松鼠症患者福音-视频下载工具

    2024-04-02 18:44:02       3 阅读