百科问答小站 logo
百科问答小站 font logo



如何评价C语言让数组退化为指针的设计? 第1页

  

user avatar   bei-ji-85 网友的相关建议: 
      

我从操作系统的角度来分析一下可能的原因:

C语言最初是用来写操作系统的,所以C语言的设计应该要满足操作系统的需要:

数组:从操作系统的角度是一片连续的内存区域。
指针:一个变量,指向一个内存区域。

对于C语言来说可以有两种选择:

1. 所有东西都是指针,自然不存在退化问题;
2. 指针是指针,数组是数组,不做退化;

对于1来说,显然不现实,操作系统里有大量的结构体类型(表)的定义,比如段描述符:

如果所有东西都是指针,那么访问这一类的数据结构,定义就变得非常复杂,因为需要一个额外的空间去保存指针:

       char arr[10];     

相当于

       struct  {     char * base;     char data[10]; } arr;     

对于早期的操作系统来说,这样设计绝对是一种内存的浪费。C语言的前身B语言(BCPL)里就没有数组的概念,所有的数组都是指针,所以从B语言到C语言是一种进步,对于编写操作系统来说更加方便。

那么第2条不做退化可不可以?

这种倒是可以,数组到指针,无非就是做一次类型转换:如果被调函数要的是指针,那么就定义个指针变量转换一下就行了。

但是如果被调函数要的是数组类型,但是调用者只有指针怎么办?C语言没有办法把指针转换成数组,这时候就要发明新的语法规则了。

那么为了避免这种困难(发明新规则),就需要把所有函数形参类型都尽量声明成指针,就没有这种困难了。那么既然所有函数形参都是指针,既然数组需要一个额外的临时变量转换成指针,为什么不干脆把所有数组都直接退化成指针呢?

C语言的数组名自身是不占用存储空间的,这样的设计也是尽可能的节约内存,如果设计一种可传参的“数组数据类型”,那么可能需要额外的空间来保存信息,这样的语言是不利于编写操作系统的。

从设计一个适合操作系统开发的编程语言来说,这样的设计在当年(内存不足)的时代里,是非常合适的。

所以,个人理解是:C语言这么设计是为了适应当时的操作系统开发而做的一些取舍。


user avatar   zhang-hao-72 网友的相关建议: 
      

不想让它退化的话可以包在struct里嘛


user avatar   pansz 网友的相关建议: 
      

数组退化为指针,与参数传递的开销没有关系。

如果觉得有关系的话,思考一下为什么C++数组对象可以传指针而没有觉得开销过大?

指针跟数组的区别是数组有长度,指针没有长度。而数组退化为指针的本质是:数组它本来就是指针,换句话说「数组本来就没有记录其长度信息,所以只能是指针」。

在C语言标准中,数组的长度信息仅仅在编译期的上下文存在,运行时间无法获取一个数组的长度信息。

sizeof 它为什么是一个编译期关键字,而不是一个普通函数?因为 sizeof 的本质是让编译器查询这个变量是怎么声明的,然后根据其声明的方式来推导其长度,而这个变量本身,则并没有记录自己的长度。

而数组只有在自身的定义域,也就是定义那个数组的上下文中才可以通过编译器定位其长度。

一旦数组作为参数传递之后,要获得长度就必须依赖运行时间信息,而数组并没有在运行时间记录其长度信息,所以根本无法获取长度,它也就只能是一个指针。

所以:从编译时间的角度,数组在传递变量后退化为指针,从运行时间的角度,数组它一直都是指针,根本不存在退化,因为它根本没有记录长度信息。

换句话说,C语言数组它从来就不具备值语义,一直都是个指针,除了在当前定义域使用sizeof这个唯一例外的情况。其他情况它本来就是指针。


其实有其它设计方案可以实现更好用的数组:如果当初C语言设计数组的时候,是让数组本身将长度信息写进内存(就像一个数组对象一样),那么,哪怕是用指针传递,也是可以依然当作数组使用的,可惜,当初并没有这么设计,于是,以后也就没有办法再修改了。




  

相关话题

  为什么不少程序员认为Matlab的语言设计不优雅甚至比较丑?能否举出一些例子来说明? 
  p是char类型指针,p[1]不是指向p[0]的下一个字节吗?为什么会到0x11? 
  各个编程语言都有哪些「黑点」? 
  为什么很多新型编程语言都抛弃了 C 语言风格的 for 语句? 
  一般编程的时候,使用汇编能比使用高级语言(比如C,C++,java等)有更高的运行效率吗?高能高出多少呢? 
  C++动态二维数组如何使用智能指针? 
  一门编程语言,先将代码编译为C,再由C编译器编译为可执行文件,是否可行? 
  怎么解决TCP网络传输「粘包」问题? 
  semaphore和mutex的区别? 
  一名大二的计算机专业的学生,目前学了很多编程语言,但都学得很浅。是不是应该专攻一门感兴趣的语言? 

前一个讨论
如果让计算机不使用操作系统做服务器性能上是否会更有优势?
下一个讨论
操作系统是不是也是加载到内存中再执行的?





© 2024-12-26 - tinynew.org. All Rights Reserved.
© 2024-12-26 - tinynew.org. 保留所有权利