百科问答小站 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语言设计数组的时候,是让数组本身将长度信息写进内存(就像一个数组对象一样),那么,哪怕是用指针传递,也是可以依然当作数组使用的,可惜,当初并没有这么设计,于是,以后也就没有办法再修改了。




  

相关话题

  如何正确通过 C++ Primer 学习 C++? 
  C语言的设计模式有哪些? 
  为什么 Go 语言能在中国这么火? 
  指向指向指向指针的指针的指针的指针有什么用? 
  请问如何区分c语言中float和double的用法? 
  Python是不是被严重高估了? 
  C语言如何封装printf函数? 
  有什么像a=a+b;b=a-b;a=a-b;这样的算法或者知识? 
  C 语言线程间怎么通信? 
  同样是巨头的语言,为什么中国是 Go 最热的国家,而 C# 越来越少? 

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





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