当前位置: 首页 > news >正文

程序语言杂谈:C/C++

C C++
问世时间、创始公司 1972,Bell Laboratory 1979,Bell Laboratory
OOP 能力 不支持 强大,但复杂
类型系统 强类型 强类型
运行模式 原生编译 原生编译
跨平台能力 一般 一般
性能 极高 极高
关键词 高性能、底层 高性能、面向对象

Hello World 程序:

// C
#include <stdio.h>
int main() {printf("Hello, world!\n");return 0;
}
// Cpp
#include <iostream>
int main() {std::cout << "Hello, world!" << std::endl;return 0;
}

简介

推荐的书:《C Primer Plus》《C++ Primer Plus》

在过去 40 多年里,C 语言已成为最重要、最流行的编程语言之一。

虽然这些年来 C++ 和 JAVA 非常流行,但是 C 语言仍是软件业中的核心技能。在最想具备的技能中,C 语言通常位居前十。特别是,C 语言已成为嵌入式系统编程的流行语言。也就是说,越来越多的汽车、照相机、DVD 播放机和其他现代化设备的微处理器都用 C 语言进行编程。除此之外,C 语言还从长期被FORTRAN 独占的科学编程领域分得一杯羹。最终,作为开发操作系统的卓越语言,C 在 Linux 开发中扮演着极其重要的角色。因此,在进入 21 世纪的第 2 个10 年中,C 语言仍然保持着强劲的势头。

摘自:《C Primer Plus》,粗体是笔者加的

欢迎进入 C++ 世界!这是一种令人兴奋的语言,它在 C 语言的基础上添加了对面向对象编程和泛型编程的支持,在 20 世纪 90 年代便是最重要的编程语言之一,并在 21 世纪仍保持强劲势头。 C++ 继承了 C 语言高效、简洁、快速和可移植性的传统。 C++ 面向对象的特性带来了全新的编程方法,这种方法是为应付复杂程度不断提高的现代编程任务而设计的。 C++ 的模板特性提供了另一种全新的编程方法——泛型编程。这三件法宝既是福也是祸,一方面让 C++ 语言功能强大,另一方面则意味着有更多的东西需要学习。

摘自:《C++ Primer Plus》,粗体是笔者加的

C/C++ 都有内存占用小、性能好、接近底层的特征,而且生态相对成熟,几乎可以完成所有的编程任务。

C/C++ 学习曲线开始较平缓(尽管深入后变得陡峭),使其成为初学者的首选语言之一。

典型应用

  • 系统编程:编写操作系统(OS)、设备驱动、芯片固件、系统管理软件、编译器和解释器、数据库系统(SQL)等。
  • 高性能开发:浏览器引擎、游戏引擎、图像渲染、物理模拟、金融系统等。
  • 嵌入式开发 & 物联网:单片机等微处理器上的程序。
  • 底层开发:需要直接与硬件、系统 API 交互的场景。

另外一说,C/C++ 也是恶意程序偏爱的语言。(所以 C/C++ 程序有时容易被杀毒软件索敌。。。)

高性能

C/C++ 程序的性能上限很高,原因主要有:

  • C/C++ 原生编译运行,相比托管语言(如 Java、C#、Python 等),没有托管环境的 “中间层”,操作更快。
  • C/C++ 提供了 “强大而灵活” 的功能,恰当利用它们可以大幅提高程序性能。例如:位操作、指针等。

零开销抽象

C++ 的零开销抽象(Zero-overhead Abstraction)是C++设计的重要原则之一:

  1. 不为不使用的功能付出代价(You don't pay for what you don't use)。
  2. 你使用的东西,你不可能用更低的代价手工实现(What you do use is just as efficient as what you could have written by hand)。

这使得 C++ 的性能与 C 接近,还可以 “免费” 享受抽象的便利。

内存开销小,手动管理

相比托管语言,C/C++ 的内存开销十分优秀。这是因为托管语言的内存需要垃圾收集器(GC)来释放,而 C/C++ 的内存由程序员手动管理(包括内存的申请和释放)。一般来说,程序员比 GC 更知道 “内存该何时释放”,因而 C/C++ 的内存开销几乎是最小的。

内存模型简介

C/C++ 是需要手动管理内存的语言。作为这类语言的代表,这里简单介绍一下 C/C++ 的内存模型。

C/C++ 有两种内存:栈内存、堆内存。在函数体中直接声明的变量,其存在栈内存中。栈内存由系统自动分配,在栈内储存的变量在编译时确定(自由度比较低)。栈内存的一个例子:

// C
int main() {int a = 0;char str[] = "Hello, world!";return 0;
}

astr[] 都在栈内存中。栈内存中的变量会在其声明周期结束后自动释放。在本例中,main() 退出时就会释放 astr[]。栈内存是连续的,在内存地址上,astr[] 是紧邻的。

堆内存需要手动分配和释放,且申请速度较慢(因为需要 System Operation)。以下是例子:

// C
#include <stdlib.h>
int* func() {int* p = malloc(sizeof(int));return p;
}
int main() {int* q = func();free(q);return 0;
}

在本例中第 4 行,我们用 malloc() 在堆上申请一块内存,并用一个指针 int *p 来接收它。注意尽管我们申请的内存在堆上,但是指向这块内存的指针 p 是存储在栈内存中的。第 6 行,p 的声明周期结束,其被释放,但是其指向的堆内存并没有释放。在第 9 行,我们用 free 手动释放这块内存。

C++ 用,可以用 newdelete 来申请、释放内存,更方便一些。

底层能力

C/C++ 的底层能力是显著优势,具体来说:

  • C/C++ 提供直接的内存操作,也就是程序员可以很自由地操作指针。具体请见上一节。

  • 一些系统级 API 是以 C/C++ 提供的。例如,在 Windows 系统上,我们直接通过 Windows API 写入文件(这允许我们进行更高级的文件操作):

    // C
    #include <windows.h>
    int main() {HANDLE file = CreateFileA("test.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);const char* data = "Hello, Windows API!";DWORD bytesWritten;WriteFile(file, data, strlen(data), &bytesWritten, NULL);CloseHandle(file);return 0;
    }
    
  • 直接与硬件操作。例如,直接控制串口通信(如 USB 通信)。具体来说比较复杂,这里不举例了。

  • 硬件特定优化:例如 SIMD、缓存优化等。

还有更多对内存、CPU 等的精细操作可以通过 C/C++ 完成,这里也不举例了。

弊端

C/C++ 不是没有缺陷的,下面介绍它们的弊端。

指针与内存管理

从前面的内容不难看出,堆内存需要程序员手动释放,如果程序员忘了释放,将导致 “内存泄漏” 的灾难。C++ 提供了智能指针(如 std::shared_ptr)来帮助程序员管理内存,但总体来说内存管理仍是 C/C++ 程序员需要面对的挑战。除此之外,还有可能遇到空指针、野指针等挑战。

异常机制(C++)

C++ 的异常机制几乎是 “半残” 的。要保证 C++ 程序的异常安全通常比较难,而且不推荐使用。这主要因为:

  • C++ 抛出的异常可以是任何类型,甚至是 void。这使得捕获所有异常比较困难。

  • C++ 不要求函数声明它抛出什么异常,这样就不容易知道需要处理哪些异常。

  • C++ 标准库抛出异常的行为比较混乱。例如:

    // Cpp
    #include <vector>
    int main() {std::vector<int> v;v.at(10);     // 抛出 std::out_of_rangev[10];        // 未定义行为,不保证抛出return 0;
    }
    

C++ 中不推荐使用异常机制,这还有一个原因:写异常处理代码可能导致额外的开销,这违背了 C++ “零成本抽象” 的理念。

标准库有限 & 生态碎片

如果仅使用 C/C++ 的标准库,要开发现代的应用程序有一定难度,因为如网络编程、一些 IO 功能(比如 JSON 解析),标准库没有支持。这其实和 C/C++ 标准库的定位有关。

标准库功能的范围有限(基本上只有核心的算法),因而往往需要使用很多第三方库来补充和拓展,这就使得快速上手开发变得比较困难。当然,这也催生了如 Boost,Qt 等解决方案,它们集合了大量通用功能(基本上是 “大杂烩”)。(后面会介绍)

这些第三方库百家争鸣,有时一个功能有好几个开源库实现,但支持情况、维护频率又有所不同,各个库之间的协作效果有时不尽人意……这就构成了 “生态碎片” 的问题。

晦涩(有时)

这其实取决于程序员如何写 C/C++。由于 C/C++ 的 “强大和灵活”,程序员可以写出像这样的代码(OIer 可能比较眼熟):

// C
#include <stdio.h>
#include <ctype.h>
int read() {char c = getchar(); int x = 0;while (!isdigit(c)) c = getchar();while (isdigit(c))x = (x << 3) + (x << 1) + (ch ^ 48), c = getchar();return x;
}

第 7 行看着是不是一头雾水? x = (x << 3) + (x << 1) 实际上与 x *= 10 等效,ch ^ 48ch - '0' 等效。我们采取晦涩的写法,一定程度上可以增强性能,但是牺牲了可读性。

困境

C/C++ 如此强大,但是要用 C/C++ 快速开发一个现代应用程序,却充满挑战:

  • 技术选型:不得不使用第三方库,难以回避生态碎片的问题。
  • GUI:要用 C/C++ 开发出现代的 GUI 程序比较困难。
  • 编译问题:C/C++ 多源文件编译比较缓慢(相比 Java、C# 等),没有真正的模块系统。这主要是编译时的预处理(比如处理 #include)导致的。虽然有一些缓解措施(比如 “预编译头”),但仍是核心痛点之一。
  • 开发体验:比如写 :: 不如 . 方便,方法的声明和定义要分离,等等。

如果你想快速开发一个现代应用程序,笔者推荐 C#。

生态

C/C++ 的生态很发达,这里只举一些代表性的例子。

Boost

Boost 是一个广泛使用的 C++ 库集合,它提供了许多功能,覆盖了多个领域,如算法、容器、函数式编程、泛型编程、模板元编程、并发编程等。Boost 库通常被认为是“准标准”库,因为许多 Boost 库后来被纳入 C++ 标准。例如,C++11 及以后的标准中引入了智能指针(shared_ptr, weak_ptr)、正则表达式、线程库等,这些都在 Boost 中先出现。

由 DeepSeek 总结,供参考

Boost 尽管功能全面,但是历史悠久,技术债逐渐累积,如今也不是太好用。Boost 的地位或许会逐渐下降,Boost 的一些组件也逐渐有了更优的替代。

Qt

Qt 是一个跨平台的 C++ 应用程序开发框架。它远不止一个 GUI 库,而是一个全面的工具集,用于创建高性能、现代化的桌面、嵌入式和移动应用。

Qt 的商业模式

  • 开源版本(Qt for Open Source):使用 GPL/LGPL 许可证。如果你的项目也是开源的,可以免费使用。
  • 商业版本:提供专业的技术支持、更宽松的许可证(允许闭源开发)和额外的工具模块。需要付费购买。

谁在使用 Qt?

Qt 被广泛应用于各个领域:

  • 汽车:宝马、奥迪、特斯拉等品牌的车载信息娱乐系统。
  • 工业自动化:工业控制软件、医疗设备界面。
  • 嵌入式设备:智能家居中控、路由器管理界面、机顶盒。
  • 知名软件:Autodesk Maya, Adobe Photoshop Elements, VirtualBox, WPS Office, VLC 媒体播放器等。

由 DeepSeek 总结,供参考

Qt 的主要特点是:跨平台、全面、GUI。不少常见的应用也是用 Qt 编写的。因为 Qt 的商业模式,其在闭源软件中的使用不多(听说授权费很高)。

笔者体验过一点 Qt,感觉工具链不是很成熟,而且 Qt 做出来的 UI 颜值一般。笔者个人认为,Qt 有些古老了,其 “信号与槽” 的框架有更优秀、更简洁的替代(比如 XAML 的绑定语法)。而且 SDK 和 Runtime 都的体积都挺大的。如果你用 Qt 做一些小程序,那么发布包会显得很大。

Qt 给笔者一种 “笨拙” 的感觉。

可以看看:Qt血的教训/细数Qt开发的各种坑/又爱又恨/欢迎围观留言评论 - 飞扬青云 - 博客园。

Visual C++

核心组成部分

Visual C++ 主要包含以下几个关键部件:

  1. VC++ 编译器 (cl.exe)
    • 负责将 C/C++ 源代码编译成目标代码和可执行文件。它以其高性能和深度优化而闻名,特别是对 Windows 平台的优化。
  2. Visual Studio IDE
    • 提供强大的代码编辑器、调试器、项目管理器、UI 设计器等,极大地提高了 C++ 的开发效率。
  3. Microsoft C++ 标准库
    • 包括 C 运行时库 和 C++ 标准库的实现。
  4. Windows API 和 SDK
    • 提供访问 Windows 操作系统核心功能的接口,是开发原生 Windows 应用程序的基础。
  5. MFC 和 ATL
    • MFC:微软基础类库,一个用于快速构建传统 Windows 桌面应用程序 UI 的 C++ 类库,在早期非常流行。
    • ATL:活动模板库,用于轻量级、高效的 COM 组件开发。

由 DeepSeek 总结,供参考

Visual 是微软推出的一套 SDK,在 Windows 平台上挺重要的。其工具链成熟,开发还算流畅。我认为有以下不足:

  • Windows API:这是很低级的 API,如果你想用它开发现代程序(比如写 GUI),那简直是折磨。(不要这么做。)
  • MFC:提供比 Windows API 高级点的封装,但是也不是很理想。MFC 可以让你 “拖拖拽拽” 就整出一个 GUI 程序。非常非常简单的程序还勉强可以用 MFC;如果 UI 或者程序需求比较复杂(多页、多窗口),不建议使用 MFC,这是挺古老的技术了。

其他

放在 “其他” 不代表它们就不重要!这只是因为笔者对他们了解不多。

  • OpenCV:开源的计算机视觉库。
  • POCO:一套功能强大的跨平台开源 C++ 库。
  • NVIDIA CUDA:使用 NVIDIA 图形卡强大的并行计算功能,可以用于机器学习、图像渲染等场景。
  • Unreal Engine:知名的游戏引擎。

Ending

以上就是 C/C++ 的介绍了。C/C++ 是很复杂的语言,无论是语法特性还是生态现状都不简单。笔者能力有限,只能介绍自己比较熟悉的部分。笔者曾有多年的 C/C++ 经验,在这里也是付出过心血踩过坑,对 C/C++ 真是又爱又恨。

http://www.hskmm.com/?act=detail&tid=21739

相关文章:

  • 2025秋_7
  • PEP8 规范
  • print() 函数
  • 第九天
  • Pycharm 设置
  • [NOIP 2016 提高组] 组合数问题
  • 新建第一个项目
  • 笛卡尔树 (区间最小值)
  • CF2003F. Turtle and Three Sequences
  • 【Rust GUI开发入门】编写一个本地音乐播放器(11. 支持动态明暗主题切换) - Jordan
  • 利用接口中的静态虚拟成员实现自定义配置节
  • 天线增益与有源接收面积之间的关系
  • 2025CSP-S晋级和英才计划入围后:我走过了哪些路
  • 流量分析
  • fdsaf -
  • 【J+S 二十连测】-- 第十二套爆炸记
  • 2025-2026-1 CS3311 软件工程 个人项目第一版已发布
  • Python浅拷贝、深拷贝
  • 破解 Pycharm
  • 阿里业务身份建模
  • 实用指南:矩阵结构体 图片绘制 超级玛丽demo6
  • 5分钟理清:Session、JWT、Token、SSO、OAuth 2.0 认证逻辑
  • 2025年10.1~10.6日信息竞赛计划安排表
  • 【Rust GUI开发入门】编写一个本地音乐播放器(10. 拼装UI组件) - Jordan
  • 国产数据库-达梦docker镜像安装
  • CAP 8.4 版本发布通告
  • 【Leetcode】随笔 - 详解
  • DevEco Studio 编辑器的使用 - 实践
  • docker安装MySQL8.0.25的坑
  • WPF 深入系列.2.布局系统.尺寸属性 - 指南