【C语言】基础概念梳理(一)

文章目录

  • 前言
  • 我眼中的C语言
  • 一、开发环境
    • [1. 代码编辑工具](#1. 代码编辑工具)
    • [2. 代码编译器](#2. 代码编译器)
  • 二、C语言的运行流程机制
  • 三、变量
    • [1. 三要素](#1. 三要素)
    • [2. 标识符规范](#2. 标识符规范)
  • 四、常量
    • [1. 常量分类](#1. 常量分类)
    • [2. 如何定义标识符常量](#2. 如何定义标识符常量)
  • 五、二进制
    • [1. 进制转换](#1. 进制转换)
    • [2. 源码,反码,补码](#2. 源码,反码,补码)
  • 六、数据类型
    • [1. 基本类型](#1. 基本类型)
    • [2. 数据类型转换](#2. 数据类型转换)
  • 七、运算符
    • [1. 分类](#1. 分类)
    • [2. 运算符汇总](#2. 运算符汇总)
    • [3. 运算符优先级](#3. 运算符优先级)
  • 八、流程控制语句
    • [1. 分支控制语句](#1. 分支控制语句)
    • [2. 循环控制语句](#2. 循环控制语句)
    • [3. 跳转控制语句](#3. 跳转控制语句)

前言

工作后过度侧重实践,忽视了理论学习,导致难以理解核心代码。

如今重新学习C语言,结合工作经验总结了一些心得体会。

水平有限,如有不足,欢迎指正!


我眼中的C语言

C语言项目的编写类似于古代皇朝的治理。你就是皇帝,内存是国库,存储是皇库,外设是你的州府百官。一个项目的好坏,取决于你对这个国家的治理能力如何。

CPU相当于是你的丞相,编写代码的过程就是你书写圣旨的过程,丞相无论能力强弱,都要按照圣旨执行,所以圣旨的编写尤为重要。圣旨编写的是否既简洁又明确,是检验一个皇帝治理水平的核心标准。

一、开发环境

1. 代码编辑工具

向我们日常使用的windows记事本,稍微功能多一点儿的vs code,Notepad++等,再高级一点集成开发环境(IDE),如qt,keil,DEV- C++等,是编辑器+编译器+调试器的一站式开发工具,包含编辑器的核心功能,还能直接编译运行代码。

由此可见,只要能编写,修改文本的软件都可称为代码编辑工具

2. 代码编译器

如GCC,Min GW,MSVC,Clang等都属于编译器。本质上是将程序员写的高级语言翻译成计算机能识别的机器语言。

以GCC为例编译代码分为4个阶段:

  1. 预处理阶段:gcc -E test.c -o test.i。展开宏、处理头文件、删除注释

  2. 编译阶段:gcc -S test.i -o test.s。核心阶段将C语言转成汇编。高级语言-》低级语言的核心阶段。

  3. 汇编阶段:gcc -c test.s -o test.o。把汇编语言代码(.s)转换成机器语言指令(二进制文件)。

  4. 链接阶段:gcc test.o -o test.exe 。把目标文件(.o)和系统库(如printf所在的libc库)链接起来,生成可执行文件(Windows 下.exe,Linux 下无后缀)。

二、C语言的运行流程机制

生成可执行文件后,我们点击执行,操作系统会做三件事。分别是:

  1. 分配内存:为程序开辟独立的内存空间(栈、堆、全局 / 静态区、代码区);
  2. 加载指令:把可执行文件中的机器码指令加载到内存的 "代码区";
  3. 定位入口:找到程序的入口点(main函数的起始地址),准备执行。

这里补充一下C语言4大区

内存区域 存储内容 特点
栈区 局部变量、函数参数、函数返回地址、临时变量 编译器自动分配释放;后进先出;速度快;空间小(易溢出);生命周期随函数作用域结束而结束
堆区 动态分配的数据(如malloc/calloc申请的内存) 程序员手动申请释放;速度较慢;空间大;需自行管理(易内存泄漏或悬空指针)
全局区(静态区) 全局变量、static修饰的变量(含局部静态变量) 程序编译时分配,运行结束释放;生命周期贯穿整个程序;未初始化变量自动清零(BSS段)
代码区(常量区) 编译后的机器指令、字符串字面量、const修饰的全局常量 只读存储;程序运行期间存在;试图修改会触发段错误

流程图如下:

编写源代码

预处理\] → 处理宏、头文件 ↓ \[编译\] → 生成汇编代码 ↓ \[汇编\] → 生成目标文件(机器码) ↓ \[链接\] → 合并目标文件 + 库 → 可执行文件 ↓ \[加载\](OS负责)→ 分配内存(代码区/全局区/栈/堆) ↓ \[执行\] → CPU取指执行 ├── 函数调用 → 创建栈帧 ├── malloc → 从堆申请内存 └── 变量访问 → 根据所在区进行读写 ↓ \[退出\] → 释放资源,终止进程 对于嵌入式来说实际硬件中存储的位置: | 存储介质 | 中文名称 | 核心特点 | 对应软件逻辑 | |-----------|-------------|----------------------|-------------------------| | RAM | 随机存取存储器(内存) | 可读可写、掉电丢失、速度快 | 栈、堆、全局 / 静态区(运行时) | | Flash/ROM | 闪存 / 只读存储器 | 只读(或需特殊操作写)、掉电不丢、速度慢 | 存储程序代码、全局 / 静态 / 常量的初始值 | ## 三、变量 ### 1. 三要素 **1.1 类型:** C语言中的类型分类: 基本类型:int(4字节)、char(1字节)、float(4字节)、double(8字节) 修饰类型:short(2字节)、long(4/8字节)、unsigned、signed 构造类型:数组、结构体、联合体、枚举 指针类型:指向其他类型的变量 空类型:void 解释:创建变量时首要考虑的就是类型,本质上是开辟不同大小的内存空间。但由于芯片的内存和数据链的负载能力有限,实际工作过程中,**我们要尽可能的完美利用我们申请空间中的每一个0和1。** **1.2 变量名:** 解释:变量名就是用来标记一处内存位置。变量名一定要起的规范好理解,一个好的变量名既能方便我们理解代码,也能方便我们后续的使用。 **1.2 值:** 值存放在变量对应的内存单元中,可以随时改变(除非用 const 修饰)。 变量的值在未初始化时是垃圾值(即之前该内存遗留的二进制内容),直接使用会导致未定义行为。 赋值操作就是将新的数据写入内存单元。 解释:值是变量当前存储的具体数据,它必须与变量的类型相匹配。实际工作中,我们一定要认真管理好代码中所有变量的初始值,防止出现开机上电屏幕上出现一堆随机值。 ### 2. 标识符规范 | 规则 | 说明 | |--------|------------------------------------------| | 组成字符 | 只能由字母(a-z, A-Z)、数字(0-9)和下划线(_)组成。 | | 首字符 | 不能以数字开头。 | | 区分大小写 | sum、Sum、SUM 是三个不同的标识符。 | | 不能是关键字 | 不能使用 C 语言的关键字(如 int、if、while 等)作为标识符。 | | 长度限制 | 理论上无限制,但编译器通常只识别前若干字符(如 31/63 个),建议不要太长。 | 解释:变量名属于标识符(Identifier)的一种。标识符还包括函数名、结构体名、宏名等。实际工作中,标识符的命名可以参考Linux内核代码中的驼峰式命名法,清晰易理解,方便后期维护拓展项目。 // 规范的标识符 int firstNumber; // 驼峰命名 float my_var; // 下划线命名 char className; // 避免与关键字冲突 const int MAX_STUDENTS = 100; // 宏常量全大写 ## 四、常量 **概念:** 常量是固定值,在程序执行期间不能修改。项目中常用于当作全局设置指令等。 为何要引入常量这一概念? 1. 提高可读性:用有意义的名称代替魔法数字 2. 便于维护:修改一处即可影响所有使用处 3. 增强安全性:防止意外修改 实际工作中,常量往往被用来标记一些常用的固定值,如:3.1415926,特定三角函数值,最大值最小值等等。 ### 1. 常量分类 **1.1 字面常量** 字面量常量是直接写在代码中的具体值,无需额外定义。 | 类型 | 示例 | 说明 | |--------------|------------------------------------------------|-----------------------------------------------------| | 整型字面量 | 123、-456、0xFF(十六进制)、075(八进制)、0b1010(二进制,C23 起) | 默认 int,后缀 L/l 表示 long,LL 表示 long long,U 表示 unsigned | | 浮点型字面量 | 3.14、2.0e-5、.5、1. | 默认 double,后缀 f/F 表示 float,l/L 表示 long double | | 字符型字面量 | 'A'、'\\n'、'\\x41' | 单引号括起,类型为 int,可含转义序列 | | 字符串字面量 | "Hello"、"Line1\\nLine2" | 双引号括起,类型为 char \[\](只读存储),末尾自动添加 \\0 | | 布尔字面量(C99 起) | true、false | 需包含 \,类型为 bool | ### 2. 如何定义标识符常量 标识符常量是给常量值起一个名字,通过标识符来使用。在C语言中,主要通过两种方式定义:#define宏定义和const关键字。此外,枚举常量也属于标识符常量。 **本质就是 "有名字的常量",核心是名字固定、值也固定,程序运行中不能修改。** ```c #include #include // 1. 标识符常量:用#define定义(宏定义) #define PI 3.14 // 2. 标识符常量:用const定义 const int MAX_SCORE = 100; // 3. 标识符常量:枚举常量 enum Season { SPRING = 1, SUMMER, AUTUMN, WINTER }; int main() { // ========== 字面常量(直接用原始值) ========== // 这里的 5、3.14、'A'、"Hello" 都是字面常量 float area1 = 3.14 * 5 * 5; // 3.14、5 是字面常量 char ch = 'A'; // 'A' 是字面常量 printf("Hello\n"); // "Hello" 是字面常量 // ========== 标识符常量(用"名字"代替原始值) ========== float area2 = PI * 5 * 5; // PI 是标识符常量(代替3.14) int score = MAX_SCORE; // MAX_SCORE 是标识符常量(代替100) int season = SUMMER; // SUMMER 是标识符常量(代替2) // 打印对比 printf("字面常量计算面积:%.2f\n", area1); printf("标识符常量计算面积:%.2f\n", area2); printf("最高分(标识符常量):%d\n", MAX_SCORE); printf("夏季(枚举常量):%d\n", SUMMER); return 0; } ``` ## 五、二进制 计算机内部采用二进制(Binary)表示数据,因为电路只有"开/关"两种状态(0/1),稳定可靠。 位(bit):最小的数据单位,值为0或1。 字节(byte):8个bit,是计算机基本存储单位。 其他常用进制: 八进制(Octal):基数为8,用0\~7表示,C语言中以 0 开头(如 075)。 十六进制(Hexadecimal):基数为16,用0-9、A- F(或a-f)表示,C语言中以 0x 或 0X 开头(如 0x2F)。 ### 1. 进制转换 进制转换规则(二进制 ↔ 十进制/八进制/十六进制) 1. 二进制 ↔ 十进制 (1) 二进制转十进制(按权展开):每一位×2\^对应幂次,求和 * 例:1101.101 → 整数部分1×2³+1×2²+0×2¹+1×2⁰=13,小数部分1×2⁻¹+0×2⁻²+1×2⁻³=0.625 → 13.625 (2) 十进制转二进制:整数除2取余(逆序),小数乘2取整(顺序) * 例:13→1101,0.625→101 → 1101.101 2. 二进制 ↔ 八进制/十六进制 8=2³ → 3位一组;16=2⁴ → 4位一组,不足补0后转换 (1) 二进制→八进制:1011011.011 → 001 011 011.011 → 133.3 (2) 二进制→十六进制:1011011.011 → 0101 1011.0110 → 0x5B.6 (3) 反向转换:八进制每位扩3位二进制,十六进制每位扩4位二进制 ### 2. 源码,反码,补码 计算机中有符号整数的表示需要区分正负,为了区分正负,所以引入了源码反码补码这一概念。现代计算机普遍使用**补码**。 **1. 原码(Sign-Magnitude)** **定义** 最高位为符号位(0 表示正数,1 表示负数),其余位表示数值的绝对值。 **表示范围(n 位)** \[ − ( 2 n − 1 − 1 ) , + ( 2 n − 1 − 1 ) \] \\left\[-(2\^{n-1} - 1), +(2\^{n-1} - 1)\\right\] \[−(2n−1−1),+(2n−1−1)

存在"+0"和"-0"两个零,浪费编码空间。

示例(8 位)

数值 原码
+5 0000 0101
-5 1000 0101
+0 0000 0000
-0 1000 0000

缺点

  • 加减法运算复杂,需先判断符号位再决定运算类型;
  • 两个零的存在浪费了一个编码组合。

2. 反码(Ones' Complement)
定义

  • 正数的反码与原码相同;
  • 负数的反码是对应正数原码的所有位取反(符号位也取反)。

表示范围(n 位)

同原码: [ − ( 2 n − 1 − 1 ) , + ( 2 n − 1 − 1 ) ] \left[-(2^{n-1} - 1), +(2^{n-1} - 1)\right] [−(2n−1−1),+(2n−1−1)]

依然存在"+0"和"-0"两个零。

示例(8 位)

数值 反码 说明
+5 0000 0101 与原码相同
-5 1111 1010 对 +5 的原码(0000 0101)所有位取反
+0 0000 0000 与原码相同
-0 1111 1111 对 +0 的原码所有位取反

缺点

  • 仍存在两个零,浪费编码;
  • 加法运算需处理"循环进位"(端回进位),硬件实现复杂。

3. 补码(Two's Complement)
定义

  • 正数的补码与原码相同;
  • 负数的补码是其反码加 1(忽略溢出)。

表示范围(n 位)

− 2 n − 1 , + ( 2 n − 1 − 1 ) \] \\left\[-2\^{n-1}, +(2\^{n-1} - 1)\\right\] \[−2n−1,+(2n−1−1)

只有一个零,相比原码/反码多表示一个最小负数。

示例(8 位)

数值 补码 说明
+5 0000 0101 与原码/反码相同
-5 1111 1011 -5 的反码(1111 1010)加 1
+0 0000 0000 取反加 1 后仍为 0(唯一零)
-128 1000 0000 无对应正数 128,8 位补码范围:-128 ~ 127

优点

  1. 唯一零:避免编码浪费,仅 0000 0000 表示零;
  2. 加减法统一:无需判断符号位,直接进行二进制加法,溢出自动丢弃进位;
  3. 硬件实现简单:CPU 的 ALU(算术逻辑单元)只需加法器即可完成加减法运算。

补码的快速计算方法

  1. 给定负数 − x -x −x,其 n 位补码 = 2 n − x 2^n - x 2n−x(忽略溢出);

  2. 从原码转补码(负数):符号位不变,数值位取反后加 1(符号位参与运算)。

六、数据类型

在C语言中,数据类型是变量和表达式的本质属性,它直接决定了内存占用空间、数值取值范围以及可执行的操作类型。当我们定义不同数据类型的变量时,实际上就是在为这些变量分配相应大小的内存空间。

工作实践中,数据类型就是我们用C语言量化现实 的最小单元。
数据类型的主要功能:

  • 内存分配:明确变量所需的内存空间大小(以字节为单位)
  • 取值范围:限定变量能够存储的数值范围(最小值和最大值)
  • 操作权限:规定允许执行的操作类型(例如整型支持位运算,而浮点型则不支持)

C语言数据类型的分类体系:

  1. 基本数据类型:

    • 整型(int)
    • 浮点型(float/double)
    • 字符型(char)
    • 布尔型(bool)
  2. 构造数据类型:

    • 数组
    • 结构体(struct)
    • 联合体(union)
    • 枚举(enum)
  3. 指针类型

  4. 特殊类型:

    • 空类型(void)

1. 基本类型

1.1 整形

整型用于存储整数,分为有符号(signed,默认)和无符号(unsigned)。常用整型有:

类型 常见大小(字节) 取值范围(有符号) 取值范围(无符号)
short 2 -32,768 ~ 32,767 0 ~ 65,535
int 4 -2,147,483,648 ~ 2,147,483,647 0 ~ 4,294,967,295
long 4 或 8(取决于平台) 至少 -2³¹ ~ 2³¹-1 至少 0 ~ 2³²-1
long long 8 -9.2×10¹⁸ ~ 9.2×10¹⁸ 0 ~ 1.8×10¹⁹

1.2 浮点型

浮点类型常用于存储带小数的实数。C语言提供了三种浮点类型:

类型 常见大小(字节) 精度(有效十进制位数) 取值范围(约)
float 4 6~7 位 ±1.2×10⁻³⁸ ~ ±3.4×10³⁸
double 8 15~16 位 ±2.2×10⁻³⁰⁸ ~ ±1.8×10³⁰⁸
long double 8/10/16(平台相关) 更高精度 更大范围

1.3字符类型
char 类型用于存储单个字符,其本质是在内存中以整数形式存储字符对应的 ASCII 码(或扩展编码)值。

特性:

  • 固定大小:1 字节
  • 取值范围:
    • signed char:-128 ~ 127
    • unsigned char:0 ~ 255
  • 默认是否有符号由编译器决定,可通过 signed/unsigned 关键字显式指定

字符表示:

  • 字面量:用单引号包裹,如 'A''\n'
  • 转义序列:
    • \n 换行符
    • \t 制表符
    • \\ 反斜杠
    • \x41 十六进制 ASCII 值表示
c 复制代码
char ch = 'A';
char newline = '\n';

1.4 布尔类型

就是0和1。C99 之前没有专门的布尔类型,通常用 int 模拟(0 表示假,非 0 表示真)。C99 引入了 _Bool,并提供 <stdbool.h> 头文件简化使用。

三种定义布尔类型的方式:

(1) 使用 int 类型模拟(传统方法)

c 复制代码
int flag = 0;  // 表示假
int done = 1;  // 表示真
if (done) { ... }

缺点:类型语义不明确,代码可读性较差。

(2) 使用 _Bool 类型(C99 标准引入)

c 复制代码
_Bool flag = 0;   // 0 表示假
_Bool done = 1;   // 1 表示真

说明:_Bool 是无符号整型,仅能存储 0 或 1。任何非零值赋给 _Bool 变量都会转换为 1。

不足:语法略显生硬,可读性一般。

(3) 使用 <stdbool.h> 标准库(C99 标准引入)

c 复制代码
#include <stdbool.h>
bool flag = false;   // bool 是 _Bool 的别名
bool done = true;    // true/false 是预定义宏,分别展开为 1/0

推荐:使用 bool 类型名配合 true/false 值,代码意图清晰明了。

2. 数据类型转换

在C语言中,不同类型的数据进行运算时会自动发生数据类型转换。转换方式分为自动转换和强制转换两种。

2.1 自动类型转换

由编译器自动完成,主要发生在以下两种情况:

(1) 运算过程中的类型转换

  • 整型提升:在表达式中,所有小于int的整型(如char、short、_Bool)都会先提升为int(或unsigned int)后再参与运算。
c 复制代码
char c1 = 100, c2 = 200;
int sum = c1 + c2;  // c1和c2先提升为int类型,再进行相加
  • 寻常算术转换 :当操作数类型不同时,编译器会将类型统一转换为精度更高的类型。转换规则按以下优先级进行:

    复制代码
    long double > double > float > unsigned long long > long long > 
    unsigned long > long > unsigned int > int
c 复制代码
int i = 10;
float f = 3.14f;
double d = i + f;  // i先转换为float,运算结果再转换为double

(2) 赋值过程中的类型转换

将右侧表达式的值赋给左侧变量时,会自动转换为左侧变量的类型。

  • 高精度转低精度:可能发生数据截断或舍入
c 复制代码
double pi = 3.1415926;
int i = pi;  // i值为3,小数部分丢失
  • 大范围转小范围:若值超出目标类型范围,会发生溢出
c 复制代码
unsigned char uc = 300;  // 300%256=44
signed char sc = 130;    // 结果未定义(通常为-126)

2.1 强制转换

程序员显式指定将某个表达式的类型转换为另一种类型。语法为:

c 复制代码
(类型名) 表达式

int a = 5, b = 2;
float result = (float)a / b;   // 先将 a 转换为 float,再与 b 相除,结果为 2.5

注意事项:

  1. 数据丢失风险:强制转换可能导致数据截断或精度损失
  2. 指针转换隐患:不同类型指针间的强制转换可能引发未定义行为(如内存对齐问题或类型双关)
  3. 谨慎使用:过度依赖强制转换会屏蔽编译器警告,潜在掩盖逻辑错误

七、运算符

运算符就是对数据进行运算的符号。

1. 分类

一元运算符:作用于单个操作数,例如负号运算(-a)、自增(++i)和逻辑非(!flag)。

二元运算符:需要两个操作数参与运算,如加法(a + b)和比较运算(x > y)。

三元运算符:涉及三个操作数的运算,在C语言中仅条件运算符(?:)属于此类。

2. 运算符汇总

类别 运算符 说明
算术运算符 + - * / % ++ -- 基本数学运算、自增自减
关系运算符 > < >= <= == != 比较大小,返回真(1)/假(0)
逻辑运算符 && || ! 逻辑与、或、非
位运算符 & | ^ ~ << >> 按位与、或、异或、取反、左移、右移
赋值运算符 = += -= *= /= %= &= |= ^= <<= >>= 赋值及复合赋值
条件运算符 ? : 三元条件表达式
其他 sizeof & * , () [] . -> 长度运算符、取地址、间接引用、逗号、函数调用、下标、结构体成员等

3. 运算符优先级

运算符优先级决定了表达式中运算的执行顺序,而结合性则规定了同一优先级运算符的计算方向。

运算符优先级表

优先级 运算符 结合性
1(最高) () [] . -> ++(后缀) --(后缀) 从左到右
2 ++(前缀) --(前缀) +(一元) -(一元) ! ~ *(解引用) &(取址) (类型) sizeof 从右到左
3 * / % 从左到右
4 + - 从左到右
5 << >> 从左到右
6 < > <= >= 从左到右
7 == != 从左到右
8 &(按位与) 从左到右
9 ^ 从左到右
10 ` `
11 && 从左到右
12 `
13 ?: 从右到左
14(最低) = += -= 等赋值运算符 从右到左
15 , 从左到右

记忆口诀

括号优先级最高,运算顺序依次为:单目 > 算术 > 移位 > 关系 > 按位 > 逻辑 > 条件 > 赋值 > 逗号。

八、流程控制语句

我们生活中的所有事件逻辑都可以用三大流程表示,分别是分支、循环、跳转。这三大流程就是C语言中的流程控制语句,流程控制语句决定了程序的执行路径。

1. 分支控制语句

1.1 if 语句

c 复制代码
if (条件) {
    // 条件为真时执行的代码
}

1.2 if-else 语句

c 复制代码
if (条件) {
    // 条件为真时执行的代码
} else {
    // 条件为假时执行的代码
}
  • 可通过 else if 实现多分支条件判断
  • 注意:单条语句可省略大括号,但建议保留以提高代码可读性

1.3 switch-case 语句

c 复制代码
switch (表达式) {
    case 常量1:
        // 表达式等于常量1时执行的代码
        break;
    case 常量2:
        // 表达式等于常量2时执行的代码
        break;
    default:
        // 无匹配时执行的代码
}
  • 表达式必须为整型(包括 char 和枚举类型)
  • case 标签必须是整型常量表达式(不能使用变量或范围)
  • 通常每个 case 后需加 break 语句,否则会继续执行后续 case(穿透效应)
  • default 分支可选,可放置在任意位置。

2. 循环控制语句

  1. while 循环
c 复制代码
while (条件) {
    // 条件成立时重复执行
}

先判断条件后执行,可能完全不执行。

  1. do-while 循环
c 复制代码
do {
    // 循环体至少执行一次
} while (条件);

先执行一次循环体,再判断条件,保证至少执行一次。

  1. for 循环
c 复制代码
for (初始化; 条件; 更新) {
    // 循环体
}

执行流程:初始化 → 条件判断 → 循环体 → 更新 → 再次条件判断...

注意事项:

  • 三个表达式都可省略,但必须保留分号
  • for(;;) 表示无限循环
  • 从 C99 开始,可在初始化部分定义变量,其作用域仅限于循环内部。

3. 跳转控制语句

  1. break

    用于跳出当前所在的 switch 语句或最内层的 whiledo-whilefor 循环。
    仅影响当前循环层,外层循环不受干扰

  2. continue

    用于循环结构中,跳过本次循环剩余的语句,直接进入下一次迭代

    • while/do-while 中:跳转至条件判断部分
    • for 循环中:跳转至更新表达式部分
  3. goto

    无条件跳转到函数内的指定标签位置。语法:

    c 复制代码
    goto label;
    ...
    label:

    需谨慎使用,可能降低代码可读性,但在处理多层循环跳出或错误处理时仍具实用价值。

  4. return

    终止当前函数执行并返回调用者:

    • 若函数有返回值,必须跟随返回表达式
    • 若返回类型为 void,可简写为 return;1

相关推荐
左左右右左右摇晃2 小时前
Java并发——死锁
java·开发语言·spring
沫离痕2 小时前
AI机器人客服-Dify接入
开发语言·javascript·ecmascript
半瓶榴莲奶^_^2 小时前
java模式
java·开发语言
sword devil9002 小时前
TRAE:agent团队
开发语言
co_wait2 小时前
【c 语言】linux下gcc编译工具的使用
linux·c语言·开发语言
2301_815482932 小时前
C++编译期矩阵运算
开发语言·c++·算法
always_TT2 小时前
结构体数组与初始化
c语言
☆5662 小时前
C++中的类型擦除技术
开发语言·c++·算法
m0_569881472 小时前
C++与自动驾驶系统
开发语言·c++·算法