}
}
数组的大小可以程序运行的时候才定义吗?
不。在数组的定义中,数组的大小必须是编译时可知的,不能是在程序运行时才可知的。例如,假设i是一个变量,你就不能用i去定义一个数组的大小:
char array[i];
有些语言支持这种定义,但C语言不支持。如果C语言支持这种定义,栈就会变得更复杂,调用函数的开销就会更大,而程序的运行速度就会明显变慢。
如果数组的大小在编译时是可知的,即使它是一个非常复杂的表达式,只要它在编译时能被计算出来,你就可以定义它。
如果你要使用一个在程序运行时才知道其大小的数组,你可以说明一个指针,并且调用malloc()或calloc()函数从堆中为这个数组分配内存空间。以下是一个拷贝传给main()函数的argv数组的例子:
例 7.15 在动行时确定大小的数组,使用了指针和malloc()
# include
# include
int
main (int argc, char* * argv)
{
char* * new_argv;
int i;
new_argv = (char* * ) calloc(argc + l, sizeof (char * ));
/ * or malloc ((argc +1) * sizeof (char * ) ) * /
printf ("allocated room for %d pointers starting at %P\n", argc +
1, new_argv);
for (i = 0;i
{
/ * make room for '\0' at end, too * /
new_argv [i]= (char* ) malloc(strlen(argv[i]) + l);
strcpy(new_argv[i], argv[i]);
printf ("allocated %d bytes for new_argv[%d] at %P",
"copied\"%s\"\n",
strlen(argv[i]) + l, i, new_argv[i], new_argv[i]) ;
}
new_ argv [argc] = NULL:
for (i = 0;i
free(new_argv[i]);
printf ("freed new_argv[%d] at %P\n" , i, new_argv[i]) ;
argv[i]=NULL;
}
free(new_argv);
printf("freed new_argv itself at %P\n",new_argv);
return 0;
}
注意:为什么例7.5在释放了new_argv数组中的每个元素之后,还要将这些元素赋值为NULL呢?这是一种在长期实践的基础上形成的习惯。在释放了
一个指针之后,你就无法再使用它原来所指向的数据了,或者说,该指针被“悬挂”起来了,它不再指向任何有用的数据。如果在释放一个指针之后立即将它赋值为
NULL,那么,即使程序再次使用该指针,程序也不会出错。当然,程序可能会间接引用这个空指针,但这种错误在调试程序时就能及时被发现。此外,
程序中可能仍然有一些该指针原来的拷贝,它们仍然指向已被释放的那部分内存空间,这种情况在C程序中是很自然的。总之,尽管上述这种习惯并不能解决所有问题,但确实有作用。
《C语言编程要点》