【C语言天天练(二)】预处理

2024-04-20 12:48
文章标签 语言 预处理 天天

本文主要是介绍【C语言天天练(二)】预处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引言:


       学C语言之初,一提到预处理,脑子里想到的就是#define的宏定义以及#include包含的头文件。后来随着对C的深入学习发现,预处理不止这些。比如条件编译、预定义的宏等等。下面对此进行总结。

       先给出预处理的定义:在编译程序之前,先由预处理器检查程序(因此称为预处理器),根据程序中使用的预处理器命令,预处理器用符号缩略语所代表的内容替换程序中的缩略语。


1. #define

       最常用的预处理器命令就是define命令,该预处理器命令有三部分组成:#define本身、符号缩略语、替换列表(或称为主体)。

       结构可写为:#define 宏 主体        其中宏部分不能有空格,只能是数字、下划线、字母,但第一个字符不能使数字。如:#define PX printf("x is %d.\n", x)

       预处理器发现程序中的宏后,会用它的等价替换文件代替宏。如果该字符串中还包括宏,则继续替换这些宏。如果宏出现在双引号中,则不做替换。如果在双引号中出现的宏前面有“#运算符”,则可以用宏参数创建字符串。如:

#define PSQR(X) printf("The square of X is %d.\n", ((X)*(X)))

PSQR(8)   //等价于printf("The square of X is %d.\n", ((8)*(8))),输出The square of X is 64.

#define PSQR(X) printf("The square of "#X" is %d.\n", ((X)*(X)))

PSQR(8)   //等价于printf("The square of8 is %d.\n", ((8)*(8))),输出The square of8 is 64.

       小结:引号中的字符中中的X被看作普通文本,而不是被看作一个可替换的语言符号。#符号用作一个预处理运算符,它可以把语言符号转化为字符串。


       预处理器的粘合剂:##运算符。和上面的#运算符一样,##运算符可以用于类函数宏的替换部分。##还能用于类对象宏的替换部分,把两个符号组合成单个语言符号,如:

#define XNAME(n) x##n

XNAME(4)  //等价于x4


       从宏的定义和使用可以看出,它与函数非常相近,但宏与函数又有所不同,他们的选择实际上是时间和空间的权衡。宏产生内联代码,也就是说在程序中产生语句。如果使用宏20次,则会把20行代码插入程序中,如果使用函数20次,那么程序中只有一份函数的语句拷贝,因此节省了空间。另一方面,程序的控制必须转移到函数中并随后返回调用程序,因此这比内联代码话费的时间多。


2.#include

       预处理器发现#include指令后,就会寻找后跟的文件名并把这个文件的内容包含到当前文件中。被包含文件的文本将替换源代码文件中的#include指令,就像把被保护文件中的全部内容键入到源文件中的这个特定位置一样。

#include <name.h>    // 文件放在尖括号中,搜索系统工作目录

#include “name.h”     // 文件名放在双引号中,搜索当前工作目录

#include "/dir1/dir2/name.h" // 搜索/dir1/dir2目录

头文件中一般包含的内容有:明显常量、宏函数、函数声明、结构体模板定义、类型定义


3. 其他指令

#undef指令取消前面的#define定义。#if #ifdef #ifndef #else #elif #endif指令可用于选择什么情况下编译哪些代码。#line指令用于重置行和文件信息,#error指令用于给出错误消息,#param指令用于想编译器发出指示


4. 预定义的宏:

__DATE__ : 进行预处理的日期

__FILE__  :代码当前源代码文件名的字符串文字

__LINE__ :代表当前源代码文件中的行号的整数常量

__STDC__ :设置为1时,表示该实现遵循C标准

__TIME__ : 源文件编译时间

这篇关于【C语言天天练(二)】预处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/920304

相关文章

C语言进阶(预处理命令详解)

《C语言进阶(预处理命令详解)》文章讲解了宏定义规范、头文件包含方式及条件编译应用,强调带参宏需加括号避免计算错误,头文件应声明函数原型以便主函数调用,条件编译通过宏定义控制代码编译,适用于测试与模块... 目录1.宏定义1.1不带参宏1.2带参宏2.头文件的包含2.1头文件中的内容2.2工程结构3.条件编

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Go语言中make和new的区别及说明

《Go语言中make和new的区别及说明》:本文主要介绍Go语言中make和new的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1 概述2 new 函数2.1 功能2.2 语法2.3 初始化案例3 make 函数3.1 功能3.2 语法3.3 初始化

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码