[嵌入式Linux] 有关C语言的问题

[复制链接]
1963|16
 楼主| maowa_2005 发表于 2014-3-1 16:34 | 显示全部楼层 |阅读模式
请教一个比较古老的问题,C语言中一般不能这样定义一个数组,例如 在子函数中定义int n=3; int a[n];究其原因,有人说是编译器在编译的时候不能确定数组的大小,也就不能给数组分配空间,所以无法编译,但是数组a的空间是在栈中分配的,应该是在程序运行阶段分配和回收的啊,为什么会在编译阶段就需要确定啊,是不是对于栈的分配方式理解不对啊,还有,一个程序中的代码段,数据段,BSS段以及栈和堆都是在哪个阶段分配的(编译、汇编、链接还是执行阶段),求高手指教
香水橙 发表于 2014-3-2 12:30 | 显示全部楼层
楼主说的这个问题要从两方面看:

首先,int a[n]这一句,如果n是常数,肯定没有问题,但是你把n定义为变量,对于编译器来说,它不会对变量的数值进行任何的评估,也就是说编译器不会把int n=3与int a[n]做任何的关联,因此在处理int a[n]时编译器将报错。

其次,在某些C++的实现中,允许你这种处理,也就是说在碰到int a[n]的时候,编译器对变量n的数值进行了评估,它发现这时n的数值是一个已知值,从而用具体数值为数组分配了空间。

由此可以看到,根本原因是在编译阶段是否能够对变量的数值进行评估。我们知道C语言是60-70年代的产物,那个时候计算机的性能还很差,不能指望它非常智能,所以在语法上作了很多限制,而C++出来时计算机的性能已经大为提高,智能程度自然会高很多,限制也会少很多。
airwill 发表于 2014-3-2 15:38 | 显示全部楼层
可以明确的说, 各个数据段是在连接时确定的.
msblast 发表于 2014-3-2 20:44 | 显示全部楼层
子函数中的局部变量存储在栈(stack)中,这是一个运行时空间。
在编译阶段是无法预测到运行时变化的空间的,只有常量的栈空间才能在编译时确定下来。
mj5742356 发表于 2014-3-3 13:30 | 显示全部楼层
数组的个数是一个变量,这样的话编译器不能保证数组的大小是固定不变的。程序就失去控制了啊。
 楼主| maowa_2005 发表于 2014-3-3 14:59 | 显示全部楼层
airwill 发表于 2014-3-2 15:38
可以明确的说, 各个数据段是在连接时确定的.

能否说的具体些啊
ayb_ice 发表于 2014-3-3 15:55 | 显示全部楼层
虽然是在栈里分配,但也需要知道分配多大嘛
 楼主| maowa_2005 发表于 2014-3-3 16:23 | 显示全部楼层
airwill 发表于 2014-3-2 15:38
可以明确的说, 各个数据段是在连接时确定的.

你所说的各个数据段是在连接的时候确定的,是不是指连接的时候,将多个目标文件中的相同的段进行整合啊,其实在进行连接之前,每个目标文件中都会包含代码段,数据段,BSS段等,连接的作用其实就是将这些目标文件中的相同的段进行整合,不知道我理解的对不对啊,如果我的理解是对的,那么a[n],是在栈中的,编译阶段应该没有分配栈空间吧,所以还是没理解为什么会在编译阶段报错,求解
 楼主| maowa_2005 发表于 2014-3-3 16:25 | 显示全部楼层
ayb_ice 发表于 2014-3-3 15:55
虽然是在栈里分配,但也需要知道分配多大嘛

是在栈里分配的,但是编译阶段应该不会涉及到栈空间分配吧,为什么会在编译阶段报错啊
ayb_ice 发表于 2014-3-3 17:00 | 显示全部楼层
人家编译器要产生分配空间代码,不知道多少,如何产生相关代码

看看分配局部变量的代码你就明白了

其实很简单,就是对SP加减操作,不知道的大小,不知道加减多少
 楼主| maowa_2005 发表于 2014-3-3 18:01 | 显示全部楼层
ayb_ice 发表于 2014-3-3 17:00
人家编译器要产生分配空间代码,不知道多少,如何产生相关代码

看看分配局部变量的代码你就明白了

有点明白了,是不是编译阶段,编译器需要给局部变量确定空间,也可以说是占位符,确定需要的栈空间,在程序运行期间,就可以根据之前确定所需要的空间,在内存的栈中进行实际的分配空间
airwill 发表于 2014-3-3 20:28 | 显示全部楼层
我只是说: 各个数据段是在连接时确定的.
另外, C编译器就是不支持这个操作, 有啥好说的. 不行那就改 C++ 吧
香水橙 发表于 2014-3-3 23:44 | 显示全部楼层
ayb_ice 发表于 2014-3-3 15:55
虽然是在栈里分配,但也需要知道分配多大嘛

编译器不关心栈的分配,否则不会有栈溢出的问题。

前面我已经说了,LZ的问题是由于编译器的智能程度决定的,这个一个历史的原因,没有什么合理不合理,也不是你认为应该什么样就什么样。
dictionary 发表于 2014-3-5 08:25 | 显示全部楼层
int n = 3;
int a[n];

和  int a[3];
从语意上讲 有什么区别?
 楼主| maowa_2005 发表于 2014-3-5 11:16 | 显示全部楼层
dictionary 发表于 2014-3-5 08:25
int n = 3;
int a[n];

可以看看2楼给的解释
dictionary 发表于 2014-3-5 14:35 | 显示全部楼层
maowa_2005 发表于 2014-3-5 11:16
可以看看2楼给的解释

我是反问好么?
就算编译器能通过
int n = 3;
int a[n];
这种编程方法 说明什么 ? 只有 无聊的人才会这么做吧
qbasicljx 发表于 2014-3-5 15:06 | 显示全部楼层
int *pt=new int[n];
就好了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

76

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部