C++编程思想上有这么一段话(P126):
=========================================================================
const可以用于集合,但编译器不能把一个集合存放在它的符号表里,所以必须分配内存。在这种情况下,const意味着“不能改变的一块存储”。然而,其值在编译时不能被使用,因为编译器在编译时不需要知道存储的内容。这样,我们不能写:
//:CONSTAG.CPP -- Constants and aggregates
const int i[]={1,2,3,4};
//!float f[i[3]];//Illegal
=========================================================================
我是这样理解这段话的,float f[i[3]];这句语句非法,是因为数组常量区别于普通常量,普通常量存放在符号表中而不是内存中,而数组常量就存放在内存中,因为它存放在内存中,所以编译器编译的时候不能知道其值,这就是我的问题所在,存放在内存中的内容编译器就不能在编译的时候知晓吗?那么下面的现象作何解释呢:
#include <iostream.h>
int max(int,int);
void main()
{
int a,b;
a=2,b=3; //C中不允许这种写法,C中可以写成int a=2,b=3;运行通过。
int i=max(a,b);//用函数来初始化变量
cout<<i<<endl;
}
int max(int a,int b)
{
return (a>b)?a:b;
}
为什么可以用函数值来初始化变量呢?函数也是存放在内存中的啊,编译的时候编译器又是怎么知道函数的值的呢,还有,不管是在C编译器上还是C++编译器上,我发现都可以用简单的表达式来初始化变量,这些该作何解释???
那段话的意思是说编译器在编译时i[3]的值它是不知道的,因此它就无法为数组f分配内存,所以float f[i[3]]是非法的。
而i=max(a,b),编译时是不知道max(a,b)的值是多少的,但因为i既然定义为int型变量而不是数组,编译器当然知道该为i分配多大的内存。
你的说法并不矛盾。:),编译器看到int i=max(a,b)时,他首先会检查max的返回值是否
能转换为int,然后再检查a,b的参数是否型别和声明的相符,当然还得检查max的实作语法,但这只限于文本方式的检查,所以变异可以通过。
还有就是如果声明float f[i[3]],这个在vc里面不能用,但在gcc里面可以。
第一个问题:
==========
首先不管你给的那段文字表达些什么意思。对于指针或都是数组之类的东西,编译器一般都不作过深入的检测,也就是说它对指针指的是什么东西,或者数组下标对应的值是些什么东西,值为什么一率不关心。
我们知道,声明一个数组,在编译期间是一定要能确定其大小的。假如像你做的那样:
float f[i[3]];
相当于:
const int size = i[ 3 ]; // size 的值在编译器间是不能确的。
float f[ size ]; // 这里要声明一个未知大小的数组。:(
你说能不错吗?关于数组的其实还可以引出其它的一些话题,譬如对象数组不能支持多态等。既然是写C++程序,我们就多用 vector 少用 数组 吧。vector 更安全
其实thinking一书的翻译有时候看着挺晕的
其实主要是分配内存的问题,我们知道分配内存时要知道变量所需的空间大小,这就是为什么我们在定义变量时要指定类型,而在定义数组时还要指定数组的大小,而且数组的size在数组定义时必须是已知的,而在
const int i[]={1,2,3,4};float f[i[3]]; 中,i[3]本身也需要在编译时给他内存空间,他的值在float f[i[3]]定义时是不被知道的。而且i[3]本身是变量,是有内存空间的,一般地,变量是不能用来当数组的size的。至于int i=max(a,b);是可行的,是因为int 已经告诉了变量i所需的空间大小了,所以没问题。
顺便说一下,thinking in c++ 中文版不怎么样,最好看原版。
有些东西就是允许得,也没什么为什么得
他允许你就这么用不就好了
你可能弄混淆了
float f[i[3]];
你在这里是定义一个float f数组
C++里明确规定在定义数组时,个数必须是常量,换句话说,就是放在符号表里的.
int i=max(a,b);//用函数来初始化变量
max返回一个int对象,在赋值是调用了拷贝构造函数,顺理成章,通过
恩,不错!
呵呵,看来你还真是一个新手哇。不要紧,只是不要钻牛角尖就好 :)
说实在的,你问得这些问题,我再也想不到怎样解释才能让你一下子明白。这样好了,我尽可能从侧面去解释,然后让你自己去整理和领悟:
1. 对 int 型这类内建型对象,用 C++ 的话来讲,也可以说有构造函数,只不过编译器有意隐藏这些东西的存在。因为受了 C 语言的影响,所以你对这样的讲法觉得不可理喻,看下面:
通常对一个 int 型变量初始化为 0,通常都会这样做: int i = 0; 对吧?其实在 C++ 中你可以用另外的写法:
int i( 0 ); // 想想它是调用什么函数来初始化的 ?
// 调用拷贝构造函数来初始化。
或者:
int i = int( ); // 想想又调用了什么函数?
// 调用了默认构造函数和赋值运算符。
所以说并不是只有类对象才有构造函数的。
2.符号表到底是什么?它在哪里呢?
唔~~~,实话实说,你是在钻牛角尖。不过就我知道的一点,随便说一下吧。其实这里所指的符号表永远也不会出现在你的程序中,而且你也不可能像想象中那样:找出符号表在哪,然后从中寻觅一些感兴趣的东西以求证自己的猜测 :) 。可以这么说,一般人是找不到这个符号表的,因为它是编译器在编译代码的过程中,从源代码中收集到的符号,经过特殊组织后而形成的一张表,编译器依赖于它来完成编译工作。所以说,它在哪,是什么样的,用得着你或我还有所有的程序员担心么?不必理会太多,知道有这么回事就行了,好吗?
最后,我建议你不要再用 thinking 系列来启程 :) good luck!