是这样理解,恐怕LZ是在TC这类编译器上编译吧?
在开辟变量时,编译器是静态分配其值的,这个站在编译原理角度来看就很好理解。
int *num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]};
此声明语句,要对num[5]每个元素都赋值。TC这类编译器在做此工作时,是将其视作在编译期静态对待的,即他认为a[0]-a[4]都是已经开辟好的元素。
而
static int a[5]={1,3,5,7,9};
就将a[0]-a[4]都申请为静态变量,即在编译期就固定了其在内存做的位置。而如果我们将其改成
int a[5]={1,3,5,7,9};
那么a[0]-a[4]就将在main函数执行时动态开辟,那么在 int *num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]}; 时TC编译器认为找不到a[0]-a[4]所以报错。
解决方法:
你可以手动赋值,不要放在元素开辟处
main()
{
static int a[5]={1,3,5,7,9};
int *num[5];/*={&a[0],&a[1],&a[2],&a[3],&a[4]};*/
int **p;
num[0] = &a[0];
num[1] = &a[1];
num[2] = &a[2];
num[3] = &a[3];
num[4] = &a[4];
for(p=num;p<num+5;p++)
printf("%d ",**p);
printf("\n");
getch();
}
这样应该就不会报错。
通过这个例子,我们充分的可以了解到编译器在对待语句时将是个如何的处理过程。这也说明,其实TC不是标准的C89语法,而GCC编译器是严格兼容C99语言的,所以在处理类似静/动态语句时能做到绝对正确。
这也反映出语言的发展就是这样走过来,TC作为一个先辈的确为软件工程作出了巨大的贡献,可以这样说,我们后期的语言规范和理论化研究都得益于TC这类古老编译器的开创性作用。
也向安德森这样的计算机科学家致敬。