打印
[嵌入式Linux]

有关C语言的问题

[复制链接]
1428|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)中,这是一个运行时空间。
在编译阶段是无法预测到运行时变化的空间的,只有常量的栈空间才能在编译时确定下来。

使用特权

评论回复
5
mj5742356| | 2014-3-3 13:30 | 只看该作者
数组的个数是一个变量,这样的话编译器不能保证数组的大小是固定不变的。程序就失去控制了啊。

使用特权

评论回复
6
maowa_2005|  楼主 | 2014-3-3 14:59 | 只看该作者
airwill 发表于 2014-3-2 15:38
可以明确的说, 各个数据段是在连接时确定的.

能否说的具体些啊

使用特权

评论回复
7
ayb_ice| | 2014-3-3 15:55 | 只看该作者
虽然是在栈里分配,但也需要知道分配多大嘛

使用特权

评论回复
8
maowa_2005|  楼主 | 2014-3-3 16:23 | 只看该作者
airwill 发表于 2014-3-2 15:38
可以明确的说, 各个数据段是在连接时确定的.

你所说的各个数据段是在连接的时候确定的,是不是指连接的时候,将多个目标文件中的相同的段进行整合啊,其实在进行连接之前,每个目标文件中都会包含代码段,数据段,BSS段等,连接的作用其实就是将这些目标文件中的相同的段进行整合,不知道我理解的对不对啊,如果我的理解是对的,那么a[n],是在栈中的,编译阶段应该没有分配栈空间吧,所以还是没理解为什么会在编译阶段报错,求解

使用特权

评论回复
9
maowa_2005|  楼主 | 2014-3-3 16:25 | 只看该作者
ayb_ice 发表于 2014-3-3 15:55
虽然是在栈里分配,但也需要知道分配多大嘛

是在栈里分配的,但是编译阶段应该不会涉及到栈空间分配吧,为什么会在编译阶段报错啊

使用特权

评论回复
10
ayb_ice| | 2014-3-3 17:00 | 只看该作者
人家编译器要产生分配空间代码,不知道多少,如何产生相关代码

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

其实很简单,就是对SP加减操作,不知道的大小,不知道加减多少

使用特权

评论回复
11
maowa_2005|  楼主 | 2014-3-3 18:01 | 只看该作者
ayb_ice 发表于 2014-3-3 17:00
人家编译器要产生分配空间代码,不知道多少,如何产生相关代码

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

有点明白了,是不是编译阶段,编译器需要给局部变量确定空间,也可以说是占位符,确定需要的栈空间,在程序运行期间,就可以根据之前确定所需要的空间,在内存的栈中进行实际的分配空间

使用特权

评论回复
12
airwill| | 2014-3-3 20:28 | 只看该作者
我只是说: 各个数据段是在连接时确定的.
另外, C编译器就是不支持这个操作, 有啥好说的. 不行那就改 C++ 吧

使用特权

评论回复
13
香水橙| | 2014-3-3 23:44 | 只看该作者
ayb_ice 发表于 2014-3-3 15:55
虽然是在栈里分配,但也需要知道分配多大嘛

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

前面我已经说了,LZ的问题是由于编译器的智能程度决定的,这个一个历史的原因,没有什么合理不合理,也不是你认为应该什么样就什么样。

使用特权

评论回复
14
dictionary| | 2014-3-5 08:25 | 只看该作者
int n = 3;
int a[n];

和  int a[3];
从语意上讲 有什么区别?

使用特权

评论回复
15
maowa_2005|  楼主 | 2014-3-5 11:16 | 只看该作者
dictionary 发表于 2014-3-5 08:25
int n = 3;
int a[n];

可以看看2楼给的解释

使用特权

评论回复
16
dictionary| | 2014-3-5 14:35 | 只看该作者
maowa_2005 发表于 2014-3-5 11:16
可以看看2楼给的解释

我是反问好么?
就算编译器能通过
int n = 3;
int a[n];
这种编程方法 说明什么 ? 只有 无聊的人才会这么做吧

使用特权

评论回复
17
qbasicljx| | 2014-3-5 15:06 | 只看该作者
int *pt=new int[n];
就好了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

76

帖子

2

粉丝