import{_ as s,c as a,o as i,a6 as n}from"./chunks/framework.CZRoMP2i.js";const l="/c/assets/1.D60Zf6_d.png",e="/c/assets/2.D2-G6nV2.png",p="/c/assets/3.DpzkVk5V.png",t="/c/assets/4.BXk95GIP.png",r="/c/assets/5.CbWTB08W.png",c="/c/assets/6.twO9TCIg.png",h="/c/assets/7.CKOjeIvS.png",d="/c/assets/8.DKmR0CxE.png",o="/c/assets/9.Cudf77_s.gif",k="/c/assets/10.BBUUlhRC.png",u="/c/assets/11.iLABkB7O.png",g="/c/assets/12.BQuYWOU9.png",b="/c/assets/13.CslpH6j0.png",m="/c/assets/14.BAyvZdKq.png",E="/c/assets/15.C3oC1iUd.png",C="/c/assets/16.Ds-jsEZn.png",F="/c/assets/17.Cd37gMYs.png",y="/c/assets/18.CAw2z3gc.png",_="/c/assets/19.DdPThnr-.png",v="/c/assets/20.q_rvlDnY.png",B="/c/assets/21.JRHg9RZA.png",f="/c/assets/22.Baq-Hb06.png",A="/c/assets/23.c1ht53mu.png",D="/c/assets/24.CAZmH5Py.png",x="/c/assets/25.DWeCYBe9.png",q="/c/assets/26.2XM8pYni.png",w="/c/assets/27.CN0t-fuo.png",S="/c/assets/28.AcDh3LXQ.png",L="/c/assets/29.CUkDFAc6.png",P="/c/assets/30.picNTNaJ.png",T="/c/assets/31.DKX92RgJ.png",W="/c/assets/32.Bxr7QKI3.png",M="/c/assets/33.DuFWsOgW.png",U="/c/assets/34.Da9qUcfr.png",R="/c/assets/35.7_gEABSX.gif",O="/c/assets/36.C2KQYoVC.gif",N="/c/assets/37.RTUP8Vtx.png",I="/c/assets/38.Dq21DxwL.png",V="/c/assets/39.QmpUaNxU.png",G="/c/assets/40.DP0C29gZ.png",X="/c/assets/41.DwzHokd4.png",$="/c/assets/42.Bi6K26yA.png",H="/c/assets/43.Bw8DcEQ_.png",K="/c/assets/44.DPc8Z9rS.png",Q="/c/assets/45.S84xHMTl.png",j="/c/assets/46.iw3JQUkn.png",Y="/c/assets/47.ILeJt-HK.png",J="/c/assets/48.CHgm7khh.png",Z="/c/assets/49.N1nqJaEg.png",z="/c/assets/50.DHsnibMi.png",ss="/c/assets/51.BQr6Q0uV.png",as="/c/assets/52.BVemi2Lh.png",is="/c/assets/53.BHR69UXx.png",ns="/c/assets/54.CPSU5SJI.png",ls="/c/assets/55.CaQLoDlw.png",es="/c/assets/56.aRGy4XbL.png",ps="/c/assets/57.kNO9fmPR.png",ts="/c/assets/58.D4EkoC4o.png",rs="/c/assets/59.V23Lo9e_.png",cs="/c/assets/60.Du9LVeMB.png",hs="/c/assets/61.DdFg75U9.png",ds="/c/assets/62.C6bz6KtT.png",os="/c/assets/63.CB6LAhB5.png",ks="/c/assets/64.Bip8bkua.png",us="/c/assets/65.DRNHRduW.png",gs="/c/assets/66.Cth4qqEn.png",bs="/c/assets/67.DWGWZ64P.png",ms="/c/assets/68.3hDIDdvx.png",Es="/c/assets/69.Bw_dQ4ap.png",Cs="/c/assets/70.Cn_ubTyA.png",Fs="/c/assets/71.C84EBqwB.png",ys="/c/assets/72.dZfJY4eR.png",_s="/c/assets/73.B0zm0Z79.png",vs="/c/assets/74.CaTcEy1Q.png",Bs="/c/assets/75.iEc8mo9g.png",fs="/c/assets/76.Co2KxM6t.png",As="/c/assets/77.CaUm8Qhc.png",Ds="/c/assets/78.kOkqIKG6.png",xs="/c/assets/79.CyeASH-c.png",qs="/c/assets/80.CFdk60La.png",ws="/c/assets/81.Bhl-0uK_.png",Ss="/c/assets/82.Dni9KbXV.png",Ls="/c/assets/83.BXx10MCV.png",Ps="/c/assets/84.CXcIKX1T.png",Ts="/c/assets/85.CQ3_QCQT.png",Ws="/c/assets/86.CQoDRJM5.gif",Ms="/c/assets/87.CPfwZvD9.gif",Us="/c/assets/88.bxEomEjU.gif",Rs="/c/assets/89.C_onhf2k.png",Os="/c/assets/90.Budj3s38.gif",Ns="/c/assets/91.CH8koQdu.gif",Is="/c/assets/92.kUJhxMtg.png",Vs="/c/assets/93.BJeJJW4_.png",Gs="/c/assets/94.BCuK6eJL.gif",Xs="/c/assets/95.rKC-z4z-.gif",$s="/c/assets/96.BJE3xxuT.gif",Hs="/c/assets/97.DJOq__O0.gif",Ks="/c/assets/98.BDt_0fRR.png",Qs="/c/assets/99.Bo5OawW8.png",js="/c/assets/100.sUWUfl5e.png",Ys="/c/assets/101.BK4jpnB8.png",Js="/c/assets/102.EF8vdbSq.png",Zs="/c/assets/103.DjxdA_Co.png",zs="/c/assets/104.sp68q1hh.gif",sa="/c/assets/105.DhMRyxNN.gif",aa="/c/assets/106.CdcLZM0R.gif",ia="/c/assets/107.D-5AsTTr.png",na="/c/assets/108.2RQKmAUa.png",la="/c/assets/109.CI4xX8SM.png",ea="/c/assets/110.C8QUZ9v3.gif",pa="/c/assets/111.g5tQfhWz.gif",ta="/c/assets/112.CX0_1NsE.gif",ra="/c/assets/113.BrFJeoK6.png",ca="/c/assets/114.58TjSSjH.gif",ha="/c/assets/115.CgqNV2hL.png",da="/c/assets/116.BasYWvkM.png",oa="/c/assets/117.CjFxJpBr.png",ka="/c/assets/118.Dm5Jspvp.gif",ua="/c/assets/119.1krCh8cy.gif",ga="/c/assets/120.DOSyahv7.gif",ba="/c/assets/121.BHEvX_FI.gif",ma="/c/assets/122.DFA0g1_d.gif",Ea="/c/assets/123.D50nO5eA.gif",Ca="/c/assets/124.cAvG1Qfq.png",Fa="/c/assets/125.DpakQFWz.gif",ya="/c/assets/126.Bg61j9QI.gif",_a="/c/assets/127.DPvD9UCw.gif",va="/c/assets/128.Ceu65U_n.gif",Ba="/c/assets/129.BWPFRK_8.gif",fa="/c/assets/130.Ct4TfxPf.gif",Aa="/c/assets/131.zsKtx_jV.png",Da="/c/assets/132.3oqDAW0w.png",xa="/c/assets/133.D9TSeAa9.gif",qa="/c/assets/134.CCRgYIVq.png",wa="/c/assets/135.C1t2T6FV.gif",Sa="/c/assets/136.Rqa4uHq6.png",La="/c/assets/137.6yQYnjOa.gif",Pa="/c/assets/138.hYR9GiiD.gif",Ta="/c/assets/139.D3b-QIrA.gif",Wa="/c/assets/140.DGbA6qsW.gif",Ma="/c/assets/141.BToOkxf2.gif",Ua="/c/assets/142.C3wekjfY.png",Ra="/c/assets/143.CKuuzuQ_.png",Oa="/c/assets/144.B4r6Nv14.gif",Na="/c/assets/145.CvbhuZNK.png",Ia="/c/assets/146.BPgYm4ZX.gif",Va="/c/assets/147.DH2fri13.gif",Ga="/c/assets/148.CDDIqy03.gif",Xa="/c/assets/149.DCQsqYYC.gif",$a="/c/assets/150.CUjMoXNF.gif",Ha="/c/assets/151.BWbajkuB.gif",Ka="/c/assets/152.C1JnBDr7.png",Qa="/c/assets/153.DwN2p3bo.png",ja="/c/assets/154.DdSfz-Pf.gif",Ya="/c/assets/155.BMocjVt7.gif",Ja="/c/assets/156.BUU-wlaw.gif",Za="/c/assets/157.ssadIF0D.gif",za="/c/assets/158.Dq5lLq9v.gif",si="/c/assets/159.CJ0_loZ8.gif",ai="/c/assets/160.BPOK9irZ.gif",ii="/c/assets/161.B1eB55rC.gif",ni="/c/assets/162.VIcU-hkN.gif",li="/c/assets/163.BM9viRZJ.gif",ei="/c/assets/164.DpMBA1SK.gif",pi="/c/assets/165.DgXuU6LF.png",ti="/c/assets/166.Dnw73s2h.gif",ri="/c/assets/167.SnFXRSaL.png",ci="/c/assets/168.DnoEqOjV.png",hi="/c/assets/169.BJBdn7pw.png",di="/c/assets/170.DXtQWYsM.gif",oi="/c/assets/171.hcERTQkN.gif",ki="/c/assets/172.CioraEUv.png",ui="/c/assets/173.kWHWwnc_.png",Ai=JSON.parse('{"title":"第一章:开发环境的安装和配置(⭐)","description":"","frontmatter":{},"headers":[],"relativePath":"notes/01_c-basic/01_xdx/index.md","filePath":"notes/01_c-basic/01_xdx/index.md","lastUpdated":1723426385000}'),gi={name:"notes/01_c-basic/01_xdx/index.md"},bi=n('

第一章:开发环境的安装和配置(⭐)

1.1 什么是编译器?

特性MinGW-w64CygwinMSYS2
简介Minimalist GNU for WindowsPOSIX 兼容环境和工具集结合了 MinGW 和 Cygwin 的工具集
编译器提供 GCC 编译器提供 POSIX 兼容环境,包含大量工具提供 MinGW-w64 工具链和 Cygwin 环境
生成文件Windows 原生可执行文件POSIX 兼容的可执行文件可以生成 Windows 原生可执行文件或 POSIX 文件
依赖无需额外依赖依赖 Cygwin DLL根据使用工具链决定(MinGW-w64 无依赖,Cygwin 有依赖)
工具和库基本的编译工具丰富的 Unix 工具和库丰富的工具和库,强大的包管理系统
性能性能较好可能较低,因为通过兼容层调用系统取决于使用的工具链(MinGW-w64 性能较好)
复杂度简单易用设置和使用相对复杂较为灵活,复杂度介于 MinGW-w64 和 Cygwin 之间
适用场景开发 Windows 原生应用运行和开发 Unix 程序混合使用 Unix 工具和开发 Windows 原生应用
优点轻量级,直接生成 Windows 应用完整的 POSIX 兼容环境,丰富的工具灵活的环境,强大的包管理系统
缺点工具和库较少生成文件依赖 Cygwin DLL,性能可能较低环境较大,占用更多空间,复杂性比 MinGW-w64 高

NOTE

1.2 编译器的安装和配置

1.2.2 MinGW-w64 的安装和配置

1.2.2.1 安装

NOTE

下载地址在这里

NOTE

本人的解压目录是:D:\\develop\\mingw64

1.2.2.2 配置 path 环境变量

NOTE

因为,本人安装 MinGW-w64 的目录是 D:\\develop\\mingw64,所以配置 path 环境变量就需要 D:\\develop\\mingw64\\bin

shell
gcc --version

1.2.3 Cygwin 的安装和配置

1.2.3.1 安装

NOTE

下载地址在这里

NOTE

默认是最小化安装,没有 GCC,需要选择 gcc-core、gcc-g++、make、gdb、binutils 。

1.2.3.2 配置 path 环境变量

1.2.4 MSYS2(推荐)

1.2.4.1 安装

NOTE

下载地址在这里

NOTE

可能很多人,会遇到安装到 50% 就一直卡死在那边,不用慌,关闭它,再次重新安装即可。

NOTE

如果没有出现命令终端,也不要慌,去 Win11 操作系统的开始菜单,那边找一下,就能找到。

shell
sed -i \\
    "s#https\\?://mirror.msys2.org/#https://mirrors.tuna.tsinghua.edu.cn/msys2/#g" \\
    /etc/pacman.d/mirrorlist*

shell
pacman -Syu --noconfirm # 更新包管理器
shell
pacman -Sy base-devel --noconfirm # 安装开发工具包
shell
pacman -Sy mingw-w64-x86_64-toolchain --noconfirm # 安装开发 gcc 相关工具链

1.2.4.2 配置 path 环境变量

1.3 什么是 IDE(集成开发环境)?

NOTE

1.43 IDE 的安装和配置

1.4.1 CLion

1.4.1.1 概述

NOTE

本次,演示的 CLion 的安装版本是 2024.1.4 ,后续版本可能会更新,但是操作几乎不会发生太多变化!!!

1.4.1.2 安装

1.4.1.3 配置

1.4.2 VS Code

1.4.2.1 概述

NOTE

1.4.2.2 安装

1.4.2.3 配置

1.4.3 Microsoft Visual Studio

1.4.3.1 概述

NOTE

本次,演示的 Visual Studio 的安装版本是 Visual Studio 2022 ,后续版本可能会更新,但是操作几乎不会发生太多变化!!!

1.4.3.2 安装

1.4.3.3 配置

NOTE

第二章:C 语言入门(HelloWorld,⭐)

2.1 手动版

c
#include <stdio.h>

int main(){
    printf("Hello World");
    return 0;
}

shell
gcc HelloWorld.c -o HelloWorld.exe

shell
./HelloWorld.exe

2.2 VS Code 版

c
#include <stdio.h>

int main(){
    printf("Hello World");
    return 0;
}

shell
gcc HelloWorld.c -o HelloWorld.exe

shell
./HelloWorld.exe

2.3 VS 版

c
#include <stdio.h>

int main(){
    printf("Hello World");
    return 0;
}

2.4 CLion 版

c
#include <stdio.h>

int main(){
    printf("Hello World");
    return 0;
}

NOTE

内容如下所示:

txt
-Dfile.encoding=UTF-8
-Dconsole.encoding=UTF-8

第三章:五花八门的 C 语言编译器(⭐)

3.1 概述

3.2 桌面操作系统

NOTE

MSVC 不开源,我们可以使用 Visual Studio Community 社区版,但是如果想使用 Visual Studio Community 社区版生成出来的应用进行商用,就需要好好阅读微软的许可证和说明书了。

NOTE

目前而言,GCC 已经属于跨平台的项目了,支持 Windows、Linux 和 MacOS ,在 Windows 上 GCC 的移植项目,如:MinGW、Cygwin 以及 MSYS2,其差别如下所示:

NOTE

在 MacOS 中,尽管 Clang 是默认编译器;但是,也可以 Homebrew 等包管理器来安装 GCC ,以便开发 C/C++ 项目。

3.3 嵌入式系统

3.4 C 语言为什么有那么多的编译器?

NOTE

各个厂商可以为了自己的利益、根据自己的喜好来开发编译器。

NOTE

微软官方给出的答复:最新的标准已经在 C++ 中支持了,C 语言就没必要再重复了。

IMPORTANT

在学习的时候,无所谓使用那个 C 语言编译器了;但是,如果要开发实际项目(开源或商业),最好使用 GCC 编译器,因为其功能最强大、开源、跨平台、免费,支持最新的 C 语言标准。

第四章:注释(⭐)

4.1 概述

NOTE

4.2 单行注释

c
// 单行注释

NOTE

在 CLion 中的快捷键是 Ctrl + /

c
#include <stdio.h> // 这是编译预处理指令

int main() { // 定义主函数

    printf("你好,世界!!!"); // 输出所指定的一行信息

    return 0;  // 函数执行完毕时返回函数值0
}

4.3 多行注释

c
/*
  这是第一行注释
  这是第二行注释
  这是第三行注释
*/

NOTE

c
#include <stdio.h> 

int main() { 
	
    /*
       printf(1);
       printf(2);
    */
    printf("你好,世界!!!"); 

    return 0;  
}

第五章:HelloWorld 的规范(⭐)

5.1 规范的代码风格

5.1.1 正确的缩进和空白

NOTE

各种 IDE 都有格式化的快捷键,如:CLion 的格式化快捷键是 Ctrl + Alt + L

c
#include <stdio.h>

int main() {

    int a = 1;
    int b = 2;
    int c = a + b;

    printf("c = %d", c);

    return 0;
}

5.1.2 代码风格

NOTE

看个人爱好,任选一种即可,本人喜欢行尾分格!!!

c
int main(){                                      
    if(a > b) {
		return a;
	} else {
		return b;
	}  
  	return 0;                   
}
c
int main()
{                                      
    if(a > b) 
	{
		return a;
	} 
	else 
	{
		return b;
	}  
  	return 0;                   
}

5.2 代码细节剖析

5.2.1 main() 函数

c
int main(){
    return 0;
}

NOTE

5.2.2 函数体

5.2.3 printf() 函数

c
printf (const char *__format, ...)
c
printf ("Hello World"); // 将字符串输出到控制台,行尾不换行
c
printf("Hello World\\n");

5.2.4 标准库和头文件

5.2.4.1 概述

c
#include <stdio.h>

5.2.4.2 标准库(Standard Library)

NOTE

实际的 printf() 函数的实现代码通常位于标准库的实现文件中,如:在 Linux 中的标准库libc.so.6 就包含了 printf() 函数的实现。

5.2.4.3 头文件(Header Files)

头文件功能说明常用函数和宏
stdio.h标准输入输出库printfscanffprintffscanffopenfclosefgetsfputs
stdlib.h标准库,提供内存分配、程序控制、类型转换、随机数生成等功能mallocfreeexitatoiatofrandsrand
string.h字符串处理库strlenstrcpystrncpystrcatstrcmpstrstrmemsetmemcpy
math.h数学库sincostanexplogsqrtpow
time.h时间和日期库timeclockdifftimemktimestrftimelocaltimegmtime
ctype.h字符处理库isalnumisalphaisdigitislowerisuppertolowertoupper
stdbool.h布尔类型库booltruefalse
assert.h断言库assert

5.2.4.4 预处理命令

c
// 用于包含标准库头文件或系统头文件。
// 编译器将在系统的标准头文件目录中查找文件。
#include <filename>
c
// 用于包含用户自定义的头文件。
// 编译器首先在当前目录中查找文件,如果未找到,再在标准头文件目录中查找。
#include "filename"

第六章:CLion 高级配置(⭐)

6.1 安装和配置 WSL2

6.1.1 概述

6.1.2 WSL2 的安装

powershell
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

IMPORTANT

以管理员身份打开 PowerShell 并运行,执行完上述命令之后,如果提示需要重启计算机,那就重启计算机。

powershell
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

IMPORTANT

以管理员身份打开 PowerShell 并运行,执行完上述命令之后,如果提示需要重启计算机,那就重启计算机。

powershell
wsl --update

NOTE

wsl2 的最新 Linux 内核包托管在 GitHub 上,某些国家可能会污染 Github 相关的域名,那么就需要手动下载,然后安装即可,下载地址在这里

powershell
wsl --set-default-version 2

powershell
wsl --list --online

powershell
wsl --install Ubuntu-24.04

NOTE

官方支持的 Linux 版本,托管在 Github 上,某些国家可能会污染 Github 的域名;此时,要么走科学上网,要么在 Microsoft Store 中搜索并安装。

powershell
wsl --list

6.1.3 配置 WSL2

shell
sudo dnf update -y # 更新包管理器 
sudo dnf groupinstall "Development Tools" -y # 安装开发工具包
sudo dnf install gcc gcc-c++ -y # 安装GCC相关工具链
sudo dnf install cmake -y # 安装 cmake
sudo dnf install make -y # 安装 make
sudo dnf install gdb -y # 安装 gdb

6.1.4 配置 WSL2

shell
sudo apt update && sudo apt upgrade -y # 更新包管理器
sudo apt install build-essential -y # 安装开发工具包
sudo apt install gcc g++ -y # 安装 GCC 相关工具链
sudo apt install cmake -y # 安装 cmake
sudo apt install gdb -y # 安装 gdb

NOTE

默认仓库中的 GDB 的版本会很高,CLion 会不支持,那么就需要手动下载源码,自行编译,本次不再演示!!!

6.2 切换 CLion 中的 cmake 的工具链

6.3 修改 CMakeLists.txt 文件

txt
cmake_minimum_required(VERSION 3.10)

# 项目名称和版本号
project(c-study VERSION 1.0 LANGUAGES C)

# 设置 C 标准
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED True)

# 辅助函数,用于递归查找所有源文件
function(collect_sources result dir)
    file(GLOB_RECURSE new_sources "\${dir}/*.c")
    set(\${result} \${\${result}} \${new_sources} PARENT_SCOPE)
endfunction()

# 查找顶层 include 目录(如果存在)
if (EXISTS "\${CMAKE_SOURCE_DIR}/include")
    include_directories(\${CMAKE_SOURCE_DIR}/include)
endif ()

# 查找所有源文件
set(SOURCES)
collect_sources(SOURCES \${CMAKE_SOURCE_DIR})

# 用于存储已经处理过的可执行文件名,防止重复
set(EXECUTABLE_NAMES)

# 创建可执行文件
foreach (SOURCE \${SOURCES})
    # 获取文件的相对路径
    file(RELATIVE_PATH REL_PATH \${CMAKE_SOURCE_DIR} \${SOURCE})
    # 将路径中的斜杠替换为下划线,生成唯一的可执行文件名
    string(REPLACE "/" "_" EXECUTABLE_NAME \${REL_PATH})
    string(REPLACE "\\\\" "_" EXECUTABLE_NAME \${EXECUTABLE_NAME})
    string(REPLACE "." "_" EXECUTABLE_NAME \${EXECUTABLE_NAME})

    # 处理与 CMakeLists.txt 文件同名的问题
    if (\${EXECUTABLE_NAME} STREQUAL "CMakeLists_txt")
        set(EXECUTABLE_NAME "\${EXECUTABLE_NAME}_exec")
    endif ()

    # 检查是否已经创建过同名的可执行文件
    if (NOT EXECUTABLE_NAME IN_LIST EXECUTABLE_NAMES)
        list(APPEND EXECUTABLE_NAMES \${EXECUTABLE_NAME})

        # 创建可执行文件
        add_executable(\${EXECUTABLE_NAME} \${SOURCE})

        # 查找源文件所在的目录,并添加为包含目录(头文件可能在同一目录下)
        get_filename_component(DIR \${SOURCE} DIRECTORY)
        target_include_directories(\${EXECUTABLE_NAME} PRIVATE \${DIR})

        # 检查并添加子目录中的 include 目录(如果存在)
        if (EXISTS "\${DIR}/include")
            target_include_directories(\${EXECUTABLE_NAME} PRIVATE \${DIR}/include)
        endif ()

        # 检查并添加 module 目录中的所有 C 文件(如果存在)
        if (EXISTS "\${DIR}/module")
            file(GLOB_RECURSE MODULE_SOURCES "\${DIR}/module/*.c")
            target_sources(\${EXECUTABLE_NAME} PRIVATE \${MODULE_SOURCES})
        endif ()
    endif ()
endforeach ()

6.4 配置 .clang-format 文件

txt
BasedOnStyle: Google
IndentWidth: 4
UseTab: Never
ColumnLimit: 0

# 控制大括号的位置
BreakBeforeBraces: Attach

# 控制空行的使用
EmptyLineBeforeAccessModifier: Never
KeepEmptyLinesAtTheStartOfBlocks: true

# 控制短函数、短 if 语句和循环的格式
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false

# 控制其他格式选项
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true

# 控制注释的格式化
ReflowComments: true

# 控制包含指令的格式化
IncludeBlocks: Regroup
SortIncludes: CaseInsensitive

SpaceBeforeParens: ControlStatements
SpacesInParentheses: false
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false

6.5 配置 .gitignore 文件

txt
.vscode
.idea
cmake-build-*
build

6.6 演示

NOTE

如果是复制并粘贴一个文件到项目中,请点击重新加载 CMake 项目!!!

第七章:C 语言的编译过程(⭐)

7.1 概述

IMPORTANT

源程序需要以 .c 作为扩展名。

IMPORTANT

IMPORTANT

IMPORTANT

如果修改了源代码,还需要重新编译链接,并生成新的 *.exe文件,再执行,方能生效。

7.2 GCC 编译器的介绍

7.3 通过 gcc 直接生成可执行文件

shell
gcc HelloWorld.c -o HelloWorld.exe

7.4 通过 gcc 分步编译

7.3.1 概述

shell
gcc -E 源文件.c -o 源文件.i # 通常以 .i 结尾表示这个文件是一个中间状态
shell
gcc -S 源文件.i -o 源文件.s # 在 Linux 中,通常以 .s 结尾;在 Windows 中,通常以 .asm 结尾
shell
gcc -c 源文件.s -o 源文件.o # 在 Linux 中,通常以 .o 结尾;在 Windows 中,通常以 .obj 结尾
shell
gcc 源文件.o -o 源文件.exe # 在 Linux 中,通常以 .out 结尾;在 Windows 中,通常以 .exe 结尾

7.4.2 应用示例

shell
gcc -E HelloWorld.c -o HelloWorld.i

shell
gcc -S HelloWorld.i -o HelloWorld.s

shell
gcc -c HelloWorld.s -o HelloWorld.o

shell
gcc HelloWorld.o -o HelloWorld.exe

第八章:附录

8.1 WSL2 代理问题

txt
[wsl2]
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true

[experimental]
# requires dnsTunneling but are also OPTIONAL
bestEffortDnsParsing=true
useWindowsDnsCache=true

shell
wsl --shutdown

8.2 CLion 调试问题

c
#include <stdio.h>

int main() {
    // 禁用 stdout 缓冲区
    setbuf(stdout, NULL);

    int a, b, c;
    printf("请输入整数 a 、b 和 c 的值:");
    scanf("%d %d %d", &a, &b, &c);

    int result = a * b * c;

    printf("%d × %d × %d = %d", a, b, c, result);

    return 0;
}

8.3 内存泄露检测

8.3.1 概述

NOTE

win 11 中的 WSL2 就是个 Linux 环境,我们可以在上面跑各种 Linux 工具,这样我们就不需要再安装虚拟机软件了,如:VMware Workstation(它会完整的模拟一个硬件系统,并在上面跑各种 Linux ,实在是太笨重了)。

8.3.2 安装

shell
dnf -y upgrade && dnf -y install valgrind # AlmaLinux
shell
apt -y update && apt -y upgrade && apt -y install valgrind # Ubuntu

shell
which valgrind

8.3.3 整合

shell
cmake --version

cmake_minimum_required(VERSION 3.26.5) # 3.26.5

# 项目名称和版本号
project(c-study VERSION 1.0 LANGUAGES C)

# 设置 C 标准
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED True)

# 辅助函数,用于递归查找所有源文件
function(collect_sources result dir)
    file(GLOB_RECURSE new_sources "\${dir}/*.c")
    set(\${result} \${\${result}} \${new_sources} PARENT_SCOPE)
endfunction()

# 查找顶层 include 目录(如果存在)
if (EXISTS "\${CMAKE_SOURCE_DIR}/include")
    include_directories(\${CMAKE_SOURCE_DIR}/include)
endif ()

# 查找所有源文件
set(SOURCES)
collect_sources(SOURCES \${CMAKE_SOURCE_DIR})

# 用于存储已经处理过的可执行文件名,防止重复
set(EXECUTABLE_NAMES)

# 创建可执行文件
foreach (SOURCE \${SOURCES})
    # 获取文件的相对路径
    file(RELATIVE_PATH REL_PATH \${CMAKE_SOURCE_DIR} \${SOURCE})
    # 将路径中的斜杠替换为下划线,生成唯一的可执行文件名
    string(REPLACE "/" "_" EXECUTABLE_NAME \${REL_PATH})
    string(REPLACE "\\\\" "_" EXECUTABLE_NAME \${EXECUTABLE_NAME})
    string(REPLACE "." "_" EXECUTABLE_NAME \${EXECUTABLE_NAME})

    # 处理与 CMakeLists.txt 文件同名的问题
    if (\${EXECUTABLE_NAME} STREQUAL "CMakeLists_txt")
        set(EXECUTABLE_NAME "\${EXECUTABLE_NAME}_exec")
    endif ()

    # 检查是否已经创建过同名的可执行文件
    if (NOT EXECUTABLE_NAME IN_LIST EXECUTABLE_NAMES)
        list(APPEND EXECUTABLE_NAMES \${EXECUTABLE_NAME})

        # 创建可执行文件
        add_executable(\${EXECUTABLE_NAME} \${SOURCE})

        # 查找源文件所在的目录,并添加为包含目录(头文件可能在同一目录下)
        get_filename_component(DIR \${SOURCE} DIRECTORY)
        target_include_directories(\${EXECUTABLE_NAME} PRIVATE \${DIR})

        # 检查并添加子目录中的 include 目录(如果存在)
        if (EXISTS "\${DIR}/include")
            target_include_directories(\${EXECUTABLE_NAME} PRIVATE \${DIR}/include)
        endif ()

        # 检查并添加 module 目录中的所有 C 文件(如果存在)
        if (EXISTS "\${DIR}/module")
            file(GLOB_RECURSE MODULE_SOURCES "\${DIR}/module/*.c")
            target_sources(\${EXECUTABLE_NAME} PRIVATE \${MODULE_SOURCES})
        endif ()
    endif ()
endforeach ()

8.4 性能分析

8.4.1 概述

8.4.2 安装

8.4.2.1 AlmaLinux9

shell
dnf -y install perf

8.4.2.2 Ubuntu 22.04

shell
apt -y update \\
	&& apt -y install linux-tools-common linux-tools-generic linux-tools-$(uname -r)

NOTE

之所以报错的原因,在于 WSL2 中的 Ubuntu 的内核是定制化的,并非 Ubuntu 的母公司 Canonical 发布的标准内核,所以需要我们手动编译安装。

shell
uname -sr

shell
export KERNEL_VERSION=$(uname -r | cut -d'-' -f1)

shell
apt -y update && \\
	apt -y install binutils-dev debuginfod default-jdk default-jre libaio-dev \\
    libbabeltrace-dev libcap-dev libdw-dev libdwarf-dev libelf-dev libiberty-dev \\
    liblzma-dev libnuma-dev libperl-dev libpfm4-dev libslang2-dev libssl-dev \\
    libtraceevent-dev libunwind-dev libzstd-dev libzstd1 python3-setuptools python3 \\
    python3-dev systemtap-sdt-dev zlib1g-dev bc dwarves bison flex libnewt-dev libdwarf++0 \\
    libelf++0 libbfb0-dev python-dev-is-python3

shell
git clone \\
    --depth 1 \\
    --single-branch --branch=linux-msft-wsl-\${KERNEL_VERSION} \\
    https://github.com/microsoft/WSL2-Linux-Kernel.git

shell
cd WSL2-Linux-Kernel
shell
make -j $(nproc) KCONFIG_CONFIG=Microsoft/config-wsl

shell
cd tools/perf
shell
make clean && make

shell
cp perf /usr/bin/

8.4.3 整合

8.5 Win 中文乱码问题

NOTE

8.6 CLion 中自动导入头文件

NOTE

',555),mi=[bi];function Ei(Ci,Fi,yi,_i,vi,Bi){return i(),a("div",null,mi)}const Di=s(gi,[["render",Ei]]);export{Ai as __pageData,Di as default};