|
衡量一种语言(广义,不仅限编程语言)是否复杂,我们可以看其单词数量、词性变化以及语法结构。9 \& m' q/ \6 a5 Z 根据相关数据显示,到目前最新的C++20为止,C++的关键字大约是99个,还有6个特定上下文当中有特殊含义的名字。$ N% }+ _- q4 J6 B& S5 F { 作为对比,C语言,截止到C11,关键字是44个 显然,C++比C复杂,其关键字比C多一倍有余。# w; F N' B$ C: v4 P/ J8 `
但也有观点认为,C++只有在被孤立看待的时候,才会觉得复杂性。2 S" D; W2 M7 a 设计任何一门语言都是有背景的。2 H6 r6 Z2 o: O. J0 d5 w% K, C C++面向的是这样的特定用户:: _) ~0 U; g. B) _8 N, z' I0 w; s 应对各种复杂问题写出运行相当长时间的解决方法解决方案要满足任意的性能要求工作在不同的硬件和操作系统上和许多已存在的系统共存9 d6 p3 Z ?1 x6 y 虽然人们都希望有简单的语言,但是人们真正需要的是有助于解决问题的语言。 由于C++相当流行,因此得到结论: 人们愿意为了语言所提供的强大表现力和高效率而放弃对简单性的要求。+ ~6 n( I3 @7 u: I3 e7 X4 ~
既然如此,那为什么要解决的问题越复杂,工具就不得不复杂? 原因有三个。 第一个是类库和语言语意; R% J" ^ ]8 d2 G6 U* n% j% v2 m 诸如C++中的初始化和赋值,在许多的语言中几乎都没有什么区别,比如C。 那为什么在C++中却如此重要呢? C7 G, J5 E4 A7 h4 K; I A C++允许变量“拥有”一定的资源,如果值改变,就必须放弃这些资源。 当我们在编写那些要处理分配在别处的数据结构的类时,差异就变得十分重要。4 V# V% K" `5 E& q1 y9 P8 w
下面的代码在给s赋值时,s其实早就已经有一个值了(默认构造函数)。 在赋值的时候,s必须要放弃旧值占用的内存。2 f" Y7 f5 s$ ?$ b( Y6 y
% B0 n t; ]- I, z) V 原则上,两者之间的界限没有必要划清。* ?/ i5 \( O k8 X: _/ C8 F+ u" v 可以在初始化后紧跟一个析构操作,这样会简化很多程序,但是会使某些类的抽象变得难以实现。/ N$ N, ~% b8 Q3 v 比如 有一些C++的库会提供一种叫片的类,如果有某一个对象包括了某种数据结构,那我们可以创建一个指向该数据结构某部分的片,给这个片赋值,就会影响原数据结构中被选中的那部分。; B0 i; h" Y, N8 L7 p# r2 C! R
但如果赋值总等价于紧跟初始化后的析构操作,那此类的抽象就比较难实现了。 第二个是折中方案2 l7 v# Y: t- L& b: p 还有比如界面设计,在C++中有很多都是给类设计提供一种简化的工具,协助他们解决用户界面的问题。0 I% @3 C. T2 E; c( s) h 所以用C++设计类比用其他语言会难更多。' z' w6 N' k0 n4 v0 r5 N& Z/ f* x( ? 但同时解决方案也更广泛。 这会给库设计者提供更策略化的可能性,使得他们能考虑更多。/ q3 ?7 J- p5 S& q- o# p 通过精心设计的C++库会变得非常好用。
大家都会觉得,设计一个优秀的变长字符串和负数类十分困哪,但如果把这些东西补充到编译器中,那将会是难上加难。$ I3 h$ E* |4 R$ K* @' ]4 Z 原因是,用户很少有权利和能力去修改自己的编译器,把这种改变迁移到不同的编译器上就更别提了。( A5 Y& h! }! Y 基于此,C++提供了一个比较折中的方案。* c4 @. d: e7 D) R 它能允许我们在无需改变编译器内部的工作模式下,就能详细地定义抽象概念的具体行为。4 e2 I8 @8 |+ w1 a: Q- _ 第三个原因是复杂度的守恒" _/ k# h' U, V! _ 计算机系统复杂且具有阶段性,如果忽略了这种复杂性,不仅不能消除复杂性,还要付出一定的代价。( ?) j8 {1 x2 }/ n' C 例如计算3个浮点数相加的问题:$ Q* u8 E8 r6 ~& v! X+ Q% _
这段代码并不能对1020、-1020、1的所有排列提供精准的答案。' z+ [7 z4 i" c$ f8 S" n# E 1020+1和-1020将等于1020,1最终会被完全丢掉。 在解决这个问题时,我们可以选择处理掉或者忽略掉复杂性。 如果决定要处理,那么就需要通过确保最精准的可能答案来完成这一点。 如果忽略复杂性,那么复杂性就会转移到其它地方。 处理复杂问题的软件是肯定要面对复杂性的。
部分语言假装复杂性不存在而选择忽略它,给用户提供了一个干净整洁的接口。0 u' Q& k/ y3 W 如果世界上有些地方不符合他们所设想的模型,就干脆直接忽略掉。 还有一些语言则是把复杂性直接扔给用户。(如果用户可能不管行,就赢得了博弈,这就是为什么那么多不完善的软件产品在尚不完善时就交付了)。, q* w) j# M- x! L 在这里,C++则是采用折中办法,它允许我们编写对操作环境实施最底层控制的程序,也允许我们忽略大部分不那么重要的细节。 为了可以更加灵活,它付出的代价也更为庞大。
灵活性对于库类的设计者来说十分宝贵,他们因此能给用户提供使用不同的抽象级广泛应用领域的功能。$ o4 d3 B+ ^ ^' H1 S 因此,从长远来看,抽象仍然是世界最有力的工具。6 K9 P4 @3 S0 `5 C4 ^8 B2 k 那对于小伙伴来说,你觉得C++是复杂还是简单,复杂的原因是什么呢?欢迎讨论! |
微信公众号
手机版