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

第一章:计算机组成原理

1.1 计算机系统

1.2 冯·诺依曼体系结构

IMPORTANT

冯·诺依曼体系结构是现代计算机(量子计算机除外)设计的基础

NOTE

上述的组件协同工作,构成了一个完整的计算机系统:

1.3 各种硬件处理速度和性能优化

img

img

txt
1 秒 = 1000 毫秒,即 1 s = 1000 ms。
1 毫秒 = 1000 微妙,即 1 ms = 1000 us 。
1 微妙 = 1000 纳秒,即 1 us = 1000 ns。
txt
如果 CPU 的时钟周期按照 1 秒计算,
那么,内存访问就需要 6 分钟;
那么,固态硬盘就需要 2-6 天;
那么,传统硬盘就需要 1-12 个月;
那么,网络访问就需要 4 年以上。
txt
鹤寿千岁,以极其游,蜉蝣朝生而暮死,尽其乐,盖其旦暮为期,远不过三日尔。
	                                        --- 出自 西汉淮南王刘安《淮南子》
txt
寄蜉蝣于天地,渺沧海之一粟。 哀吾生之须臾,羡长江之无穷。 
挟飞仙以遨游,抱明月而长终。 知不可乎骤得,托遗响于悲风。
	                                        --- 出自 苏轼《赤壁赋》

NOTE

对于蜉蝣来说,从早到晚就是一生;而对于我们人类而言,却仅仅只是一天。

img

NOTE

上图以层次化的方式,展示了价格信息,揭示了一个真理,即:天下没有免费的午餐(千万不要相信别人会有发财的机会和你共享,人都是自私的,你算个啥?为什么要找你?)

1.4 计算机软件

1.4.1 操作系统的来源

1.4.2 用户态和内核态

类型内核态(Kernel Mode)用户态(User Mode)
权限内核态是操作系统代码运行的模式,拥有访问系统全部资源和执行硬件操作的最高权限。在这种模式下,操作系统的核心部分可以直接访问内存、硬件设备控制、管理文件系统和网络通信等。用户态是普通应用程序运行的模式,具有较低的系统资源访问权限。在用户态,程序不能直接执行硬件操作,必须通过操作系统提供的接口(即系统调用)来请求服务。
安全性由于内核态具有如此高的权限,因此只有可信的、经过严格审查的操作系统核心组件才被允许在此模式下运行。这样可以保护系统不被恶意软件破坏。用户态为系统提供了一层保护,确保用户程序不能直接访问关键的系统资源,防止系统崩溃和数据泄露。
功能内核态提供了系统调用的接口,允许用户态程序安全地请求使用操作系统提供的服务,比如:文件操作、网络通信、内存管理等。用户态保证了操作系统的稳定性和安全性,同时也使得多个程序可以在相互隔离的环境中同时运行,避免相互干扰。

NOTE

java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

public class Demo {
    public static void writeFile(String filePath, String content) {
        Path path = Paths.get(filePath);
        try {
            Files.write(path, content.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args){
        int a = 10;                                 // 用户态
        int b = 20;                                 // 用户态
        int c = a + b;                              // 用户态
        string filePath = "c:/demo.txt";            // 用户态
        string txt = a + b + c;                     // 用户态
        
        writeFile(filePath, a);                     // 从用户态切换到内核态完成文件写入
        
        System.out.println(a);                      // 从内核态切换回用户态
        System.out.println(b);                      // 用户态
        System.out.println(c);                      // 用户态
    }
}

1.4.3 ISA、ABI 和 API

NOTE

NOTE

NOTE

1.4.4 系统调用(System Call)和函数库(Library Call)

类型系统调用(System Call)函数库(Library Call)
定义系统调用是操作系统提供给程序员的一组接口,这些接口允许用户空间的程序请求操作系统内核提供的服务,比如文件操作、进程控制、通信和内存管理等。函数库调用是指使用高级语言编写的一组预先编译好的函数,这些函数实现了一些常用的功能,比如:字符串处理、数学计算等。程序员可以在自己的程序中直接调用这些函数,而无需重新实现它们。
权限执行系统调用时,会从用户态切换到内核态。这是因为系统调用涉及到访问受保护的系统资源,这些操作必须由操作系统控制以确保系统的稳定性和安全性。函数库调用通常在用户态执行,不涉及到用户态与内核态之间的切换。它们直接使用操作系统通过系统调用提供的服务,或者完全在用户空间内完成计算,不需要操作系统介入。
性能开销由于涉及到用户态与内核态之间的切换,系统调用的执行成本相对较高。因此,频繁的系统调用可能会影响程序的性能。相对于系统调用,函数库调用的性能开销较小。因为它们通常不涉及到模式切换,且执行的操作多在用户空间完成。
示例open(),read(),write(),fork(),exec() 等 UNIX/Linux 系统调用。C 标准库中的 printf() 等函数;数学库中的 sin(),cos() 等函数。

NOTE

第二章:初识计算机语言

2.1 计算机语言是什么?

NOTE

计算机语言有很多种,如:C、C++、Java、Go、JavaScript、Python、Scala 等。

2.2 为什么要学习计算机语言?

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

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

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

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

NOTE

编译器就是运行在操作系统之上的程序,其作用就是用来将程序员编写的源代码转换为计算机能够识别的二进制指令。

2.3 计算机语言简史

2.3.1 机器语言(相当于人类的石器时代)

txt
0000,0000,000000010000 代表 LOAD A, 16
0000,0001,000000000001 代表 LOAD B, 1
0001,0001,000000010000 代表 STORE B, 16

IMPORTANT

不同类型(CPU 架构,如:x86_64、arm 等)的处理器有不同的机器语言指令集,指令集架构(ISA)决定了机器语言的具体形式;换言之,机器语言与特定硬件架构紧密相关,机器语言程序几乎没有可移植性。

2.3.2 汇编语言(相当于人类的青铜&铁器时代)

NOTE

汇编语言,目前仍然应用于工业电子编程领域、软件的加密解密、计算机病毒分析等。

2.3.3 高级语言(相当于人类的信息时代)

NOTE

普遍使用的高级编程语言,有:C、C++、Java、Python、C#、JavaScript、Go、SQL 等。

2.3.4 总结

类别特征优点缺点示例
机器语言直接由计算机执行的二进制代码执行速度快编写困难,可读性差,与具体硬件强绑定二进制代码
汇编语言用助记符代替二进制代码的低级语言相对机器语言更易编写和理解,允许直接控制硬件资源依然需要了解硬件,不够抽象,与具体硬件或平台相关MOV,ADD 等助记符
高级语言接近人类语言,提供了更高层次的抽象易于编写和维护,可移植性好,支持多种编程范式需要通过编译器或解释器转换为机器语言,可能存在一定的性能损失C,Java, Python 等

NOTE

第三章:初识 C 语言

3.1 C 语言的由来

NOTE

C 语言最初是作为 Unix 系统的开发工具而发明的。

3.2 为什么要学习 C 语言?

NOTE

C 语言的最原始的设计目的,就是为了将 Unix 操作系统移植到其他的计算机架构上,这使得它从一开始就非常注重可移植性。

3.3 计算机语言排行榜

3.4 C 语言的版本选择

IMPORTANT

GCC 编译套件对标准的支持是最好的;所以,在实际项目开发中,我们首先会选用 GCC 编译套件来进行开发。

3.5 C 语言的优缺点

第四章:C 语言入门(Hello World,⭐)

4.1 环境的安装和配置

4.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

4.1.2 MinGW-w64 的安装和配置

4.1.2.1 安装

NOTE

下载地址在这里

NOTE

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

4.1.2.2 配置 path 环境变量

NOTE

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

shell
gcc --version

4.1.3 Cygwin 的安装和配置

4.1.3.1 安装

NOTE

下载地址在这里

NOTE

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

4.1.3.2 配置 path 环境变量

4.1.4 MSYS2(推荐)

4.1.4.1 安装

NOTE

下载地址在这里

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 相关工具链

4.1.4.2 配置 path 环境变量

4.2 IDE 的安装和配置

4.2.1 CLion

4.2.1.1 概述

4.2.1.2 安装

4.2.1.3 配置

4.2.2 VS Code

4.2.2.1 概述

NOTE

Visual Studio Code 需要安装对应的插件,才能运行 C/C++ 代码。

4.2.2.2 安装

4.2.2.3 配置

4.2.3 Microsoft Visual Studio

4.2.3.1 概述

4.2.3.2 安装

4.2.3.3 配置

NOTE

4.3 HelloWorld

4.3.1 手动版

c
#include <stdio.h>

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

shell
gcc HelloWorld.c -o HelloWorld.exe

shell
./HelloWorld.exe

4.3.2 VS Code 版

c
#include <stdio.h>

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

shell
gcc HelloWorld.c -o HelloWorld.exe

shell
./HelloWorld.exe

4.3.3 VS 版

c
#include <stdio.h>

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

4.3.4 CLion

c
#include <stdio.h>

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

NOTE

内容如下所示:

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

第五章:注释

5.1 概述

NOTE

5.2 单行注释

c
// 单行注释

NOTE

在 CLion 中的快捷键是 Ctrl + /

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

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

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

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

5.3 多行注释

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

NOTE

c
#include <stdio.h> 

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

    return 0;  
}

第六章:HelloWorld 的规范(⭐)

6.1 规范的代码风格

6.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;
}

6.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;                   
}

6.2 代码细节剖析

6.2.1 main() 函数

c
int main(){
    return 0;
}

NOTE

6.2.2 函数体

6.2.3 printf() 函数

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

6.2.4 标准库和头文件

6.2.4.1 概述

c
#include <stdio.h>

6.2.4.2 标准库(Standard Library)

NOTE

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

6.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

6.2.4.4 预处理命令

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

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

7.1 安装和配置 WSL2

7.1.1 概述

7.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

7.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

7.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 会不支持,那么就需要手动下载源码,自行编译,本次不再演示!!!

7.2 切换 CLion 中的 cmake 的工具链

7.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 ()

7.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

7.5 配置 .gitignore 文件

txt
.vscode
.idea
cmake-build-*
build

7.6 演示

NOTE

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

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

8.1 概述

IMPORTANT

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

IMPORTANT

IMPORTANT

IMPORTANT

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

8.2 GCC 编译器的介绍

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

shell
gcc HelloWorld.c -o HelloWorld.exe

8.4 通过 gcc 分步编译

8.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 结尾

8.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

第九章:附录

9.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

9.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;
}

9.3 内存泄露检测

9.3.1 概述

NOTE

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

9.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

9.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 ()

9.4 性能分析

9.4.1 概述

9.4.2 安装

9.4.2.1 AlmaLinux9

shell
dnf -y install perf

9.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/

9.4.3 整合

9.5 Win 中文乱码问题

NOTE

',643),Wi=[Ii];function Oi(Ni,Ri,Mi,Xi,Gi,Vi){return i(),a("div",null,Wi)}const Ki=s(Ui,[["render",Oi]]);export{Hi as __pageData,Ki as default};