1、聊一聊
相信大家都有看过电影,今天所分享的是其经典背景音乐,或许音乐响起你又会想起那条单纯、善良的秋田犬!今天跟大家聊聊一个有意思的话题,C中的数组下标为啥是从0开始?或者说为什么现在大部分的编程语言都会选择从0开始索引!本文将从三个方面展开这个话题。
2、话题引出
凯爷,你见过数组下标从1开始的编程语言吗?
额~ ,我想想,似乎好像matlab的数组是从1开始的。
不会吧,感觉数组用1开始的编程语言很少吧!那为什么都是从0开始呢?1开始不是很好吗?
我在有些书上看过类似的解释,从0开始设计上会方便很多,应该也有一定的历史原因吧。管那么多干嘛,怎么规定怎么用就好了呀!
确实意义倒不大,不过我还是有些好奇,毕竟我是靠C吃饭的!
bug菌,你知道数组下标为何从0开始吗?
这个问题有点难为我了,毕竟我不是语言考古学家,不过我可以跟你聊聊我的一些想法,参考一下!
1
惯性思维
从我们开始学习数数,并且用手指头开始比划着的时候,大人们就会教我们"1、2、3、4。。。。。。"一共10根手指。同样,当我们去别人家做客,然后问楼层的时候,也是第1层、第2层。。。,最多也就有个-1或者-2层,并没有说0层等等。
于是,生活中这些从1开始计数的方式顺理成章的就会让我们形成一种凡事都从1开始的惯性思维,而当我们开始学习C编程却发现数组、计数等等都是从0开始的,最开始还不怎么习惯,硬着头皮久而久之也就适应了。
其实生活中也是存在非常多从0开始标识的变量,比如下面的尺子,其测量长度就是从0开始的,同样时钟也是从零开始计时。
于是大体可以找到一丝共性,从0开始的标识方式大部分都是为了表征一种距离和偏移量,而从1开始标识则是为了表征个体数量等等。
2
简化运算与编译器
此观点应该是大部分教科书所表达的,C语言的精髓当然属于指针了,而指针的索引采用的就是一种偏移的概念。
比如我们经常使用的ptr + 4 的地址为: ptr_Addr + 4*sizeof(type),当使用指针去索引数组Array[10],则用ptr指向数组头Array,理所当然*(ptr + 4) = Array[4];也可表示为 Array + 4*sizeof(type),从而指针的偏移刚好等于数组下标。
如果Array数组从1开始标识*(ptr + 4) = Array[5];这样一方面不便于我们代码上理解,很容易忘记+1或者-1;另外一方面对于编译器解析代码还需要进行-1操作,势必会加长编译时间。
所以Array从0开始标识也是为了与指针的偏移概念对齐,可以说数组下标表征的就是偏移量,而非标识的第一个元素!
3
终极底层思想
除了C语言,现在大部分编程语言都是用0开始标识数组,比如C++,JAVA等等,这些相对后起的语言大多是为了延续着C的风格和习惯,或者是借鉴C的优点,这样一方面便于程序员更加自然的在多种编程语言中分析解决问题,另一方面为多种语言之间的相互调用、融合也会带来便利。
不过如果仅仅只是一种迁就那终将被时代所抛弃,回首看看有多少编程语言在程序员的指尖溜走,而C现在都四五十岁了,仍然保持着活力,对于数组从0开始标识当然也是容不得半点马虎的。
C语言的特色在于它可以灵活的控制底层硬件却又保持着高级语言的易用和易懂属性,所以它算是一门非常接近底层硬件的语言。
然而芯片可供程序员的控制操作大部分都是数字电路的组合,那么0/1电平,定时器的计数、系统寄存器、存储器的初始化状态值等等,均为0开始编码,既然C作为一门与底层非常亲近的语言,能够对硬件进行一种数据的抽象是一个非常自然的设计,这样就可以避免非常多用1开始标识而需要重新对齐的问题。
bug菌,第三点我真的太赞同了!
我仿佛又吹了一波C语言的牛!
3、结束语
做为一名多年的C爱好者,以上就是个人对该问题的一些理解了,最终答案还是由C语言考古队来发表吧。
好了,这里是公众号:“最后一个bug”,一个为大家打造的技术知识提升基地,如果你喜欢交流可以添加下方bug菌微信,我拉你加入公众号技术交流群。
推荐好文 点击蓝色字体即可跳转
☞【开源】bug菌把"动态数字显示"开源了!
☞【MCU】可怕,别人把我MCU固件给反汇编了!(逆向)
☞ 【程序人生】学不到东西,不想呆在这家公司了!
☞ 【C进阶】"最常见"却又"最不常用"的三个预编译