26. 【C语言】编译前的“文本大师”:预处理器指令

扩散模型原理与工程实践:从去噪过程到工业级应用 扩散模型是当前生成式AI的核心范式,其本质是在高维空间中学习从纯噪声到真实数据的可逆重建路径。它以可控的前向加噪与反向去噪为数学骨架,依托U-Net等架构实现语义与细节的协同建模,在图像合成、科学计算、工业质检等场景展现出强解释性与可干预性。相比GAN的黑箱特性和自回归模型的累积误差,扩散模型凭借稳定的L2损失优化、潜空间高效表征及CFG等条件引导机制,成为兼顾质量、可控性与部署可行性的首选技术。本文深入剖析其物理直觉、数学建模与工程落地三层逻辑,覆盖训练调参、采样加速、多模态控制及避坑实战,助力开发者真正 阅读详情

从第一个 hello.c 开始,我们几乎每个程序开头都有 #include <stdio.h>。你一直知道它是“引入头文件”,但你可能没深想过:那个 # 到底是什么?#include 和 #define 又是怎么工作的?

它们都归属于 C 语言的预处理器——在编译器真正开始编译之前,有一个独立的“预处理”阶段,对源码进行一系列的文本处理。可以把预处理器想象成一个文字编辑助手,它按照你的指令进行查找替换、条件保留、文件拼接,最后把一份“干净”的 .c 文件交给编译器。

预处理器是 C 语言极具特色的部分,用得好可以让代码更简洁、更灵活;用不好会引发各种诡异 bug。今天我们就来全面掌握它。


一、回顾编译四阶段中的预处理

第三篇我们简要介绍过编译的四个阶段。这里再复习一下预处理在整个流程中的位置:

源文件 (.c)
    ↓
[预处理]  ← 我们在这里!处理 #include、#define、#ifdef 等
    ↓
翻译单元 (纯净的 .i 文件)
    ↓
[编译]  → 汇编代码 (.s)
    ↓
[汇编]  → 目标文件 (.o)
    ↓
[链接]  → 可执行文件

预处理阶段做的工作包括:

  • 展开 #include(把头文件内容插入)
  • 替换 #define 宏
  • 处理条件编译指令(#if、#ifdef 等)
  • 删除注释
  • 处理行标识(#line)、错误指令(#error)等

最终输出一个“翻译单元”,其中不包含任何预处理指令,全都是纯 C 代码。

你可以用 gcc -E 亲眼看看预处理结果:

gcc -E hello.c -o hello.i

打开 hello.i,你会看到原本的 #include <stdio.h> 被替换成了好几千行的内容——那就是 stdio.h 里嵌套包含的所有声明。


二、宏定义 #define:文本替换的利器

1. 简单宏(对象式宏)

#define PI 3.14159
#define MAX_STUDENTS 100
#define GREETING "Hello, World!"

本质就是文本替换。预处理阶段,代码中所有出现 PI 的地方(除了字符串字面量内部),都会被原样替换成 3.14159。这和我们第四篇讲的常量定义形成了对比:

#define PI 3.14159const double PI = 3.14159;
本质文本替换带类型的只读变量
内存不占运行时内存占内存
类型检查无有
可以取地址否是
作用域从定义处到文件末尾或 #undef块作用域

定义宏的注意点:

  • 宏名通常全大写(约定俗成,一眼就知道它是宏)。
  • 不要在末尾加分号!#define PI 3.14; 会让所有 PI 被替换成 3.14;,可能导致 2 * PI 变成 2 * 3.14; 这种非法语法。

2. 带参宏(函数式宏)

宏也可以有参数,像函数一样使用:

#define SQUARE(x)  ((x) * (x))
#define MAX(a, b)  ((a) > (b) ? (a) : (b))

使用:

int y = SQUARE(5);      // 展开为 ((5) * (5))
int m = MAX(10, 20);   // 展开为 ((10) > (20) ? (10) : (20))

注意:这里有一个超级大坑——括号!

如果你写成:

#define SQUARE(x)  x * x   // 危险!没有括号

当你写 SQUARE(2 + 3) 时,它会展开成 2 + 3 * 2 + 3,由于乘法优先级高,实际计算的是 2 + 6 + 3 = 11,而不是预期的 25。

正确做法:给每个参数加括号,给整个表达式也加括号:#define SQUARE(x) ((x) * (x))。这是写宏的铁律。

3. 宏 vs 函数:什么时候用宏?

宏的优点:

  • 没有函数调用的开销(不涉及栈帧、参数复制),执行快。
  • 没有类型限制,同一个宏可以用于 int、double 等。

宏的缺点:

  • 没有类型检查。
  • 多次使用会展开多次代码,导致可执行文件变大(代码膨胀)。
  • 难以调试(调试器只能看到展开后的代码)。
  • 参数有副作用时非常危险:
int x = 5;
int y = SQUARE(x++);  
// 展开为 ((x++) * (x++)),未定义行为!x 被递增了两次

经验法则:简单的小型操作(如取最大最小值、简单的数学计算)可以考虑用宏;较复杂的逻辑优先用函数。如果函数式宏里参数会被多次使用,务必在文档中警告。


三、条件编译:让代码“随机应变”

条件编译让预处理器根据条件决定哪些代码被保留,哪些被丢弃。这是编写跨平台代码、调试开关、功能裁剪的利器。

1. #ifdef / #ifndef / #endif

#ifdef DEBUG
    printf("调试信息:当前值 = %d\n", value);
#endif

如果 DEBUG 之前被 #define 过,这行 printf 会被保留;否则会在预处理阶段直接被删除,完全不存在于最终的可执行文件里。

#ifndef 是“如果未定义”。我们一直在头文件防护里用它:

#ifndef MY_HEADER_H
#define MY_HEADER_H
// 头文件内容
#endif

2. #if / #elif / #else

#if 可以判断常量表达式(只认整型常量):

#define VERSION 2

#if VERSION == 1
    printf("版本 1 的功能\n");
#elif VERSION == 2
    printf("版本 2 的新功能\n");
#else
    printf("未知版本\n");
#endif

还可以配合 defined 操作符:

#if defined(DEBUG) && VERSION > 1
    // ...
#endif

defined(DEBUG) 等价于 #ifdef DEBUG,但可以与其他条件组合。

3. 典型的应用场景

跨平台代码:

#ifdef _WIN32
    #include <windows.h>
    #define CLEAR_SCREEN "cls"
#elif defined(__linux__) || defined(__APPLE__)
    #include <unistd.h>
    #define CLEAR_SCREEN "clear"
#endif

int main(void) {
    system(CLEAR_SCREEN);
    // ...
}

调试开关:

#ifndef NDEBUG
    #define LOG(msg) printf("[DEBUG] %s:%d: %s\n", __FILE__, __LINE__, msg)
#else
    #define LOG(msg) ((void)0)   // 发布版本中 LOG 变成空操作
#endif

((void)0) 是一个什么也不做的表达式,编译器会把它优化掉,完全零开销。这样就不需要在发布版本里删除调试语句。


四、# 和 ## 操作符:字符串化和拼接

这两个操作符是预处理阶段的功能,用于高级宏定义。

1. #:字符串化(Stringizing)

把宏参数转换成字符串字面量(在参数两边加双引号)。

#define TO_STRING(x) #x

printf("%s\n", TO_STRING(hello));  // 输出 "hello"
printf("%s\n", TO_STRING(3.14));   // 输出 "3.14"
printf("%s\n", TO_STRING(a + b));  // 输出 "a + b"

注意:如果参数里本身有空格,# 会保留。它会自动转义参数中的双引号和反斜杠。

2. ##:标记粘贴(Token Pasting)

把两个标记(token)粘成一个新的标记。

#define CONCAT(a, b) a ## b

int xy = 10;
printf("%d\n", CONCAT(x, y));  // 展开为 xy,输出 10

int value_1 = 100, value_2 = 200;
printf("%d\n", CONCAT(value_, 2));  // 展开为 value_2,输出 200

这常用于自动生成变量名或函数名。比如在状态机里:

#define STATE(name)  state_##name
enum { STATE(start), STATE(running), STATE(stopped) };
// 展开为: enum { state_start, state_running, state_stopped };

# 和 ## 在复杂的宏定义中非常有用,但可读性会下降。只在确实能简化代码时使用,不要让宏变成“魔法咒语”。


五、预定义宏:编译器自带的“身份证”

C 标准规定了一些预定义宏,所有编译器的预处理阶段都自动定义(不需要你 #define),它们提供当前编译的源文件信息。常用的有:

宏含义示例值
__FILE__当前源文件名(字符串)"main.c"
__LINE__当前行号(整数)42
__DATE__编译日期(“Mmm dd yyyy”)"Jan 15 2025"
__TIME__编译时间(“hh:mm:ss”)"14:30:00"
__STDC__如果编译器符合 ANSI C 标准,定义为 11
__STDC_VERSION__C 标准版本号201112L(C11)

这些宏在调试和日志中非常有用:

#include <stdio.h>

int main(void) {
    printf("文件: %s\n", __FILE__);
    printf("行号: %d\n", __LINE__);
    printf("编译日期: %s\n", __DATE__);
    printf("编译时间: %s\n", __TIME__);

    if (__STDC_VERSION__ >= 201112L) {
        printf("当前使用 C11 或更高版本\n");
    }
    return 0;
}

结合条件编译,你可以写出兼容多版本 C 标准的代码。


六、常见错误与陷阱

1. 宏定义末尾写分号

#define MAX 100;
// 在代码中: if (x > MAX)  → if (x > 100;)  语法错误

2. 函数式宏不包裹括号(这个坑必须刻进脑子里)

#define MULTIPLY(a, b) a * b
// MULTIPLY(2+3, 4+5) → 2+3*4+5 = 19,不是 45

3. 宏参数有副作用

#define MAX(a, b) ((a) > (b) ? (a) : (b))
int x = 5, y = 10;
int z = MAX(++x, y);  // 展开: ((++x) > (y) ? (++x) : (y)),x 被递增两次

4. 宏定义中的类型不安全

#define SQUARE(x) ((x) * (x))
SQUARE(3.14);     // 可以,double 没问题
SQUARE("hello");  // 编译错误,但错误信息指向展开后的代码,难以定位

5. 条件编译里用运行时变量

int version = 2;
#if version == 2   // 错误!#if 只能处理编译时常量

#if 发生在预处理阶段,此时没有任何变量存在。version 会被当成未定义的宏,替换为 0。


七、小结

预处理器是 C 语言给你的“编译前文本处理工具箱”:

  • #define:定义宏,做文本替换。函数式宏高效但需要加括号防副作用。
  • 条件编译:#ifdef、#if、#else 等让代码可以在不同条件下裁剪,是跨平台和调试开关的基础。
  • # 和 ##:字符串化和标记粘贴,用于高级宏技巧。
  • 预定义宏:__FILE__、__LINE__、__DATE__ 等提供编译期信息,是日志和断言的得力助手。

宏是“双刃剑”——它在极简的表象下藏着陷阱。写宏时心里默念:括号!括号!还是括号! 能用 const 或函数替代时,优先不用宏。

下一篇,我们将把这些知识融会贯通,学习如何编写可移植的头文件与模块——处理平台差异的条件编译、防止重复包含的最佳实践、以及把一个中等规模项目组织得井井有条的方法。


课后小练习

  1. 编写一个带参宏 CUBE(x),计算 x 的立方。测试 CUBE(2+3) 是否输出 125,如果不是,修正你的宏。
  2. 用条件编译实现一个程序:如果定义了 ENGLISH,输出 "Hello";如果定义了 FRENCH,输出 "Bonjour";如果什么都没定义,输出 "你好"。通过修改 #define 来切换语言。
  3. 用 __FILE__ 和 __LINE__ 实现一个调试宏 PRINT_HERE,调用它时打印当前文件名和行号。然后再写一个 LOG(fmt, ...) 宏(使用可变参数宏 ... 和 __VA_ARGS__),输出带文件名、行号的格式化日志。
  4. (小挑战)分析下面这段宏有什么问题,并给出正确的写法:
    #define SWAP(a, b) { int temp = a; a = b; b = temp; }
    // 在 if-else 中使用:
    if (x > y)
        SWAP(x, y);
    else
        printf("ok\n");
    

我们下期见!

💡获取本系列示例代码请访问 GitCode 仓库。

LVGL v8.3 图片显示与解码缓存实战:PNG 上屏、C 数组与文件双方案 LVGL v8.3 图片两种存储方式、PNG/JPG 上屏解码器挂载、LV_IMG_CACHE_DEF_SIZE 缓存调优、手动预解码头像有效性判断,及"缓存被动画清空"真实踩坑。 阅读详情

相关推荐

利用MATLAB 4f光学系统,在Python中进行弗劳恩霍夫衍射和傅里叶面滤波——用镜头模拟光学图像处理。.zip

1.版本:matlab2014a/2019b/2024b 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

C++ 之父 2024 年末重磅演讲 | 重新认识 C++:跨世纪的现代演进

作者 | 《新程序员》编辑部出品 | 优快云(ID:优快云news)12 月 5 日,美国国家工程院、ACM、IEEE 院士、C++ 之父 Bjarne Stroustrup 在「2024 全球 C++ 及系统软件技术大会」上发表了题为《重新认识 C++:跨世纪的现代演进》的演讲。屏幕上,演示文稿的第一页就令人印象深刻:“C++ 几乎可以实现我们所期望的一切!”从构建操作系统到开发高性能游戏引...

程序人生的博客 3871

利用MATLAB和Excel对逆流双管热交换器的热性能进行分析。.zip

1.版本:matlab2014a/2019b/2024b 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

static 的三种用法:C 语言里一个关键字的三张面孔

本文系统讲解 C 语言中 static 关键字的三种用法:修饰局部变量延长生命周期、修饰全局变量与函数限制作用域到本文件。通过一个包含三个文件的完整工程示例对照演示,并从存储期、作用域与链接性三个属性解释其统一原理,最后补充单元测试框架偏爱 static 函数的工程实践。

大模型全栈工程师 · Thanks_ks 298

利用MATLAB对5G NR波束成形技术的性能分析.zip

1.版本:matlab2014a/2019b/2024b 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

上市公司赫芬达尔指数、企业勒纳指数(1999-2025年)

上市公司赫芬达尔指数(HHI)和勒纳指数(LI)是衡量市场结构和市场势力(垄断力量)的两个重要指标 赫芬达尔指数(HHI)可衡量一个公司在市场中的相对份额或集中度,通过计算公司在市场中份额的平方和得出。数值越小,说明市场份额分布越分散,竞争程度越高;数值越大,说明市场集中度越高,少数企业占据较大份额,垄断程度越高 勒纳指数(LI)用于衡量企业的市场势力,即企业偏离完全竞争价格、制定高于边际成本的价格的能力,数值越接近1,表示企业市场势力越强,垄断程度越高 本文借鉴刘贯春等(2021)、孙茹峰和李楠博(2024)的思路和方法,分别测算上市公司赫芬达尔指数、勒纳指数: 赫芬达尔指数 = (公司营业收入/同行业同年营业收入合计)的平方和 企业勒纳指数 =(营业收入-营业成本-销售费用-管理费用)/营业收入 一、数据介绍 数据名称:上市公司赫芬达尔指数、企业勒纳指数 数据范围:上市公司 时间范围:1999-2025年 样本数量:85810条 数据来源:上市公司年报 更新时间:2026年11月 数据说明:内含原始数据、测算结果 二、数据指标 股票代码 股票简称 年份 省份 城市 区县 省份代码 城市代码 区县代码 行业代码 行业名称 赫芬达尔指数 勒纳指数 营业收入 营业成本 销售费用 管理费用 三、参考文献 [1]刘贯春,叶永卫,张军.社会保险缴费、企业流动性约束与稳就业——基于《社会保险法》实施的准自然实验[J].中国工业经济,2021,(05):152-169. [2]孙茹峰,李楠博.金融化对企业绿色转型意向的影响研究[J].管理学报,2024,21(11):1612-1620+1677. [3]张倩肖,段义学.数字赋能、产业链整合与全要素生产率[J].经济管理,2023,45(04):5-21. [4]伍兆祥,代吉林,

【FDE知识库】(1):AI 编程时代开发语言选型分析,云使用go,企业用java,算法python,底层c

AI 编程时代,开发语言选型需综合考量AI适配度、编译速度、跨平台与学习成本。Python以海量语料和即时执行成首选,适用于AI/ML与原型开发;TypeScript凭借类型系统与秒级构建,成为前端及应用层主流;Go以极速编译与统一风格,契合AI代理高效迭代需求。Rust/C++虽性能强,但编译慢、学习成本高,不适于快速试错。综合推荐:优先选Python、TypeScript、Go,兼顾效率与生态,实现最优AI协作体验。

freewebsys的专栏 485

工业互联网工控安全与工业质检AI大模型建设方案.pptx

工业互联网工控安全与工业质检AI大模型建设方案.pptx

不平衡电网下自抗扰顺序模型预测PWM整流器控制仿真模型(Simulink仿真实现)

内容概要:本文围绕面向城市空中交通的多无人机路径规划问题展开研究,提出了一套融合全局规划、动态避障与局部协同调整的综合路径规划方法。研究内容涵盖基于改进RRT算法与图论的全局路径规划、基于动态风险场和动态窗口法(DWA)的模型预测控制实现动态避障,以及基于分布式协同控制的多无人机局部路径协同策略。通过Matlab平台构建仿真环境,在多种典型城市交通场景下对所提方法进行了系统性验证,结果表明该方法在路径安全性、编队稳定性与任务效率方面表现优异。文章还深入探讨了算法的创新点与未来研究方向,为复杂城市环境下多无人机系统的自主协同提供了理论支撑与技术路径。; 适合人群:具备自动化、控制理论、计算机科学或相关领域基础知识,从事无人机系统、智能交通、路径规划、多智能体协同控制等方向研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①为城市空中交通系统中的多无人机安全、高效飞行提供可靠的路径规划解决方案;②支持在复杂、动态的城市场景中开展无人机自主导航、编队飞行与协同控制的技术研究与仿真验证。; 阅读建议:建议结合提供的Matlab代码进行实践操作,重点关注算法的具体实现细节、参数配置对性能的影响以及不同仿真场景下的实验设计,以深入理解各模块的集成逻辑与实际应用效果。

通信行业CentOS 7内核网络栈优化:高并发连接下UDP/TCP性能调优与系统资源管理

内容概要:本文聚焦于CentOS 7系统在通信行业高并发场景下的性能调优实践,重点围绕内核网络栈优化展开,涵盖UDP/TCP缓冲区调整、文件句柄与连接跟踪表扩容、TIME_WAIT状态复用、软中断分布优化及tuned工具的自动化调优。通过具体配置参数和实际案例(如VoIP软交换系统)深入解析各项调优措施的设计原理与实施效果,有效解决高CPS下丢包、连接失败等问题,并展望了向云化、eBPF等动态智能调优方向的发展趋势。; 适合人群:从事通信系统运维、网络开发或Linux系统性能优化的技术人员,具备一定操作系统和网络基础知识,工作经验1年以上的中初级工程师。; 使用场景及目标:①应用于软交换、媒体网关、信令网关等高并发通信设备的系统调优;②解决UDP丢包、conntrack表满、TCP连接队列溢出等典型性能瓶颈;③提升系统在小包高频、低时延要求场景下的稳定性和吞吐能力。; 阅读建议:建议结合实际生产环境或测试平台同步验证文中配置,重点关注参数背后的物理意义(如BDP、softirq、conntrack机制),并配合ss、conntrack、dmesg等命令进行调优前后对比分析,确保安全可控地实施变更。

从Elasticsearch的jvm.options读懂JVM参数的生效核验、内存分账与诊断兜底代码包

拿到一台机器和一个 Java 服务,怎样确认 JVM 实际吃进去了哪些参数,怎样给堆和堆外分配内存,怎样把 GC 日志、堆转储、异常栈这些“事后取证”的参数配齐,以及怎样在 JDK 8 与 JDK 9+ 之间安全迁移。 讲解的抓手是 Elasticsearch(下文简称 ES)的 jvm.options。这份文件经过 ES 团队多年打磨,又被无数生产集群验证过,几乎每一行都对应一个踩过的坑,是学习 JVM 参数最好的“样板间”。

【选址和定容】模拟退火改进多目标粒子群算法在分布式电源选址和定容中的应用【IEEE69节点】(Matlab代码实现)

内容概要:本文研究了模拟退火改进多目标粒子群算法在分布式电源选址和定容中的应用,以IEEE69节点配电系统为算例进行仿真分析。通过融合模拟退火算法的强全局搜索能力与粒子群算法的高效局部收敛特性,构建了一种改进的多目标优化算法,用于解决分布式电源在配电网中的最优位置选择与容量配置问题。研究旨在实现多重优化目标,包括最小化网络有功损耗、提升节点电压质量、增强系统运行的经济性与稳定性。文中详细阐述了多目标优化模型的数学构建、算法的改进机制与实现流程,并基于Matlab平台完成了算法编程与仿真验证,结果表明所提方法在求解质量和收敛性能上均优于传统算法。; 适合人群:具备电力系统分析、优化理论基础及Matlab编程能力,从事配电网规划、分布式能源系统优化、智能优化算法应用等相关领域的科研人员、工程师以及高校研究生。; 使用场景及目标:①解决高比例分布式电源接入背景下配电网的科学规划问题;②为新型电力系统中源网协调设计提供有效的优化工具;③为相关领域的科研工作提供可复现、可拓展的算法模型与仿真代码实例,支持进一步的算法对比与功能升级。; 阅读建议:建议读者结合提供的Matlab代码与IEEE69节点标准数据,动手复现实验结果,深入理解算法的参数设置、迭代过程与多目标折衷分析方法,并可根据实际研究需求修改目标函数或引入新的约束条件以适应不同的应用场景。

2024 《计算机网络》实验教学指导书.doc

2024 《计算机网络》实验教学指导书.doc

无刷直流电机BLDC无感+滑模观测器+转速电流双闭环PI控制(总共三个仿真模型)(Simulink仿真实现)

内容概要:本文档系统性地提供了无刷直流电机(BLDC)的高级控制策略仿真资源,聚焦于无位置传感器控制技术,重点实现了基于滑模观测器(SMO)的转子位置估算方法,并结合转速与电流双闭环PI控制结构,构建了完整的Simulink仿真模型体系。资源包含三个核心仿真模型:无感控制下的滑模观测器设计、双闭环PI控制器的参数整定与动态调节,以及系统整体的运行性能仿真分析。文档深入剖析了滑模观测器在反电动势提取与相位补偿中的关键技术,展示了其在不同工况下对电机启动、调速及负载扰动响应的鲁棒性表现,旨在帮助研究人员掌握BLDC在无传感器条件下的高精度控制实现路径,并为进一步引入模糊PID等先进控制策略提供对比基准与技术支撑。; 适合人群:具备电机控制理论基础、自动控制原理知识及Simulink建模经验,从事电气工程、自动化、电力电子或新能源驱动系统研究的科研人员、工程技术人员及高校研究生。; 使用场景及目标:①深入理解无刷直流电机无位置传感器控制的基本原理与实现流程;②掌握滑模观测器在转子位置与速度估算中的设计方法及其抗干扰特性;③学习并优化转速电流双闭环PI控制结构,提升系统动态响应性能与运行稳定性。; 阅读建议:建议结合Simulink模型进行同步仿真操作,重点关注滑模观测器的抖振抑制效果、系统启动过程的稳定性以及PI参数调节对动态性能的影响,同时可参照文档中提及的模糊PID等对比方案,拓展对先进控制算法的研究与实践应用。

Basilisk vs. STK:开源航天仿真工具在Windows上的实战体验与生态对比

本文对比了开源航天仿真工具Basilisk与商业软件STK在Windows平台上的实战体验与生态差异。从技术架构、安装配置、使用成本、功能覆盖、社区生态到适用场景,全面分析了二者的优劣势,为航天工程师和研究人员提供选型参考。Basilisk在性能和扩展性上表现突出,而STK在可视化与专业模块上更具优势。

weixin_30632089的博客 588

解决redhat8/centos8无法使用yum问题(报错:This system is not registered to Red Hat Subscription Management)

解决redhat无法使用yum问题、以及替换repo文件后仍无法使用yum的问题

qq_43569119的博客 4342
上一篇: 25. 【C语言】二进制文件与随机读写
下一篇: 27. 【C语言】编写可移植的头文件与模块
gugucoding
博客等级 码龄140天 7粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值