C语言学习记录(十五)C预处理器和C库

news2025/7/14 22:53:56

文章目录

  • 一、C预处理器
    • 1.1 翻译程序
    • 1.2 明示常量:#define
    • 1.3 在#define中使用参数
    • 1.4 文件包含:#include
    • 1.5 其他指令
      • 1.5.1 #undef指令
      • 1.5.2 从C预处理角度看已定义
      • 1.5.3 条件编译
        • 1.5.3.1 #ifdef、#else和#endif指令
        • 1.5.3.2 #ifndef
        • 1.5.3.3 #if和elif指令
  • 二、C库
    • 2.1 数学库
    • 2.2 断言库

一、C预处理器

C预处理器在程序执行之前查看程序(故称为预处理器)。根据程序中的预处理指令,预处理把符号缩写替换成其他的内容。

1.1 翻译程序

在预处理之前,编译器必须对该程序进行一些翻译处理。首先,编译器把源代码中出现的字符映射到源字符集。该处理过程处理多字节和三字符序列。

第二,编译器定位每个反斜杠后面跟着换行符的实例,并删除它们。

第三,编译器把文本划分成预处理记号序列、空白序列和注释序列(记号是由空格、制表符或换行符分隔的项)。编译器将用一个空格字符替换每一条注释。

1.2 明示常量:#define

#define预处理指令和其他预处理指令一样,以#号作为一行的开始。ANSI和后来的标准都允许#号前面有空格或制表符,而且还允许在#和指令的其余部分之间有空格。但是旧版本的C要求指令从一行的最左边开始,而且#和指令其余部分不能有空格。指令可以出现在源文件的任何地方。其定义从指令出现的地方到该文件的末尾有效。我们大量使用#define指令来定义明示常量(也叫符号常量)。但是该指令还有其他用途。下面举例说明。

#include <stdio.h>

#define TWO 2   /* 可以使用注释 */
#define OW "Consistency is the last refuge of the unimagina\
tive. - Oscar Wilde" // 反斜杠把该定义延续到下一行

#define FOUR TWO*TWO
#define PX printf("X is %d.\n", x)
#define FMT "X is %d.\n"

int main() {

    int x = TWO;

    PX;
    x = FOUR;
    printf(FMT, x);
    printf("%s\n", OW);
    printf("TWO: OW\n");

    return 0;
}

每行的#define(逻辑行)都有3部分组成。

1、第一部分是#define指令本身。
2、第二部分是选定的缩写,也称为。有些宏代表值(本例),这些宏被称为类对象宏。C语言还有类函数宏宏的名称中不允许有空格,而且必须遵循C变量的命名规则。
3、第三部分称为替换列表或替换体。一旦预处理器在程序中找到宏的实例后,就会用替换体代替该宏。从宏变成最终替换文本的过程称为宏展开。注意,可以在#define行使用标准C注释,每条注释都会被一个空格代替。

在这里插入图片描述

宏可以表示明示常量,也可以表示任何字符串,甚至可以表示整个C表达式。但是要注意,虽然PX是一个字符串常量,它只打印一个名为x的变量。

由于编译器在编译期对所有的常量表达式(只包含常量的表达式)求值,所以预处理不会进行实际的乘法运算,这一过程在编译时进行。预处理不做计算,不对表达式求值,它只进行替换。

1.3 在#define中使用参数

在#define中使用参数可以创建 外形和作用与函数类似的类函数宏。带有参数的宏看上去很像函数,因为这样的宏也使用圆括号。类函数宏定义的圆括号中可以有一个或多个参数,随后这些参数出现在替换体中。

1.4 文件包含:#include

当预处理器发现#include指令时,会查看后面的文件名并把文件的内容包含到当前文件中,即替换源文件中的#include指令。这相当于把被包含文件的全部内容输入到源文件#include指令所在的位置。

#include指令有两种形式:

#include<stdio.h> // 文件名在尖括号中
#include "hot.h"  // 文件名在双引号中

尖括号告诉预处理器在标准系统目录中查找文件。双引号告诉编译器首先在当前目录中(或文件名指定的目录)查找文件,如果未找到再查找标准系统目录。

C语言习惯使用.h后缀表示头文件,这些文件包含需要放在程序顶部的信息。头文件经常包含一些预处理指令。有些头文件(如stdio.h)由系统提供,当然你也可以创建自己的头文件。

1.5 其他指令

程序员可能要为不同的工作环境准备C程序和C库包。不同的环境可能使用不同的代码类型。预处理器提供一些指令,程序员通过修改#define的值即可生成可移植的代码。#undef指令取消之前的#define定义。#if、#ifndef、#else、#elif和#endif指令用于指定什么情况下编写那些代码。#line指令用于重置行和文件信息,#error指令用于给出错误信息,#pragma指令用于向编译器发出指令。

1.5.1 #undef指令

#undef指令用于“取消”已定义的#define指令。

#define ITEM 400

#undef ITEM

将移除上面的定义。现在就可以把ITEM重新定义为一个新值。即使原来没有定义ITEM。取消ITEM的定义仍然有效。

1.5.2 从C预处理角度看已定义

处理器在识别标识符时,遵循与C变量命名相同的规则。当预处理器在预处理器中发现一个标识符时,它会把该标识符当作已定义或未定义的。这里的已定义表示由预处理器定义。如果标识符是同一个文件中由前面的#define指令创建的宏名,而且没有用#undef指令关闭,那么该标识符是已定义的。如果标识符不是宏,假设是一个文件作用域的C变量,那么该标识符对预处理器而言就是未定义的。

已定义的宏可以是对象宏,包括空宏或类函数宏:

#define LIMIT 1000 //LIMIT是已定义的
#define GOOD	// GOOD是已定义的
#define A(X) ((-(X))*(X)) //A是已定义的
int q;	// q不是宏,因此是未定义的
#undef GOOD	// GOOD取消定义,是未定义的 

注意,#define宏的作用域从它在文件中的声明位置开始,直到#undef指令取消宏为止,或延伸至文件尾(以二者中先满足的条件作为宏作用域的结束)。另外还要注意,如果宏通过头文件引入,那么#define在文件中的位置取决于#include指令的位置。

1.5.3 条件编译

可以使用其他指令创建条件编译。也就是说,可以使用这些指令告诉编译器根据时的条件执行或忽略信息块

1.5.3.1 #ifdef、#else和#endif指令

#ifdef指令说明,如果预处理器已定义了后面的标识符,则执行#else或#endif指令之前的所有指令并编译所有C代码(先出现哪个指令就执行到哪里)。如果预处理器未定义,且有#else指令。则执行#else和#endif之间的所有代码。

#ifdef TITLE // 如果已经用#define定义了TITLE,则执行下面的代码
	#include "time.h"
	#define START 3
#else	// 如果没有用#define定义TITLE,则执行下面的指令
	#include "cow.h"
	#define START 5
#endif

1.5.3.2 #ifndef

#ifndef指令与#ifdef指令的用法类似,也可以和#else、#endif一起使用,但是它们的逻辑相反。#ifndef指令判断后面的标识符是否是未定义的,常用于定义之前未定义的常量。

#ifndef SIZE
	#define SIZE 30
#endif
#ifndef _STDIO_H
#define _STDIO-H


# endif

1.5.3.3 #if和elif指令

if指令很像C语言中的if。#if后面跟整型常量表达式,如果表达式未非零,则表达式为真,可以在指令中使用C的关系运算符和逻辑运算符。

#if SYS == 1
#include "TIME.h"
#endif
#if defind (IBMPC)
	#include "TIME.h"
#elif defind (VAC)
	#include "VAX.h"
#endif

二、C库

2.1 数学库

数学库中包含许多有用的数学函数,math.h头文件提供这些函数的原型。在math.h中的函数,注意,函数中涉及的角度都以弧度为单位(1弧度 = 180/Π = 57.296度)

在这里插入图片描述

2.2 断言库

assert.h头文件支持的断言库是一个用于辅助调试程序的小型库。它由assert()宏组成,接收一个整型表达式作为参数,如果表达式的值为假,assert()宏就在标准错误流(stderr)中写入一条错误信息,并调用abort()函数终止程序(abort()函数的原型在stdlib.h头文件中)。assert()宏是为了标识出程序中某些条件为真的关键位置,如果其中一个具体条件为假,就用assert()语句终止程序。通常assert()的参数是一个条件表达式或逻辑表达式。如果assert()中止了程序,它首先会显示失败的测试,包含测试的文件名和行号。

#include <stdio.h>
#include "stdlib.h"
#include "math.h"
#include "assert.h"

int main() {

    int x, y, z;
    puts("please enter a number:\n");
    scanf("%d %d", &x, &y);

    if(y == 0){

        assert(y == 0);
        puts("error");
    }
    
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/38180.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Gof23-创建型-工厂-单例-抽象工厂-建造-原型以及UML的绘制

创建型的设计模式工厂模式单例模式抽象工厂建造者模式原型模式UML图形的绘制工厂模式 工厂模式 Factory Pattern 适用的场景&#xff1a;统一的接口作为统一的零件&#xff0c;实现类作为零件的组合&#xff0c;将实例产品类的生产交给工厂&#xff0c;用户只需要面对工程提取…

XML的创建和读取

rapidxml是一个快速的xml库&#xff0c;由C模板实现的高效率xml解析库&#xff0c;同时也是boost库的property_tree的内置解析库。 当使用rapidxml时&#xff0c;只需要把rapidxml.hpp 、 rapidxml_print.hpp 和 rapidxml_utils.hpp 三个文件拷贝到你的工程目录下&#xff0c;就…

Pytorch中KL loss

1. 概念 KL散度可以用来衡量两个概率分布之间的相似性&#xff0c;两个概率分布越相近&#xff0c;KL散度越小。 上述公式表示P为真实事件的概率分布&#xff0c;Q为理论拟合出来的该事件的概率分布。D(P||Q)&#xff08;P拟合Q&#xff09;和D(Q||P)&#xff08;Q拟合P&…

ajax之Content-Type示例

参考资料: Content-Type详解【SpringBoot】SpringBoot接收请求的n种姿势 目录前期准备0. Content-Type概念解释1. application/x-www-form-urlencoded1.1 form表单示例1.2 jQuery的ajax示例2. application/json2.1 指定contentType为json,不使用RequestBody接收2.2 不指定cont…

01 OSI七层网络排查 troubleshooting 思路及对应工具

文章目录1 .前言2. OSI 的七层模型&#xff0c;和 TCP/IP 的四层 / 五层模型区别2.1 网络专业术语2.2 TLS 解释2.3 什么是TCP 流&#xff1f;3. 网络各层排查工具3.1 应用层3.1.1 浏览器的开发者工具3.1.1.1 找到有问题的服务端IP3.1.1.2 辅助排查网页慢的问题3.1.1.3 解决失效…

嵌入式数据库sqlite3

一、数据库 数据库的基本概念 常用的数据库 大型数据库 Oracle公司是最早开发关系数据库的厂商之一&#xff0c;其产品支持最广泛的操作系统平台。目前Oracle关系数据库产品的市场占有率名列前茅。 IBM 的DB2是第一个具备网上功能的多媒体关系数据库管理系统&#xff0c;支…

bootstrap学习(四)

bootstrap中图片、按钮、表单 按钮&#xff1a; 不加样式的按钮&#xff1a; 在bootstrap中a标签也可以生成按钮&#xff1a; 默认按钮尺寸可以不加&#xff0c;它是自动显示默认尺寸 加btn-block&#xff1a;class 图片&#xff1a; 表单&#xff1a; 垂直表单&#xff1a;…

【语音识别】MFCC+VAD端点检测智能语音门禁系统【含GUI Matlab源码 451期】

⛄一、MFCC简介 1 引言 语音识别是一种模式识别, 就是让机器通过识别和理解过程把语音信号转变为相应的文本或命令的技术。语音识别技术主要包括特征提取技术、模式匹配准则及模型训练技术3个方面。目前一些语音识别系统的适应性比较差, 主要体现在对环境依赖性强, 因此要提高…

[mysql] 深入分析MySQL版本控制MVCC规则--实测 (mysql 8.0 innodb引擎)

背景&#xff1a;基于之前的一篇文章 可重复读&#xff1a;可重复读隔离级别的实现是每个事务在打开时都会生成一个一致的视图。 当其他事务提交时&#xff0c;不会影响当前事务中的数据。 为了保证这一点&#xff0c;MySQL是通过多版本控制机制MVCC来实现的&#xff1b; 我们亲…

Go语言面试题合集(2022)

基础语法 Go 支持默认参数或可选参数吗&#xff1f; 不支持。但是可以利用结构体参数&#xff0c;或者…传入参数切片数组。 // 这个函数可以传入任意数量的整型参数 func sum(nums ...int) {total : 0for _, num : range nums {total num}fmt.Println(total) }Go 语言 tag…

pandas算术运算、逻辑运算、统计运算describe()函数、统计函数、累计统计函数及自定义函数运算

一、pandas算术运算 直接对数据进行加、减、乘、除等运算&#xff0c;可使用函数add()、sub()、mul()、div()或、-、、 代码如下 数据生成 import pandas as pd import numpy as np# 数据生成代码 num np.random.randint(50, 100, (3, 5))# 传入标签索引 column [第一列, …

[hadoop全分布部署]安装Hadoop、配置Hadoop 配置文件①

&#x1f468;‍&#x1f393;&#x1f468;‍&#x1f393;博主&#xff1a;发量不足 个人简介&#xff1a;耐心&#xff0c;自信来源于你强大的思想和知识基础&#xff01;&#xff01; &#x1f4d1;&#x1f4d1;本期更新内容&#xff1a;安装Hadoop、配置Hadoop 配置文件…

基于SSM的高校课程评价系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

一文带你深入理解【Java基础】· 注解

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

多线程编程【条件变量】

条件变量&#x1f4d6;1. 为什么需要条件变量&#xff1f;&#x1f4d6;2. 条件变量概念&#x1f4d6;3. 发信号时总是持有锁&#x1f4d6;4. 生产者消费者问题&#x1f4d6;5. 基于阻塞队列的生产者消费者模型&#x1f4d6;1. 为什么需要条件变量&#xff1f; 在很多情况下&a…

Android开发音效增强中铃声播放Ringtone及声音池调度SoundPool的讲解及实战(超详细 附源码)

需要源码请点赞关注收藏后评论区留下QQ~~~ 一、铃声播放 虽然媒体播放器MediaPlayer既可用来播放视频&#xff0c;也可以用来播放音频&#xff0c;但是在具体的使用场合&#xff0c;MediaPlayer存在某些播音方面的不足之处 包括以下几点 1&#xff1a;初始化比较消耗资源 尤其…

软件开发工程师笔试记录--关键路径,浮点数计算,地址变换,中断向量,I/O接口,海明码

时间&#xff1a;2022年11月26日 10&#xff1a;00 -11&#xff1a;00 &#xff08;可提前登录15分钟&#xff09; 公司&#xff1a;XX&#xff08;rongyu&#xff09; 岗位&#xff1a;软件开发工程师&#xff08;我的简历语言是Java&#xff09; 题型&#xff1a;选择题&…

一次应用多次fgc原因的排查及解决

应用多次fgc性能排查&#xff08;一次抢购引起的性能问题&#xff09; 大家好我是魔性的茶叶&#xff0c;今天分享一个项目jvm多次fgc的整个排查流程 上班后不久运维突然通知我们组&#xff0c;有一个应用在短时间内多次fgc&#xff0c;即将处于挂掉的状态。 首先我登录skyw…

客户听不进去,很强势,太难沟通了,怎么办?

案例 最近接手一项目,项目范围蔓延,成本超支,进度延期,问项目经理怎么回事? 项目经理C无奈诉苦到:用户A大领导,是业主B的领导,咱们业主B不敢反驳他,让我直接与用户A对接,说A提的需求,默认答应,我有什么办法啊,只能接了。 分析 经过复盘,导致项目蔓延的主要原因…

【参赛经历总结】第五届“传智杯”全国大学生计算机大赛(初赛B组)

成绩 比赛链接 比赛过程 被虐4h 比赛体验不是很好我开始五分后才在qq上看到题第一题签到题第二题调了1h吧&#xff0c;算法题做的不多&#xff0c;题目没读全&#xff0c;wa了几发&#xff0c;有几发是网络问题&#xff0c;交了显示失败&#xff0c;但还是判wa了第三题知道…