先讲讲自己的编程经历吧。
我最早接触编程是在初中的时候,当时因为参加竞赛,开始了 C++ 的学习。只可惜那时候只是参加了一些当地组织的比赛,并没有继续走到 NOIP 之类的竞赛舞台,现在想想也算是学生时代的一个小遗憾吧。(写到这里又开始感伤了哈哈)不过真正让我喜欢上编程的,其实并不是比赛本身,而是在第一次写出程序,第一次让计算机按照自己的想法解决一个问题的时候,那种很特别的感觉。我本身比较喜欢数学,也喜欢敲键盘,可能正是因为这两个原因,在写出第一个程序之后,我慢慢就喜欢上了编程。
很多人可能会觉得,会写代码就代表计算机水平很高,但其实并不是这样。我觉得自己就是一个比较典型的例子,虽然平时写代码不少,但距离真正意义上的计算机能力,还有很长的一段路。现实中的计算机领域,更多是工程实践、系统设计、软件架构等内容。而算法更多体现的是一个人的逻辑能力、抽象能力和解决问题的能力,这也是为什么高中阶段可能会看到一些数竞转信竞,或者数信双修的同学,因为两者在底层思维上确实有不少相通的地方。
高中时期,因为课业压力增加,我自然也不可能一直保持编程学习,只是在暑假或者一些空闲时间,零零散散写过一些基础代码。高考结束之后,我重新开始了编程学习之路,当时又接触了一些 C 和 Python。不过可能是因为 C++ 用习惯了吧,我其实并没有真正大量使用这两门语言。学完基本语法之后,更多时候还是继续使用 C++ 解决问题,甚至后来也逐渐接触了一些 vibecoding。所以现在回头看,虽然我知道 C 和 Python 的语法,但真正让我用它们完成一些复杂任务,反而没有 C++ 那么熟练。
后来,我慢慢接触到了区块链。这是我目前比较感兴趣的一个方向。如果未来只能选择一种技术改变金融领域,我大概率还是会选择区块链。关于这个方向,我之后也会单独写一篇文章,聊聊自己对区块链的一些理解。接触区块链之后,再加上自己对 C++ 一些特点的重新认识,我开始了解另一门比较新的语言——Rust。Rust 是我目前比较看好的一门语言,对它的一些描述是它试图在性能、安全和现代开发体验之间寻找新的平衡,这也是它吸引我的地方。当然,还有很多语言也值得学习,Java、JavaScript、Go、Swift、Lean、Solidity 等语言,都在自己的领域发挥着重要作用,只是受到发展方向、学习成本以及语言自身特点的影响,目前暂时没有深入研究。
介绍完自己的编程经历后,我想说的是:编程语言其实没有绝对的优劣。不同语言诞生于不同的背景,也适用于不同的问题。它们更像是工具箱中的不同工具,没有必要追求掌握所有工具,而是在面对问题的时候,知道应该选择什么工具,以及为什么选择它。
我的起跑线
在真正开始重新认识 C 和 Python 之前,我觉得有必要先回顾一下自己的起点。 我的编程经历主要从 C++ 开始,而且很大程度上来自算法竞赛。 不过这里需要说明一下,我熟悉的 C++ 其实并不是完整意义上的 C++。相比于工程开发中涉及的大量内容,我接触最多的还是竞赛中的那一套:STL、数据结构、算法模板,以及如何快速把一个想法转化成代码。
比如数组,我习惯使用:
vector<int> v;需要排序的时候:
sort(v.begin(), v.end());需要记录一些键值关系:
map<string, int> mp;这些东西在算法竞赛中非常常见,也逐渐成为了一种编程习惯。 很多时候,面对一个问题,我想到的都是: 有没有现成的数据结构? 有没有合适的算法? 自己能不能快速实现? 程序能不能高效执行? 这也是 C++ 带给我的一种思维方式。 它提供了大量已经封装好的工具,同时又保留了足够的自由度,让我可以根据自己的需求进行修改和扩展,在保证开发效率的同时,也尽可能追求程序运行效率。
| 我在 C++ 里这么写 | 在 C 里对应 | 在 Python 里对应 |
|---|---|---|
vector<int> v; | 动态数组需要自己管理内存,例如 malloc | list,自动扩容 |
v.push_back(x); | 手动扩容并添加元素 | append(x) |
int* p = new int[10]; | malloc 分配内存,需要 free | 通常不需要直接管理 |
for(int x:v) | 使用下标或者指针遍历 | for x in list |
map<string,int> | 需要借助结构体、哈希表实现 | dict |
sort() | qsort() | sorted() 或 sort() |
当然,这张表只是列出了一些简单的区别。 实际上,不同语言之间的差异远不止这些。看到这里可能会产生一个问题: 为什么会有这么多编程语言? 既然 C++ 已经可以完成很多事情,为什么还需要 C、Python,甚至 Rust? 为什么不设计一门“万能语言”,解决所有问题呢?
为什么需要不同的编程语言?
在学习了几门编程语言之后,我曾经有过一个疑问: 既然 C++ 已经可以完成很多事情,为什么还需要 C、Python,甚至更多其他语言?
如果只是为了让计算机完成任务,难道一门语言不能解决所有问题吗?后来我慢慢发现,编程语言其实是在不同需求之间做出的选择。
计算机本身并不能理解人的想法,我们需要通过程序告诉它应该如何执行。但这里存在一个矛盾:
对于机器来说,我们希望程序运行得足够快,能够尽可能发挥计算机的性能;而对于人来说,我们又希望写代码的过程足够简单,可以快速验证自己的想法。
比如,如果我要控制一个机器,让它高效地执行某个任务,那么我可能需要更加关注底层细节,榨干它的所有性能。但如果我只是想快速验证一个想法,比如分析一批数据,那么我可能更希望少考虑一些底层问题,把更多精力放在自己的想法上。
这两个方向并没有谁一定更好。只是不同场景下,我们关注的重点不同。 C 语言更接近计算机本身,它给予程序员更多控制权;Python 则更加关注表达效率,让人可以用更少的代码完成更多事情;而 C++ 则处在两者之间,既保留了底层能力,也提供了大量高级工具。
这也是为什么不同语言能够长期存在。它们并不是简单的替代关系,而是在解决不同的问题。就像现实生活中,不同工具有不同用途一样。一把锤子和一把螺丝刀没有必要比较谁更优秀,重要的是面对不同的问题时,知道应该选择什么工具。
对于编程语言来说也是如此。真正重要的可能不是“哪门语言最好”,而是理解: 为什么这门语言会这样设计? 它希望解决什么问题? 它又做出了什么取舍?
往下看一层:C
学习 C 的过程,有点像重新拆开一个已经习惯使用的工具。以前写 C++ 的时候,很多事情都是理所当然的。 需要动态数组? vector。 需要字符串? string。 需要映射关系? map。 需要动态申请空间? new。 这些东西已经成为了一种编程习惯,以至于我很少再去思考: vector 的底层是什么? new 到底帮我做了什么? 程序运行的时候,内存究竟发生了什么? 而 C 语言恰好把这些问题重新摆到了面前。 在 C++ 中,我更多关注的是: “我要解决什么问题。” 而在 C 中,我需要开始关注: “计算机到底是如何完成这件事情的。”
看见 C++ 隐藏的东西
比如动态数组。 在 C++ 中:
vector<int> v;然后:
v.push_back(x);即可完成扩容和添加元素。 但在 C 中,没有现成的 vector,需要自己申请内存,管理空间大小,并在需要的时候重新分配。 这让我第一次更加直观地理解: C++ 并不是凭空创造了这些能力,而是在 C 的基础上建立了一层更方便的抽象。 同样,new 和 delete 也是如此。 C++:
int* p = new int[10];
delete[] p;C:
int *p = malloc(sizeof(int) * 10);
free(p);看起来只是语法不同,但背后体现的是不同的设计理念。C 把更多控制权交给程序员。这带来了更强的自由度,同时也意味着程序员需要承担更多责任。内存泄漏、数组越界,这些问题不会因为语言简单就消失,而是需要开发者更加小心。 学习 C 的意义,并不是因为以后一定要用 C 写所有程序,而是它让我重新理解: 程序到底是如何运行在计算机上的。 其实,这也是我后来重新认识 C 的一个原因。
一个问题
之前参加网络安全面试的时候,曾经遇到过一个让我印象很深的问题:
printf("hello"); 这样一句简单的代码,在计算机内部到底经历了什么?
(其实当时研究生学长问我的原问题是:print(f) 这一行代码,在计算机中是如何一步一步执行出来的。)
当时的我其实回答不上来。因为平时写代码时,我更多关注的是: 程序能不能运行? 结果是否正确? 算法是否高效?
但很少真正思考: 这一行代码从源代码到屏幕上的字符,中间到底发生了什么? 函数是如何被调用的? 参数是如何传递的? 数据经过了哪些层次? 操作系统和硬件又参与了什么?
这些问题可能已经超出了某一门语言本身,而是计算机系统的基础。 而学习 C,恰好提供了一条更加接近计算机运行过程的路径。 它不会替你隐藏太多细节,反而会迫使你重新思考: 一段程序究竟是如何从源代码,变成计算机真正执行的指令。 至于这个问题的完整答案,我打算之后单独写一篇文章。
从一行简单的 printf("hello"); 开始,看看一段代码究竟是如何一步一步在计算机中运行起来的。
换一个方向:Python
如果说 C 是让我往计算机内部看,那么 Python 则刚好是另一个方向。 它让我开始思考: 如果程序的目标是快速验证一个想法,那么我们是否真的需要关注所有底层细节?
在学习 C++ 的过程中,我逐渐习惯的一种思维方式是: 变量是什么类型? 数据存储在哪里? 算法复杂度是多少? 程序如何运行? 这些问题当然很重要。
但有些时候,我们面对的问题并不是如何让计算机发挥极限性能,而是如何快速把自己的想法实现出来。
而 Python 恰好选择了另一种设计方向。
从写代码到表达想法
比如在 C++ 中,如果需要保存一组数据:
vector<int> v;
v.push_back(1);
v.push_back(2);而在 Python 中:
v=[1,2]同样的事情可以更加直接地表达。 这种区别并不是简单的“代码多少”。 背后体现的是两种不同的设计思想。 C++ 更倾向于让程序员拥有更多控制权。 Python 则希望程序员能够更加关注问题本身,而不是花费大量精力处理语言和底层细节。
动态类型带来的自由
Python 一个很明显的特点就是动态类型。 在 C++ 中:
int a = 10;变量的类型在定义时已经确定。 而 Python:
a = 10
a = "hello"它允许变量名在不同时间引用不同类型的对象。 这种设计让 Python 写起来更加灵活。 尤其是在数据分析、人工智能、自动化脚本等场景中,我们往往更关注: 这个想法能不能快速验证? 这个数据能不能快速处理? 这个模型能不能快速运行? 而不是一开始就设计完整的数据结构。
但隐藏复杂性并不代表复杂性消失
不过,Python 的简单也并不是没有代价。 很多时候,人们会说: “Python 很慢。” 但这个“慢”其实需要具体分析。 如果是大量简单循环:
for i in range(10000000):
...Python 的执行效率确实通常不如 C/C++。 因为 Python 需要解释器参与执行,并且动态类型也带来了额外开销。 但如果任务主要是: 数据读取、网络请求、调用成熟库、AI模型训练, 那么 Python 的效率可能并不会成为主要瓶颈。 很多时候,真正限制我们的并不是计算机运行速度,而是人的开发速度。 以前学习 C++ 的时候,我更多关注: 如何让程序更快? 如何设计更好的算法? 如何优化复杂度?
而 Python 让我看到另一种可能: 程序也可以是一种快速表达想法的工具。 很多人工智能、数据分析领域的发展,也离不开 Python 这种“降低实验成本”的特点。 当然,这并不意味着 Python 可以替代所有语言。 如果需要接近硬件、追求极致性能,C/C++ 仍然有不可替代的价值。 但如果目标是快速探索、验证想法,那么 Python 提供了一种非常高效的方式。 这也是我重新认识 Python 后最大的感受: 编程不仅仅是让机器执行命令。有时候,更重要的是让人的想法能够快速变成现实。
一个反思
其实,回过头来看,我之前没有真正掌握 Python,也有一些自己的原因。
写算法题比较多之后,我会对一些“黑盒”产生天然的抵触。 在算法竞赛中,我习惯了去理解: 一个数据结构为什么这样设计? 一个算法为什么能够成立? 一个优化为什么能够降低复杂度?
所以当面对 Python 中大量封装好的库和接口时,我有时候会产生一种不太适应的感觉。 因为如果不了解背后的原理,只是记住: 这个函数怎么调用。 这个库怎么使用。 那么这些东西很容易随着时间遗忘。
而 Python 恰恰是一门高度依赖生态的语言。 很多时候,真正解决问题并不是自己从底层实现所有东西,而是知道: 有没有现成的工具? 如何正确使用它? 它背后的原理是什么? 这也是我过去学习 Python 时遇到的问题。
另一个原因,则是 C++ 使用习惯带来的影响。 从 C++ 切换到 Python,并不仅仅是语法变化。 它背后对应的是两种不同的编程思维。 C++ 中,我习惯关注数据结构、类型和效率;而 Python 中,我需要更加关注如何快速表达想法。 这种思维方式的转换,并不是简单背几个语法就能完成的。
之前参加网络安全面试时,也暴露出了这个问题。 当时有同辈问我: 脚本是不是自己写的? 我回答是通过 AI 辅助完成。 现在回头看,一个学习过 Python 的人,如果连一些基础脚本都无法独立完成,着实可笑。
但我觉得,能够早点发现这个问题,也是一件好事。 至少它让我意识到: 学习一门语言,不能只停留在知道语法、会调用工具。 真正重要的是理解它的设计思想,并通过实际使用建立自己的能力。 所以之后,我也会像前面重新认识 C 一样,重新补充自己的 Python 学习过程。 从简单脚本开始,真正理解 Python 为什么适合快速表达想法,以及它在实际工程中是如何被使用的。
看一眼 Rust
关于 Rust,其实目前我的了解还比较有限。 我接触它主要是因为区块链和底层开发方向的兴趣。相比 C++,Rust 希望在性能、安全性和现代开发体验之间找到一种新的平衡。 不过目前我还没有真正使用 Rust 完成过实际项目,所以这里不会过多评价它。 等未来真正学习和使用之后,可能再回来打个补丁。
写给刚开始编程的人
回头看自己的编程经历,我其实觉得自己从 C++ 开始学习编程是一件比较幸运的事情。 当然,这并不代表 C++ 一定是最好的入门语言。不同的人有不同的目标,也会有不同的选择。 如果你喜欢算法、数学,或者希望训练自己的逻辑能力,C++ 可能是一条不错的道路。它会让你接触数据结构、算法,培养一种更加严谨的思考方式。 如果你的目标是快速做出一些东西,比如自动化脚本、数据分析或者人工智能应用,那么 Python 可能会更加适合。 如果你想进一步理解计算机内部,理解内存、程序运行和硬件之间的关系,那么 C 会是一条很好的道路。
但无论选择哪门语言,我觉得最重要的不是“学会多少语法”,而是不要停留在: “这个函数怎么调用?” “这个代码怎么运行?”
而应该继续追问: 它为什么这样设计? 它解决了什么问题? 它背后隐藏了什么?
编程语言会不断变化,新的语言也会不断出现。 真正属于自己的能力,是面对一个问题时,能够分析它、拆解它,并选择合适的方法解决它。
换成我自己的选择
回到自己身上,我目前对于这些语言的定位其实还比较简单。
C++ 依然会是我解决算法问题的主要工具。 C 则更多承担“理解计算机”的角色。它让我重新关注那些平时容易忽略的细节:内存如何管理,程序如何运行,代码如何一步步变成机器能够执行的指令。 Python 可能会是我之后需要重点补充的一门语言。以前我更多停留在“知道语法”的阶段,未来希望真正用它快速验证想法、编写脚本、处理数据,把它变成解决实际问题的工具。 至于 Rust,目前更多是一种对未来的储备。我目前对它的了解还比较浅,真正的认识还需要等未来实际使用之后再慢慢建立。
所以现阶段,我对自己的定位大概是: 用 C++ 训练算法思维,用 C 理解计算机底层,用 Python 提高解决问题的效率,用 Rust 探索未来可能的发展方向。
当然,这只是现在阶段的选择。技术的发展很快,自己的兴趣和方向也会不断变化。 但无论未来使用什么语言,我希望自己始终保持一个习惯: 不仅知道怎么写代码,也知道为什么这样写。
收尾
写完这些之后,我最大的变化可能不是学会了更多语言,而是重新认识写代码的方式。 C 让我重新关注计算机本身,理解程序如何运行;Python 让我看到快速表达想法的价值;而 C++ 则连接了算法思维和工程效率。 未来我可能还会学习更多语言,也可能会发现自己现在的一些理解并不完全正确。但至少现在,我希望自己不只是一个会写代码的人。 编程语言只是入口。真正值得探索的,是代码背后的解决问题的方式。