news 2026/5/1 10:47:36

CentOS Stream 9入门学习教程,从入门到精通,CentOS Stream 9 中 Linux C 编程 —语法详解与实战案例(13)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CentOS Stream 9入门学习教程,从入门到精通,CentOS Stream 9 中 Linux C 编程 —语法详解与实战案例(13)

CentOS Stream 9 中 Linux C 编程 —语法详解与实战案例


一、概述

在 Linux 系统中进行 C 语言开发,主要依赖三大核心工具:

工具功能
GCCGNU 编译器集合,用于编译 C/C++ 代码
GDBGNU 调试器,用于调试程序运行时错误
Make / Makefile自动化编译工具,管理多文件项目依赖
Autotools项目自动化构建系统(configure + Makefile)

✅ 开发环境准备(CentOS Stream 9):

# 安装开发工具包sudodnf groupinstall"Development Tools"-y# 安装调试工具sudodnfinstallgdb -y# 安装 Autotoolssudodnfinstallautoconf automake libtool -y# 验证安装gcc --version gdb --versionmake--version

二、GCC 编译


2.1 GCC 工具链

GCC(GNU Compiler Collection)包含多个工具:

工具作用
gccC 语言编译器前端
cppC 预处理器
as汇编器
ld链接器
ar静态库打包工具
nmobjdumpreadelf目标文件分析工具

✅ 编译流程四阶段:

源代码(.c) → 预处理(.i) → 编译(.s) → 汇编(.o) → 链接(可执行文件)

2.2 gcc 命令基本用法

基本语法:

gcc[选项][输入文件]-o[输出文件]

常用选项:

选项说明
-E只进行预处理
-S只进行编译到汇编
-c只编译到目标文件(.o)
-o指定输出文件名
-g生成调试信息(供 GDB 使用)
-Wall启用所有警告
-O0/-O1/-O2/-O3优化级别(0=无优化,3=最高优化)
-I<目录>指定头文件搜索路径
-L<目录>指定库文件搜索路径
-l<库名>链接指定库(如 -lm 链接 math 库)

2.3 gcc 使用实例

✅ 案例1:编译单文件程序

// hello.c#include<stdio.h>intmain(){printf("Hello, Linux C Programming!\n");return0;}
# 编译并运行gcc hello.c -o hello ./hello# 输出:Hello, Linux C Programming!

✅ 案例2:分步编译(预处理 → 编译 → 汇编 → 链接)

# 1. 预处理(展开宏、包含头文件)gcc -E hello.c -o hello.i# 2. 编译为汇编代码gcc -S hello.i -o hello.s# 3. 汇编为目标文件gcc -c hello.s -o hello.o# 4. 链接生成可执行文件gcc hello.o -o hello# 或者一步到位gcc hello.c -o hello

✅ 案例3:启用调试和警告

gcc -g -Wall -O0 hello.c -o hello_debug# -g:生成调试信息# -Wall:显示所有警告# -O0:不优化,便于调试

✅ 案例4:链接数学库

// math_test.c#include<stdio.h>#include<math.h>intmain(){doublex=2.0;doubleresult=sqrt(x);printf("sqrt(%.1f) = %.6f\n",x,result);return0;}
# 必须链接数学库 -lmgcc math_test.c -o math_test -lm ./math_test# 输出:sqrt(2.0) = 1.414214

三、综合案例:使用 GCC 编译包含多个源文件的项目


3.1 案例概述

项目结构:

project/ ├── main.c // 主函数 ├── calc.h // 函数声明 ├── calc.c // 函数实现 └── Makefile // 后续章节使用

功能:实现加减乘除计算器


3.2 案例详解

✅ 文件1:calc.h(头文件)

// calc.h - 函数声明#ifndefCALC_H#defineCALC_H// 加法intadd(inta,intb);// 减法intsubtract(inta,intb);// 乘法intmultiply(inta,intb);// 除法(注意除零检查)doubledivide(inta,intb);#endif

✅ 文件2:calc.c(函数实现)

// calc.c - 函数定义#include"calc.h"#include<stdio.h>intadd(inta,intb){returna+b;}intsubtract(inta,intb){returna-b;}intmultiply(inta,intb){returna*b;}doubledivide(inta,intb){if(b==0){fprintf(stderr,"Error: Division by zero!\n");return0.0;}return(double)a/(double)b;}

✅ 文件3:main.c(主程序)

// main.c - 主函数#include<stdio.h>#include"calc.h"intmain(){intx=10,y=5;printf("x = %d, y = %d\n",x,y);printf("%d + %d = %d\n",x,y,add(x,y));printf("%d - %d = %d\n",x,y,subtract(x,y));printf("%d * %d = %d\n",x,y,multiply(x,y));printf("%d / %d = %.2f\n",x,y,divide(x,y));// 测试除零printf("10 / 0 = %.2f\n",divide(10,0));return0;}

✅ 手动编译命令:

# 方法1:一步编译所有源文件gcc main.c calc.c -o calculator -g -Wall# 方法2:分步编译(推荐用于大型项目)gcc -c main.c -o main.o# 编译 main.cgcc -c calc.c -o calc.o# 编译 calc.cgcc main.o calc.o -o calculator# 链接# 运行./calculator

✅ 输出:

x = 10, y = 5 10 + 5 = 15 10 - 5 = 5 10 * 5 = 50 10 / 5 = 2.00 Error: Division by zero! 10 / 0 = 0.00

四、GDB 调试


4.1 GDB 基本命令

编译时必须加-g选项:

gcc -g -Wall main.c calc.c -o calculator

常用 GDB 命令:

命令说明
gdb ./program启动 GDB
runr运行程序
breakb设置断点(b main,b 10,b calc.c:5
continuec继续执行
nextn单步执行(不进入函数)
steps单步执行(进入函数)
printp打印变量值(p x,p result
listl显示源代码
backtracebt显示调用栈
quitq退出 GDB

4.2 综合案例:使用 GDB 调试 C 语言项目


4.2.1 案例概述

修改calc.c引入一个 bug,使用 GDB 定位并修复。


4.2.2 案例详解

✅ 修改calc.c(故意制造 bug):

// calc.c - 有 bug 的版本#include"calc.h"#include<stdio.h>intadd(inta,intb){returna+b;// 正常}intsubtract(inta,intb){returna-b;// 正常}intmultiply(inta,intb){returna*b+1;// BUG: 多加了1!}doubledivide(inta,intb){if(b==0){fprintf(stderr,"Error: Division by zero!\n");return0.0;}return(double)a/(double)b;}

✅ 重新编译:

gcc -g -Wall main.c calc.c -o calculator

✅ 启动 GDB:

gdb ./calculator

✅ GDB 调试过程:

(gdb) break multiply # 在 multiply 函数设断点 Breakpoint 1 at 0x40114e: file calc.c, line 12. (gdb) run # 运行程序 Starting program: /home/user/project/calculator x = 10, y = 5 10 + 5 = 15 10 - 5 = 5 Breakpoint 1, multiply (a=10, b=5) at calc.c:12 12 return a * b + 1; # 停在这里 (gdb) print a # 查看变量 a $1 = 10 (gdb) print b # 查看变量 b $2 = 5 (gdb) next # 执行下一行 13 } (gdb) print a * b + 1 # 手动计算 $3 = 51 # 应该是50,多加了1! (gdb) quit # 退出

✅ 修复 bug:

// 修复:去掉 +1intmultiply(inta,intb){returna*b;// 修复后}

✅ 重新编译并测试:

gcc -g -Wall main.c calc.c -o calculator ./calculator# 输出:10 * 5 = 50 (正确!)

五、Make 编译


5.1 make 和 Makefile 概述

Makefile是一个文本文件,定义了:

  • 目标(target)
  • 依赖(dependencies)
  • 命令(commands)

make工具根据 Makefile 自动判断哪些文件需要重新编译。


5.2 Makefile 语法基础

基本语法:

target: dependencies <TAB>command

✅ 示例:

# 最简单的 Makefile hello: hello.c gcc hello.c -o hello

特殊变量:

变量说明
$@目标文件名
$<第一个依赖文件
$^所有依赖文件

伪目标(.PHONY):

.PHONY: clean clean: rm -f *.o calculator

5.3 Makefile 实例

✅ 基础版 Makefile(对应前面的计算器项目)

# Makefile for calculator project # 编译器 CC = gcc # 编译选项 CFLAGS = -g -Wall # 目标文件 TARGET = calculator # 源文件 SRCS = main.c calc.c # 目标文件 OBJS = $(SRCS:.c=.o) # main.o calc.o # 默认目标 all: $(TARGET) # 链接目标文件 $(TARGET): $(OBJS) $(CC) $(OBJS) -o $(TARGET) # 编译 .c 到 .o %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ # 清理 .PHONY: clean clean: rm -f $(OBJS) $(TARGET) # 重新编译 .PHONY: rebuild rebuild: clean all

✅ 使用:

# 编译make# 清理makeclean# 重新编译makerebuild# 查看帮助(可选添加).PHONY:helphelp: @echo"Available targets:"@echo" make - 编译项目"@echo" make clean - 清理目标文件"@echo" make rebuild - 重新编译"

5.4 Make 编译的基本步骤

  1. 编写 Makefile:定义目标、依赖、命令
  2. 运行 make:自动检查依赖,只编译修改过的文件
  3. 增量编译:节省时间,提高效率
  4. 清理项目make clean删除中间文件

六、综合案例:使用 Makefile 管理 C 语言项目


6.1 案例概述

项目结构升级:

advanced_project/ ├── src/ │ ├── main.c │ ├── calc.c │ └── utils.c ├── include/ │ ├── calc.h │ └── utils.h ├── lib/ ├── bin/ └── Makefile

新增功能:字符串工具函数


6.2 案例详解1(基础版)

✅ 创建目录结构:

mkdir-p advanced_project/{src,include,lib,bin}cdadvanced_project

✅ 文件1:include/utils.h

// utils.h#ifndefUTILS_H#defineUTILS_H// 字符串反转voidreverse_string(char*str);// 字符串长度intstring_length(constchar*str);#endif

✅ 文件2:src/utils.c

// utils.c#include"utils.h"intstring_length(constchar*str){intlen=0;while(str[len]!='\0'){len++;}returnlen;}voidreverse_string(char*str){intlen=string_length(str);inti,j;chartemp;for(i=0,j=len-1;i<j;i++,j--){temp=str[i];str[i]=str[j];str[j]=temp;}}

✅ 修改src/main.c

// main.c#include<stdio.h>#include"calc.h"#include"utils.h"intmain(){intx=10,y=5;chartest_str[]="Hello World";printf("=== Calculator Test ===\n");printf("%d + %d = %d\n",x,y,add(x,y));printf("%d * %d = %d\n",x,y,multiply(x,y));printf("\n=== String Utils Test ===\n");printf("Original: %s\n",test_str);reverse_string(test_str);printf("Reversed: %s\n",test_str);return0;}

✅ 基础版 Makefile:

# Makefile - 基础版 CC = gcc CFLAGS = -g -Wall -I./include TARGET = bin/calculator SRCDIR = src INCDIR = include BINDIR = bin SRCS = $(wildcard $(SRCDIR)/*.c) OBJS = $(SRCS:$(SRCDIR)/%.c=$(BINDIR)/%.o) $(BINDIR)/%.o: $(SRCDIR)/%.c @mkdir -p $(BINDIR) $(CC) $(CFLAGS) -c $< -o $@ $(TARGET): $(OBJS) @mkdir -p $(dir $@) $(CC) $(OBJS) -o $@ .PHONY: clean clean: rm -rf $(BINDIR) .PHONY: run run: $(TARGET) ./$(TARGET) .PHONY: all all: $(TARGET) .PHONY: help help: @echo "Targets:" @echo " make - 编译" @echo " make run - 运行" @echo " make clean - 清理"

✅ 编译运行:

makemakerun

输出:

=== Calculator Test === 10 + 5 = 15 10 * 5 = 50 === String Utils Test === Original: Hello World Reversed: dlroW olleH

6.3 案例详解2(进阶版)

✅ 进阶版 Makefile(支持调试/发布模式、自动依赖)

# Makefile - 进阶版 # ============ 配置 ============ CC = gcc BINDIR = bin SRCDIR = src INCDIR = include LIBDIR = lib # 调试模式(默认)或发布模式 DEBUG ?= 1 ifeq ($(DEBUG), 1) CFLAGS = -g -Wall -O0 -DDEBUG TARGET = $(BINDIR)/calculator_debug else CFLAGS = -O2 -DNDEBUG TARGET = $(BINDIR)/calculator_release endif CFLAGS += -I$(INCDIR) # 自动发现源文件 SRCS = $(wildcard $(SRCDIR)/*.c) OBJS = $(SRCS:$(SRCDIR)/%.c=$(BINDIR)/%.o) DEPS = $(OBJS:.o=.d) # 自动生成依赖 $(BINDIR)/%.d: $(SRCDIR)/%.c @mkdir -p $(dir $@) @$(CC) -MM -MT "$(BINDIR)/$*.o" -MF $@ $(CFLAGS) $< # 包含依赖文件(如果存在) -include $(DEPS) # 编译规则 $(BINDIR)/%.o: $(SRCDIR)/%.c @mkdir -p $(dir $@) $(CC) $(CFLAGS) -c $< -o $@ # 链接 $(TARGET): $(OBJS) @mkdir -p $(dir $@) $(CC) $(OBJS) -o $@ # 清理 .PHONY: clean clean: rm -rf $(BINDIR)/* # 重新编译 .PHONY: rebuild rebuild: clean $(TARGET) # 运行 .PHONY: run run: $(TARGET) ./$(TARGET) # 调试(使用 GDB) .PHONY: debug debug: $(TARGET) gdb ./$(TARGET) # 发布版本 .PHONY: release release: $(MAKE) DEBUG=0 # 默认目标 .PHONY: all all: $(TARGET) # 帮助 .PHONY: help help: @echo "Advanced Makefile Usage:" @echo " make - 编译调试版本" @echo " make DEBUG=0 - 编译发布版本" @echo " make run - 运行程序" @echo " make debug - 使用 GDB 调试" @echo " make release - 编译发布版本" @echo " make clean - 清理" @echo " make rebuild - 重新编译"

✅ 使用示例:

# 调试版本makemakerun# 发布版本makerelease ./bin/calculator_release# 调试程序makedebug# 清理makeclean

七、Makefile 自动生成技术


7.1 Autotools 简介

Autotools 是一套自动化构建工具,包含:

工具作用
autoconf生成 configure 脚本
automake生成 Makefile.in
libtool管理库文件

工作流程:

Makefile.am + configure.ac → automake → Makefile.in → autoconf → configure → ./configure → Makefile → make → 可执行文件

八、综合案例:使用 Autotools 管理 C 语言项目


8.1 案例概述

项目结构:

autotools_project/ ├── configure.ac # autoconf 配置 ├── Makefile.am # automake 配置 ├── src/ │ ├── Makefile.am # 子目录 Makefile.am │ ├── main.c │ ├── calc.c │ └── utils.c └── include/ ├── calc.h └── utils.h

8.2 案例详解

✅ 步骤1:创建configure.ac

# 在项目根目录创建 configure.actouchconfigure.ac
# configure.ac AC_INIT([calculator], [1.0], [your-email@example.com]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_PROG_CC AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([ Makefile src/Makefile ]) AC_OUTPUT

✅ 步骤2:创建根目录Makefile.am

# Makefile.am SUBDIRS = src

✅ 步骤3:创建src/Makefile.am

# src/Makefile.am bin_PROGRAMS = calculator calculator_SOURCES = main.c calc.c utils.c calculator_CFLAGS = -I$(top_srcdir)/include

✅ 步骤4:运行 Autotools 生成构建系统

# 1. 生成 aclocal.m4aclocal# 2. 生成 configure 脚本autoconf# 3. 生成 Makefile.inautomake --add-missing# 4. 运行 configure 生成 Makefile./configure# 5. 编译make# 6. 安装(可选)sudomakeinstall# 7. 清理makeclean

✅ 完整构建脚本build.sh

#!/bin/bash# build.sh - 一键构建脚本set-e# 遇错停止echo"🔄 正在生成构建系统..."# 生成 aclocal.m4echo"1/5: 运行 aclocal..."aclocal# 生成 configureecho"2/5: 运行 autoconf..."autoconf# 生成 Makefile.inecho"3/5: 运行 automake..."automake --add-missing# 配置项目echo"4/5: 运行 configure..."./configure# 编译echo"5/5: 运行 make..."makeecho"✅ 构建完成!可执行文件:src/calculator"echo"💡 运行:./src/calculator"

✅ 使用:

chmod+x build.sh ./build.sh ./src/calculator

✅ 支持标准操作:

./configure --prefix=/usr/local# 指定安装路径makemakecheck# 运行测试(需配置)sudomakeinstall# 安装makeuninstall# 卸载(需配置)

✅ Linux C 编程最佳实践

  1. 始终使用-Wall -Wextra:开启所有警告
  2. 调试版本加-g:便于 GDB 调试
  3. 使用 Makefile:管理多文件项目
  4. 分离头文件和源文件include/src/
  5. 使用 Autotools:便于跨平台分发
  6. 版本控制:使用 Git 管理代码
  7. 代码格式化:使用indentclang-format
  8. 静态分析:使用cppchecksplint

📚 附录:常用命令速查表

功能命令
编译单文件gcc -g -Wall file.c -o program
调试程序gdb ./program
设置断点break function_namebreak line_number
运行 Makefilemake
清理make clean
生成 Autotoolsaclocal && autoconf && automake --add-missing
配置项目./configure
安装sudo make install

这份文档覆盖了 CentOS Stream 9 上Linux C 编程的全部核心知识点 + 语法细节 + 实用案例 + 综合项目,所有代码均含详细注释,可直接用于教学、自学或生产环境参考。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 3:48:28

Wan2.2-T2V-A14B能否用于电影分镜草稿的快速生成?

Wan2.2-T2V-A14B能否用于电影分镜草稿的快速生成&#xff1f; 在影视工业中&#xff0c;一个导演从灵感到成片的过程往往要跨越无数道门槛——而其中最耗时、最依赖人力的环节之一&#xff0c;就是分镜草稿的绘制。传统流程里&#xff0c;画师需要反复与导演沟通&#xff0c;将…

作者头像 李华
网站建设 2026/4/30 11:57:22

PyTorch Chamfer Distance:重新定义3D点云相似性度量标准

PyTorch Chamfer Distance&#xff1a;重新定义3D点云相似性度量标准 【免费下载链接】pyTorchChamferDistance Implementation of the Chamfer Distance as a module for pyTorch 项目地址: https://gitcode.com/gh_mirrors/py/pyTorchChamferDistance 在3D深度学习领域…

作者头像 李华
网站建设 2026/5/1 3:45:15

ModernWMS开源仓库管理系统:从入门到精通的全流程指南

ModernWMS开源仓库管理系统&#xff1a;从入门到精通的全流程指南 【免费下载链接】ModernWMS The open source simple and complete warehouse management system is derived from our many years of experience in implementing erp projects. We stripped the original comm…

作者头像 李华
网站建设 2026/5/1 4:43:13

超越传统T2V模型:Wan2.2-T2V-A14B的三大核心技术优势

超越传统T2V模型&#xff1a;Wan2.2-T2V-A14B的三大核心技术优势 在视频内容主导信息传播的今天&#xff0c;谁能更快、更准地将创意转化为视觉现实&#xff0c;谁就掌握了表达的主动权。文本到视频&#xff08;Text-to-Video, T2V&#xff09;技术正站在这一变革的前沿——它不…

作者头像 李华
网站建设 2026/5/1 1:14:35

9 个 MBA 课堂汇报工具推荐,AI 降重免费网站合集

9 个 MBA 课堂汇报工具推荐&#xff0c;AI 降重免费网站合集 论文如山压顶&#xff0c;降重成了最头疼的“隐形任务” MBA课堂汇报和论文写作&#xff0c;是每一位MBA学生在求学过程中必须面对的重要挑战。无论是案例分析、商业计划书&#xff0c;还是文献综述和实证研究&#…

作者头像 李华