import{_ as s,c as a,o as i,a6 as n}from"./chunks/framework.hMCIpNYY.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",y="/c/assets/17.Cd37gMYs.png",F="/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",z="/c/assets/30.picNTNaJ.png",P="/c/assets/31.DKX92RgJ.png",T="/c/assets/32.Bxr7QKI3.png",W="/c/assets/33.DuFWsOgW.png",M="/c/assets/34.Da9qUcfr.png",U="/c/assets/35.7_gEABSX.gif",O="/c/assets/36.C2KQYoVC.gif",I="/c/assets/37.RTUP8Vtx.png",N="/c/assets/38.Dq21DxwL.png",R="/c/assets/39.QmpUaNxU.png",V="/c/assets/40.DP0C29gZ.png",G="/c/assets/41.DwzHokd4.png",X="/c/assets/42.Bi6K26yA.png",$="/c/assets/43.Bw8DcEQ_.png",H="/c/assets/44.DPc8Z9rS.png",K="/c/assets/45.S84xHMTl.png",Q="/c/assets/46.iw3JQUkn.png",Y="/c/assets/47.ILeJt-HK.png",j="/c/assets/48.CHgm7khh.png",J="/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",ys="/c/assets/71.C84EBqwB.png",Fs="/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",zs="/c/assets/84.CXcIKX1T.png",Ps="/c/assets/85.DptbJqQo.png",Ts="/c/assets/86.CQ3_QCQT.png",Ws="/c/assets/87.CQoDRJM5.gif",Ms="/c/assets/88.CPfwZvD9.gif",Us="/c/assets/89.bxEomEjU.gif",Os="/c/assets/90.C_onhf2k.png",Is="/c/assets/91.Budj3s38.gif",Ns="/c/assets/92.CH8koQdu.gif",Rs="/c/assets/93.kUJhxMtg.png",Vs="/c/assets/94.BJeJJW4_.png",Gs="/c/assets/95.BCuK6eJL.gif",Xs="/c/assets/96.rKC-z4z-.gif",$s="/c/assets/97.BJE3xxuT.gif",Hs="/c/assets/98.DJOq__O0.gif",Ks="/c/assets/99.BDt_0fRR.png",Qs="/c/assets/100.Bo5OawW8.png",Ys="/c/assets/101.sUWUfl5e.png",js="/c/assets/102.BK4jpnB8.png",Js="/c/assets/103.EF8vdbSq.png",Zs="/c/assets/104.DjxdA_Co.png",sa="/c/assets/105.sp68q1hh.gif",aa="/c/assets/106.DhMRyxNN.gif",ia="/c/assets/107.CdcLZM0R.gif",na="/c/assets/108.D-5AsTTr.png",la="/c/assets/109.2RQKmAUa.png",ea="/c/assets/110.CI4xX8SM.png",pa="/c/assets/111.C8QUZ9v3.gif",ta="/c/assets/112.g5tQfhWz.gif",ra="/c/assets/113.CX0_1NsE.gif",ca="/c/assets/114.BrFJeoK6.png",ha="/c/assets/115.58TjSSjH.gif",da="/c/assets/116.DmiFIqcy.svg",oa="/c/assets/117.BasYWvkM.png",ka="/c/assets/118.CjFxJpBr.png",ua="/c/assets/119.Dm5Jspvp.gif",ga="/c/assets/120.1krCh8cy.gif",ba="/c/assets/121.DOSyahv7.gif",ma="/c/assets/122.BHEvX_FI.gif",Ea="/c/assets/123.DFA0g1_d.gif",Ca="/c/assets/124.D50nO5eA.gif",ya="/c/assets/125.cAvG1Qfq.png",Fa="/c/assets/126.DpakQFWz.gif",_a="/c/assets/127.Bg61j9QI.gif",va="/c/assets/128.DPvD9UCw.gif",Ba="/c/assets/129.Ceu65U_n.gif",fa="/c/assets/130.BWPFRK_8.gif",Aa="/c/assets/131.Ct4TfxPf.gif",Da="/c/assets/132.zsKtx_jV.png",xa="/c/assets/133.3oqDAW0w.png",qa="/c/assets/134.D9TSeAa9.gif",wa="/c/assets/135.CCRgYIVq.png",Sa="/c/assets/136.C1t2T6FV.gif",La="/c/assets/137.Rqa4uHq6.png",za="/c/assets/138.6yQYnjOa.gif",Pa="/c/assets/139.hYR9GiiD.gif",Ta="/c/assets/140.D3b-QIrA.gif",Wa="/c/assets/141.DGbA6qsW.gif",Ma="/c/assets/142.BToOkxf2.gif",Ua="/c/assets/143.C3wekjfY.png",Oa="/c/assets/144.CKuuzuQ_.png",Ia="/c/assets/145.B4r6Nv14.gif",Na="/c/assets/146.CvbhuZNK.png",Ra="/c/assets/147.BPgYm4ZX.gif",Va="/c/assets/148.DH2fri13.gif",Ga="/c/assets/149.CDDIqy03.gif",Xa="/c/assets/150.DCQsqYYC.gif",$a="/c/assets/151.CUjMoXNF.gif",Ha="/c/assets/152.BWbajkuB.gif",Ka="/c/assets/153.C1JnBDr7.png",Qa="/c/assets/154.DwN2p3bo.png",Ya="/c/assets/155.DdSfz-Pf.gif",ja="/c/assets/156.BMocjVt7.gif",Ja="/c/assets/157.BUU-wlaw.gif",Za="/c/assets/158.ssadIF0D.gif",si="/c/assets/159.Dq5lLq9v.gif",ai="/c/assets/160.CJ0_loZ8.gif",ii="/c/assets/161.BPOK9irZ.gif",ni="/c/assets/162.B1eB55rC.gif",li="/c/assets/163.VIcU-hkN.gif",ei="/c/assets/164.BM9viRZJ.gif",pi="/c/assets/165.DpMBA1SK.gif",ti="/c/assets/166.DgXuU6LF.png",ri="/c/assets/167.Dnw73s2h.gif",ci="/c/assets/168.SnFXRSaL.png",hi="/c/assets/169.DnoEqOjV.png",di="/c/assets/170.BJBdn7pw.png",oi="/c/assets/171.DXtQWYsM.gif",ki="/c/assets/172.hcERTQkN.gif",ui="/c/assets/173.CioraEUv.png",gi="/c/assets/174.kWHWwnc_.png",Di=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":1724291342000}'),bi={name:"notes/01_c-basic/01_xdx/index.md"},mi=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-ucrt-x86_64-toolchain --noconfirm # 安装开发 gcc 相关工具链

NOTE

也许,你会看到其他人的安装命令是 pacman -Sy mingw-w64-x86_64-toolchain --noconfirm,此处解释下两者的区别:

1.2.4.2 配置 path 环境变量

NOTE

本人需要配置的 path 环境变量是 C:\\msys64\\ucrt64\\bin

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

NOTE

1.4 IDE 的安装和配置

1.4.1 CLion

1.4.1.1 概述

NOTE

1.4.1.2 安装

1.4.1.3 配置

NOTE

对于以中文、韩语和日语为母语的开发者,CLion 在 2024.2 之后的版本就绑定了本地化插件,即不需要再安装本地化插件了。

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

1.5 什么是工程/项目 ?

1.5.1 概述

NOTE

需要说明的是,一个真正的软件除了源代码之外,往往还会包括图片、视频、音频、库(框架)等其它资源,这些也是一个个的文件。

NOTE

总结:

1.5.2 工程类型/项目类型

IMPORTANT

第二章: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

NOTE

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

IMPORTANT

第四章:注释(⭐)

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 概述

NOTE

WSL2 的功能,如下所示:

NOTE

WSL2 的用途,如下所示:

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

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