cpp基础入门~~c语言的补足

个人主页:strive_debug

Bjarne Stroustrup与C++的诞生

C++之父的背景与动机

Bjarne Stroustrup(本贾尼·斯特劳斯特卢普)在开发C++时的核心驱动力源于他对当时主流编程语言(特别是C语言)局限性的深刻认识:

Stroustrup观察到的三大不足:

  1. 表达能力的局限

    • C语言缺乏高级抽象机制(如类、模板)
    • "Simula-like"特性需求日益增长但无法实现
  2. 可维护性挑战

    • C程序规模增大时代码组织困难
    • UNIX内核开发经验暴露了模块化不足的问题
  3. 可扩展性瓶颈

    • ADT(抽象数据类型)实现笨拙且低效
    • Bell实验室网络交换机项目需要更强大的类型系统

发展史:

C++参考⽂档:

https://legacy.cplusplus.com/reference/
https://zh.cppreference.com/w/cpp
http://https://en.cppreference.com/w/

C++学习资源与第一个程序指南

C++学习文档资源对比

📚三大主流参考文档

> 💡 **建议策略**:初学者从cplusplus.com入门 → cppreference查阅细节 → StackOverflow解决具体问题

C++第一个程序实现

C与C++的兼容性说明

  1. **语法兼容性**
  • C++兼容C语言99%语法特性(除VLA等少数特性)

  • C语言程序可直接保存为`.cpp`文件编译运行

  1. **编译工具差异**
  • Windows (VS):`.c`文件 → C编译器 / `.cpp` → C++编译器

  • Linux:需明确使用`gcc`(C)或`g++`(C++)命令

> 🌟 **最佳实践建议**:即使是简单测试程序也建议使用`.cpp`扩展名和C++标准写法(如cout/cin),以培养规范的C++编码习惯

cpp 复制代码
// test.cpp
#include<stdio.h>
int main()
{
printf("hello world\n");
return 0;
}

当然C++有⼀套⾃⼰的输⼊输出,严格说C++版本的hello world应该是这样写的。

cpp 复制代码
// test.cpp
#include<iostream>
using namespace std;
int main()
{
cout << "hello world\n" << endl;
return 0;
}

C++命名空间详解

namespace的核心价值

在C/C++开发中面临的核心问题:

  1. **全局作用域污染**:变量、函数、类名都存在于全局作用域

  2. **命名冲突风险**:大型项目中名称冲突概率极高

namespace的设计初衷正是为了解决这些问题。

namespace的本质特性

  1. **作用域隔离机制**
cpp 复制代码
namespace A {
    int x = 10; // A域中的x
}

int x = 20;     // 全局域中的x
  1. **可包含内容**
  • ✅变量、✅函数、✅类型(类/结构体)、✅嵌套命名空间
  1. **作用域类型对比**

namespace的关键特性

  1. **只能定义在全局**
cpp 复制代码
// ✅正确 - 全局定义
namespace N1 { /*...*/ }

void func() {
    // ❌错误 -不能在函数内定义namespace 
    // namespace N2 { /*...*/ }
}
  1. **支持嵌套定义**
cpp 复制代码
//2. 命名空间可以嵌套
namespace uint
{
   namespace king
  {
   int rand = 1;
   int Add(int left, int right)
    {
     return left + right;
    }
  }
   namespace qun
  {
   int rand = 2;
   int Add(int left, int right)
   {
     return (left + right)*10;
   }
  }
}
int main()
{
printf("%d\n", unit::king::rand);
printf("%d\n", unit::qun::rand);
printf("%d\n", unit::king::Add(1, 2));
printf("%d\n", unit::qun::Add(1, 2));
return 0;
}
  1. **多文件共享特性**
cpp 复制代码
// file1.h
namespace MyLib {
    void init();
}

// file2.cpp 
namespace MyLib {
    void init() { /*实现*/ }
}
//int main 函数调用的时候MyLib::写使用的函数,他会去自己寻找MyLib中的对应函数
//这两个MyLib的函数是不一样的,一样的就多余了,体现的是不一样的函数作用
//多⽂件中可以定义同名namespace,他们会默认合并到⼀起,就像同⼀个namespace⼀样

下面的我还没理解到,等理解到我会为大家插入链接:

namespace的实际应用场景

  1. **第三方库隔离**
cpp 复制代码
namespace boost { /*...*/ }
namespace Qt { /*...*/ }
  1. **模块化开发**
cpp 复制代码
namespace NetworkModule {
    class Socket;
    void connect();
}

namespace DatabaseModule {
    class Connection;
    void query();
}
  1. **版本控制**
cpp 复制代码
namespace MyLib_v1 { /*旧版接口*/ }
namespace MyLib_v2 { /*新版接口*/ }
namespace的特殊用法

匿名命名空间

cpp 复制代码
namespace {
    //仅在当前文件可见(类似static)
    int internalVar = 42; 
}

别名定义

cpp 复制代码
namespace very_long_namespace_name {
    /*...*/
}

namespace vl = very_long_namespace_name; //创建别名

最佳实践建议:在大型项目中优先使用命名空间组织代码结构,避免将非必要内容暴露到全局作用域

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
// 1. 正常的命名空间定义
// king是命名空间的名字,⼀般开发中是⽤项⽬名字做命名空间名。
namespace king
{
// 命名空间中可以定义变量/函数/类型
int rand = 10;
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
int main()
{
// 这⾥默认是访问的是全局的rand函数指针
printf("%p\n", rand);
// 这⾥指定king命名空间中的rand
printf("%d\n", king::rand);
return 0;
}

C++命名空间使用指南

命名空间的基本概念

当编译器查找变量/函数的声明或定义时:

  • 默认查找范围:局部作用域 → 全局作用域

  • 不会自动查找:命名空间内的定义

三种访问命名空间成员的方式

  1. 指定命名空间访问(项目推荐)
cpp 复制代码
std::cout << "Hello World" << std::endl;

**优点**:

  • 明确标识来源命名空间

  • 避免命名冲突风险

  1. using声明引入特定成员(推荐常用无冲突成员)
cpp 复制代码
using std::cout;
using std::endl;

cout << "Hello World" << endl;

**适用场景**:

  • 频繁使用的命名空间成员

  • **确认不会引起命名冲突**的情况

  1. using指令展开整个命名空间(仅推荐练习使用)
cpp 复制代码
using namespace std;

cout << "Hello World" << endl;

**风险提示**:

  • **极易引起命名冲突**

  • **项目开发中严格禁止使用**

最佳实践建议:

项目开发推荐写法

cpp 复制代码
// ✅项目开发推荐写法
#include <iostream>

int main() {
    std::cout << "Professional code" << std::endl;
    return 0;
}

// 🚨仅限练习使用的写法(不推荐用于项目)
#include <iostream>
using namespace std;

int main() {
    cout << "Practice code" << endl;
    return 0;
}

记住:良好的命名空间使用习惯是编写可维护C++代码的重要基础!

三种写法:

cpp 复制代码
// 指定命名空间访问
int main()
{
printf("%d\n", N::a);
return 0;
}

// using将命名空间中某个成员展开
using N::b;
int main()
{
printf("%d\n", N::a);
printf("%d\n", b);
return 0;
}

// 展开命名空间中全部成员
using namespace N;
int main()
{
printf("%d\n", a);
printf("%d\n", b);
return 0;
}

C++输⼊&输出

基本概念
<iostream>(Input/Output Stream)是 C++ 标准库中的输入输出流库,定义了标准输入输出对象。

主要组件

标准输入输出对象
-`std::cin`
属于 `istream` 类对象,处理窄字符(`char` 类型)的标准输入流

  • `std::cout`
    属于 `ostream` 类对象,处理窄字符的标准输出流

操作符与函数

  • `<<`
    流插入运算符(输出)

  • `>>`
    流提取运算符(输入)

  • `std::endl` (推荐使用)
    插入换行符并刷新缓冲区

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
int a = 0;
double b = 0.1;
char c = 'x';
cout << a << " " << b << " " << c << endl;
std::cout << a << " " << b << " " << c << std::endl;
scanf("%d%lf", &a, &b);
printf("%d %lf\n", a, b);
// 可以⾃动识别变量的类型
cin >> a;
cin >> b >> c;
cout << a << endl;
cout << b << " " << c << endl;
return 0;
}

#include<iostream>
using namespace std;
int main()
{
// 在io需求⽐较⾼的地⽅,如部分⼤量输⼊的竞赛题中,加上以下3⾏代码
// 可以提⾼C++IO效率
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
return 0;
}

C++ I/O 优势

  1. **类型安全** - 自动识别变量类型(通过函数重载实现)
  2. **扩展性强** - 完美支持自定义类型的输入输出
  3. **使用简便** - 无需手动指定格式说明符

命名空间注意事项

  • C++ 标准库组件位于 `std` 命名空间
  • 推荐用法:
cpp 复制代码
std::cout << "Hello" << std::endl;
  • 练习时可使用:
cpp 复制代码
using namespace std;
  • 项目开发中不建议使用 `using namespace std`

兼容性说明
在包含 `<iostream>` 后:

  • VS 系列编译器可同时使用 `printf/scanf`
  • 其他编译器可能需要显式包含 `<cstdio>`

缺省参数

基本概念

缺省参数(又称默认参数)是在函数声明或定义时为参数指定的默认值。调用函数时:

  • 未提供实参:使用形参的缺省值

  • 提供实参:使用指定的实参值

分类与规则

  1. 全缺省参数
cpp 复制代码
void func(int a = 10, int b = 20, int c = 30) {
    // ...
}
  1. 半缺省参数
cpp 复制代码
void func(int a, int b = 20, int c = 30) { // ✅正确:从右向左连续缺省
    // ...
}

// void func(int a = 10, int b, int c = 30); // ❌错误:不能间隔缺省

重要规则:

  1. **半缺省必须从右向左连续缺省 **

  2. **调用时必须从左向右依次传参**(不能跳过中间参数)

cpp 复制代码
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
// 半缺省
void Func2(int a, int b = 10, int c = 20)
int main()
{
Func1();
Func1(1);
Func1(1,2);
Func1(1,2,3);
Func2(100);
Func2(100, 200);
Func2(100, 200, 300);
return 0;
}

声明与定义分离时的规则

当函数声明与定义分离时:

  • 只能在函数声明中 指定缺省参数

  • 定义中不能重复指定

cpp 复制代码
// ✅正确示例:
// test.h
void func(int a = 10); 

// test.cpp
void func(int a) { /*...*/ }

// ❌错误示例:
// test.h
void func(int a = 10);

// test.cpp
void func(int a = 10) { /*...*/ } // 重复指定缺省值

使用建议

  1. **将缺省参数放在头文件声明中**

  2. **避免在复杂函数中使用过多缺省参数**

  3. **注意缺省参数的求值时机**(每次调用都会重新求值)

函数重载

基本概念

函数重载(Function Overloading)是C++的重要特性之一:

  • ✅允许在同一作用域内定义多个同名函数
  • ✅要求各函数的形参列表必须不同(参数个数或类型)
  • ❌仅返回值不同不构成重载

与C语言的对比

C语言 C++
同名函数处理 直接报错 允许重载
多态支持程度 编译时多态
调用匹配方式 仅按名称 名称+参数类型
cpp 复制代码
// C语言示例(报错)
void print(int a) {}
void print(float a) {} // ❌重复定义错误

// C++示例(合法)
void print(int a) {}     // #1 
void print(float a) {}   // #2 ✅合法重载  

重载规则详解

参数数量不同构成重载
cpp 复制代码
2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
参数类型不同构成重载
cpp 复制代码
// 1、参数类型不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}

参数类型顺序不同

cpp 复制代码
3、参数类型顺序不同
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
不构成重载的情况
cpp 复制代码
// 返回值不同不能作为重载条件,因为调⽤时也⽆法区分
//void fxx()
//{}
//
//int fxx()
//{
// return 0;
//} 

最佳实践建议

  1. 保持语义一致性

    重载函数应执行相似操作(如各种类型的print)

  2. 避免过度重载

    超过5个重载建议改用类方法

  3. 注意隐式转换影响

    void calc(short s) {}
    void calc(long l) {}

    calc(10); //可能产生歧义(int→short/long)

扩展阅读:《Effective C++》条款26:尽可能延后变量定义式的出现时间

C++引用

引用的基本概念

引用(Reference)是C++特有的重要特性:

  • ✅为已存在的变量创建别名(不分配新内存)
  • ✅与原变量共享同一内存地址(如同人的绰号)
  • ❗符号复用:使用&表示引用(与取地址符相同)

引用语法规范

基本格式:

复制代码
类型& refName = originalVar; 

经典示例:

复制代码
int main() {
    int value = 42;
    
    int& refValue = value; // refValue是value的别名
    
    refValue = 100;        // value的值也被修改为100
    
    cout << value;         // Output:100
    
    return EXIT_SUCCESS;
}

*引用的实际用法

代替指针,实际上就是通过给传过来的参数取别名,来直接引用那片空间,直接进行交换等操作

cpp 复制代码
void Swap(int& rx, int& ry)
{
int tmp = rx;
rx = ry;
ry = tmp;
}
int main()
{
int x = 0, y = 1;
cout << x <<" " << y << endl;
Swap(x, y);
cout << x << " " << y << endl;
return 0;
}

优点:函数调用的时候不用再加&.

通过引用和缺省参数可以更加的省事

cpp 复制代码
void STInit(ST& rs, int n = 4)
{
rs.a = (STDataType*)malloc(n * sizeof(STDataType));
rs.top = 0;
rs.capacity = n;
}

引用特性深度解析

内存模型分析:

复制代码
原变量value    引用refValue 
┌─────────┐     ┌─────────┐ 
│   0x100 │◄─────┤   0x100 │ 
├─────────┤     ├─────────┤ 
│    100  │     │         │ 
└─────────┘     └─────────┘ 

关键限制条件:

必须初始化

复制代码
int& badRef; // ❌错误:未初始化引用 

不能改变绑定

复制代码
int a=1, b=2;
int& r=a;
r=b;        // ✅赋值操作而非重新绑定 
            // a的值变为2,r仍绑定a 

不能有空引用

复制代码
int* ptr = nullptr;
int& ref = *ptr; // ❌危险行为!运行时错误 

引用vs指针对比表

引用 指针
内存开销 无额外开销 需要存储地址
初始化要求 必须初始化 可延迟初始化
可变性 永久绑定 可重新指向
null检查 永远非空 可能为空
访问方式 自动解引用 需显式解引用

实际应用场景

这里还没有了解到,等了解到了为大家弹链接:

函数参数传递(避免拷贝)
复制代码
void processBigData(BigData& data) { 
    //修改会影响原数据但无拷贝开销 
} 

BigData dataset;
processBigData(dataset);
函数返回值优化
复制代码
vector<int>& getCache() { 
    static vector<int> cache; 
    return cache; //避免返回时拷贝整个vector 
} 

auto& cache = getCache(); //直接操作原缓存 

常见误区警示

  1. 返回局部变量引用

    int& dangerousFunc() {
    int local =10;
    return local; // ❌局部变量销毁后引用无效!
    }

    auto& ref = dangerousFunc(); //崩溃风险!

  2. 混淆引用与指针操作符

    int x=5;
    int* ptr=&x; // &取地址操作符
    int& ref=x; // &引用声明符

    cout<<*ptr; // 解引用操作符
    cout<<ref; //自动解引用无需

  3. 误用const引用

    const int& r=42; // ✅合法:延长临时量生命周期

    double d=3.14;
    const int& cr=d; // ❗实际生成临时int变量绑定!

    d=4.14; // cr的值仍为3!

运行
设计哲学思考:虽然符号复用确实可能造成初学者的困惑(如&的多义性),但保持语言简洁性也是重要的设计考量。《The Design and Evolution of C++》中详细讨论了这类权衡决策

const引用的基本特性

const引用(常引用)是C++中重要的安全机制:

基本规则:

  • 可以绑定到const对象或普通对象上
  • 权限只能缩小不能放大("只读锁"原则)
  • 临时对象自动具有const属性

语法形式:

复制代码
const Type& refName = expression;

权限控制原理

权限传递方向:

复制代码
普通对象 ──允许─► const引用 (权限缩小)
const对象 ──禁止─►普通引用 (权限放大)
cpp 复制代码
int main()
{
const int a = 10;
// 编译报错:error C2440: "初始化": ⽆法从"const int"转换为"int &"
// 这⾥的引⽤是对a访问权限的放⼤
//int& ra = a;
// 这样才可以
const int& ra = a;

// 编译报错:error C3892: "ra": 不能给常量赋值
//ra++;

// 这⾥的引⽤是对b访问权限的缩⼩
int b = 20;
const int& rb = b;

// 编译报错:error C3892: "rb": 不能给常量赋值
//rb++;
return 0;
}

典型示例:

复制代码
int x =10;
const int& cr1=x;      // ✅允许:权限缩小 

const int y=20;
int& r=y;              // ❌错误:试图放大权限 

const int& cr2=y;      // ✅正确:权限匹配 

临时对象与const引用

临时对象的本质:

编译器自动生成的未具名存储空间(具有自动const属性)

实常性 指的就是借助临时空间存储再给到变量,也就是存在临时对象(被const修饰)

正确写法:
cpp 复制代码
int a=5;
int& rb=a*3;           // ❌临时对象具有常性 
//a*3的结果先存储在临时对象中,而用int& rb是对这个临时对象进行了引用
//说白了就是临时对象是被const修饰的空间,不能被修改
//本质就是权限的放大
double d=12.34;
int& rd=d;             // ❌类型转换产生临时int 
//错误类型和上面一样


const int& crb=a*3;    // ✅匹配临时对象的常性 

const int& crd=d;      // ✅合法绑定转换后的临时int 

//等效于: 
const int temp=static_cast<int>(d);
const int& crd=temp; 

底层机制解析

临时对象的生命周期延长:

当const引用绑定到临时对象时:

复制代码
表达式求值 →生成临时对象 → const引用绑定 →延长生命周期至引用作用域结束 

内存模型示例:

复制代码
原始表达式: const int& r = x + y;

编译器行为:
1. tmp = x + y;      //生成临时变量tmp (const属性)
2. const int& r=tmp; //绑定到常引用 

tmp的生命周期延长至r的作用域结束!

以下博主还没了解到,等了解的时候会为大家讲解,当然有大佬可以提前为大家讲解也是相当不错的。

实际应用场景

安全传递大对象:

复制代码
void process(const vector<int>& data){
    //保证不会意外修改调用方数据  
}

vector<int> bigData(1000000);
process(bigData);       //无拷贝开销且安全 

process({1,2,3});       //✅可接受临时vector 

优化性能技巧:

复制代码
string concat(const string& s1, const string& s2){
    return s1+s2;      //利用返回值优化(RVO)
} 

const string& result=concat("hello","world");//延长临时string生命周期 

常见误区警示

误用非const引用绑定右值

复制代码
string&& rvRef=getString(); //移动语义专用语法 ✔️ 

string& badRef=getString();// ❌非常引用不能绑右值! 

忽略隐式转换产生的临时对象

复制代码
class MyInt{
public:
    operator int() const{return value;} 

private:
    int value=42;
};

MyInt mi;
int& ri=mi;            // ❌实际产生临时int! 

const int& cri=mi;     // ✅正确方式 

滥用const_cast去除常性

复制代码
const int x=10;
const int& cr=x;

int& r=const_cast<int&>(cr); //语法允许但...
r=20;                        //❌未定义行为!可能崩溃! 

设计哲学思考:临时对象的常性是C++的重要安全机制。《Effective Modern C++》条款24专门讨论了右值引用、移动语义与临时对象的交互关系

C++指针与引用深度对比分析

兄弟关系比喻解析

指针和引用确实如同性格迥异的兄弟:

"哥哥"指针 "弟弟"引用
性格特点 自由奔放、功能强大但容易惹祸 乖巧可靠、安全稳定但缺乏灵活性
诞生顺序 从C语言继承而来 由Stroustrup专为C++设计
适用场景 需要动态内存管理或重定向的场景 需要安全别名且绑定不变的场景

核心差异对照表

基础特性对比:

指针 引用
内存占用 额外存储地址(4/8字节) 无额外存储(纯别名)
初始化要求 可延迟初始化 必须立即初始化
可变性 可改变指向 永久绑定
null处理 可设为nullptr 永远非空
访问方式 需显式解引用(*ptr) 自动解引用

操作差异示例:

代码演示:
复制代码
int main() {
    int val =10;
    
    /*-----指针操作-----*/
    int* ptr = &val;     //显式取地址    
    *ptr =20;            //显式解引用修改
    
    ptr = nullptr;       //可改变指向
    
    /*-----引用操作-----*/
    int& ref = val;      //必须初始化绑定    
    ref =30;             //直接操作原变量
    
    //ref = otherVal;     ❌无法重新绑定
    
    cout<<"val:"<<val<<" ref:"<<ref<<endl;
}
sizeof行为差异:
复制代码
32位系统示例:
sizeof(ptr) →4字节 (地址大小)
sizeof(ref) →4字节 (int大小)

64位系统示例:  
sizeof(ptr) →8字节 (地址大小)
sizeof(ref) →4字节 (int大小)

安全隐患对比

指针典型风险:

空指针问题:
复制代码
int* p = nullptr;
*p =42;               ❌运行时崩溃!
野指针问题:
复制代码
int* wildPtr;
*wildPtr=10;          ❌未定义行为!

delete ptr;           ❗ptr变成野指针!
悬垂指针问题:
复制代码
int* func(){
    int local=10;
    return &local;     ❌返回局部变量地址!
}

func作为局部域,出了函数就被销毁了,返回的是一个地址

相互转换关系

指针转引用(安全):

复制代码
int x=10;
int* ptr=&x;
int& ref=*ptr;       ✔️合法转换!

引用转指针(需注意):

复制代码
int& ref=x;
int* ptr=&ref;       ✔️等价于取x地址!

非常量引用转常量指针:

复制代码
const int* cptr=&ref;// ✔️权限缩小安全!

现代C+的最佳实践建议

1.优先选择引用的情况 :

-函数参数传递(避免拷贝)

-返回值优化(RVO场景)

2.必须使用指针的情况 :

-需要处理nullptr的特殊状态时

-需要动态内存管理(new/delete)时

3.混合使用策略:

复制代码
void smartProcess(const BigObj* ptr){
    if(ptr){           ✔️先检查空指针    
        const BigObj& ref=*ptr;//再转安全引用使用    
        ref.method();
    }
}

4.结合智能指针使用:

复制代码
unique_ptr<int> smartPtr=make_unique<int>(42);
int& ref=*smartPtr;     ✔️配合现代内存管理!

📚扩展阅读:《Effective Modern C+》条款18讲智能指针与引用的配合使用,《A Tour of C+》第7章详细讨论指针与引用的设计哲学

相关推荐
时艰.1 分钟前
Java 线程池 — ThreadPoolExecutor
java·开发语言·python
暖馒3 分钟前
深度剖析串口通讯(232/485)
开发语言·c#·wpf·智能硬件
新新学长搞科研7 分钟前
【CCF主办 | 高认可度会议】第六届人工智能、大数据与算法国际学术会议(CAIBDA 2026)
大数据·开发语言·网络·人工智能·算法·r语言·中国计算机学会
近津薪荼8 分钟前
优选算法——前缀和(1):一维前缀和
c++·学习·算法
草莓熊Lotso2 小时前
Linux 基础 IO 初步解析:从 C 库函数到系统调用,理解文件操作本质
linux·运维·服务器·c语言·数据库·c++·人工智能
梵刹古音2 小时前
【C语言】 字符数组相关库函数
c语言·开发语言·算法
闻缺陷则喜何志丹2 小时前
P8699 [蓝桥杯 2019 国 B] 排列数|普及+
c++·数学·蓝桥杯·数论·洛谷·数列
D_evil__8 小时前
【Effective Modern C++】第三章 转向现代C++:16. 让const成员函数线程安全
c++
微风中的麦穗8 小时前
【MATLAB】MATLAB R2025a 详细下载安装图文指南:下一代科学计算与工程仿真平台
开发语言·matlab·开发工具·工程仿真·matlab r2025a·matlab r2025·科学计算与工程仿真
2601_949146538 小时前
C语言语音通知API示例代码:基于标准C的语音接口开发与底层调用实践
c语言·开发语言