上周,我那读小学的侄女趴在我肩膀上,看我写代码。屏幕上密密麻麻的括号和分号并没有吸引她,反倒是那个星号,让她歪着脑袋问了一句:“舅舅,为什么你们编程里的乘法用星星,不用我们数学课的叉叉?那个叉叉不是更对吗?你写个星星,电脑会不会以为你要‘备注一下’?”
我愣了一下神。做了这么久开发,这个问题就像呼吸一样自然,以至于我们从未深究过“*”凭什么霸占了键盘C位,而那个在数学课本上统治了乘法的“×”,竟被编程世界无情地拒之门外。
其实,这不是一个小孩子的无聊问题,这背后牵扯到的,是一场跨越半个世纪的“符号权力战争”。今天,我们就来扒一扒“*”上位的那点事儿。
一、第一道致命伤:那个年代的键盘,根本没给“×”留位置
把时间拨回1960年代,计算机还是恐龙级的庞然大物。那时的输入输出设备极其原始,而我们今天熟知的ASCII,即美国信息交换标准代码,正在制定中。
ASCII的制定逻辑充满了浓浓的实用主义:在极其有限的128个编码位中,既要塞下数字、大小写字母,又要塞下标点符号,留给“外来户”的名额几乎为零。在那个编码空间比黄金还贵的年代,“×”这种专门用于数学运算的高级符号,在计算机专家眼里简直就是奢华的装饰品。而“”这个小星星,因为长得像乘法,又在打字机上一直被当作现成的乘号用,自然而然就成了平替的首选。这一替,就直接写入了1963年的初版ASCII标准,从此“”名正言顺地在代码里安了家。
那个年代的程序员别无选择。不是他们不想优雅,是硬件根本没给他们优雅的资本。
二、第二道致命伤:视觉上的“撞脸”大灾难
如果说硬件限制是历史遗留问题,那第二个原因直到今天依然成立,甚至更为致命。
你想象一下,如果编程语言支持了“×”作为乘法,那么一行普通的代码可能长这样:
int a = 2 × x;
请问,这个“×”到底是字母x的小写,还是乘号?这种混淆对于编译器来说同样难以处理。在现代高分辨率屏幕上,一个标准的“×”乘号(Unicode U+00D7)和一个小写的拉丁字母“x”(Unicode U+0078),在如Consolas或Monaco这类等宽字体下,几乎就是一对双胞胎。如果再去查ASCII表,你会惊奇地发现,里面根本连“×”这个独立字符都没有。
为了人类阅读时少出bug,为了词法解析器能分清变量名和运算符,舍弃“×”几乎是现代编程语言的一种本能保护。
三、第三道无形却致命的墙:编程语言的效率本能
除了硬件和视觉,还有一层更深的逻辑,让“×”注定无法成为主流。
要知道,C语言之所以能成为编程界的基石,很大一部分原因在于它的“简练”。在C语言创立的年代,程序员追求的是代码的“紧凑性”和“输入的便捷性”。乘法作为极其高频的运算符,必须用一个能单手、甚至一根手指迅速敲出的字符。在标准QWERTY键盘上,“*”在主键盘区的8号键上方,伸手可及。而“×”呢?抱歉,主键盘区根本没这个人,你得切到数字小键盘或者靠输入法去抠。
对于一天要敲几万次代码的开发者来说,为了一次乘法要多做一个敲击动作,这在效率上无异于犯罪。
四、除了乘法,“*”其实还是个全栈“卷王”
如果仅仅是为了替代乘号,“*”的地位或许还没那么稳固。真正让它封神的,是这个符号在计算机科学里极其强大的“复用能力”。它就像一个全栈工程师,哪里需要去哪里。
在C语言里,除了乘法,intp 表示这是一个指针,指向一个内存地址;如果你在前面再加一个星号,p 则是对这个指针进行解引用,直接取出那个内存里的数据。到了正则表达式里,“”摇身一变成了匹配规则,比如 .可以吃掉一整行代码。到了Linux命令行里,rm -rf * 的“”又变成了通配符,代表所有文件(这个命令也很危险,千万别乱敲)。在Python里,def func(args) 的“*”又成了魔法棒,允许你传入任意数量的参数。
从数学运算到内存管理,从字符串匹配到命令行操作,一个“*”包揽了无数底层逻辑。这种跨领域的符号复用,极大地降低了学习成本,也让键盘布局更为集约。相比之下,功能单一、容易混淆、输入困难的“×”,在这场竞争中,输得一点儿也不冤。
写在最后
现在,当你再次在代码里敲下那个“*”时,你看到的或许不再是一个简单的星星,而是一段计算机先驱们在极其简陋的条件下,用最低成本的符号,构建起整个数字大厦的奋斗史。
它虽然不够完美,却足够实用。它是那个时代最好的选择,也是我们今天依然在遵守的约定。下次侄女再来问我,我会告诉她:这个星星不是用来许愿的,它是用来让你写的程序,真的能实现愿望。
编程中还有哪些让你疑惑许久的“反直觉”设计?或者你遇到过哪些被符号坑惨了的血泪bug?评论区聊聊,我们一起揭开计算机世界那些习以为常的真相。