[英]Default values for Array of Pointers in C
我对此代码感到非常困惑。 我有的是
int main(){
int *array[6];
for (int i = 0; i < 6; i++){
if (array[i]==NULL){
printf("NULL\n");
}
}
}
谁能解释我的代码为什么只打印NULL一次? 我认为这将打印NULL 6次。
因为您没有初始化array
元素。 如果未初始化,则未指定其值。
采用:
int *array[6] = {0};
将所有数组元素初始化为空指针常量。
C
(与某些其他语言相比)没有为数组成员分配默认值,因此程序输出NULL
的次数是不确定的。
根据C标准(6.7.9初始化)
10如果未自动初始化具有自动存储期限的对象,则其值不确定。 如果未明确初始化具有静态或线程存储持续时间的对象,则:— —如果具有指针类型,则将其初始化为空指针;
因此在您的程序中
int main(){
int *array[6];
for (int i = 0; i < 6; i++){
if (array[i]==NULL){
printf("NULL\n");
}
}
}
数组array
可以包含任何值。 但是,如果您将通过以下方式重写程序
int main(){
static int *array[6];
for (int i = 0; i < 6; i++){
if (array[i]==NULL){
printf("NULL\n");
}
}
}
要么
int *array[6];
int main(){
for (int i = 0; i < 6; i++){
if (array[i]==NULL){
printf("NULL\n");
}
}
}
那么该数组的所有元素将被初始化为NULL。
您得到一个且始终为一个NULL值的事实取决于堆栈的内容,该内容取决于调用main之前执行的代码,而该代码又取决于您使用的编译器/ libc以及编译选项。 但是,一旦编译完成,可以多次运行该程序,总会得到相同的值。 如其他答案中所述,这是因为您没有显式初始化数组,并且数组的作用域(对于函数而言是局部的)允许编译器将其放置在堆栈上,并在堆栈中获取调用main之前的内容。
要获得6个NULL指针,您应该显式地初始化数组( int *array[6] = {0};
)或将其设为静态或全局。
在以后的情况下,编译器会将数组放在bss节中(数据节在二进制文件中不存在,但是在调用main()函数之前由libc分配并初始化为零)。
在第一种情况下(本地数组初始化为0),编译器现在可以进行优化,因为该值是已知的,并且从未修改过,并且肯定会删除数组和测试,并只需调用printf 6次。
与其他编译器一起编译,或使用不同的优化级别(-O2,-O3)编译,将为您带来不同的结果,但每次调用之间仍保持一致(如果不一致)。
无论如何,无论初始化数组如何,都应该针对C标准进行修正:主程序必须返回一个值,并且仅在C99模式下允许'for'循环初始声明,因此应获得以下信息:
#include <stdio.h>
int main(){
int* array[6];
int i = 0;
for (i = 0; i < 6; i++) {
if (array[i] == NULL) {
printf("%d NULL\n", i);
}
}
return 0;
}
我添加了显示NULL值的位置编号的方法,以表明它始终是相同的。 您甚至可以添加else语句,并在不为NULL时打印值:
} else {
printf("%d %p\n", i, array[i]);
你会得到这样的东西:
$ ./test
0 NULL
1 0x4011cd
2 0x7f8d2fdf64c0
3 NULL
4 0x4011a0
5 0x401050
$ ./test
0 NULL
1 0x4011cd
2 0x7fa96155e4c0
3 NULL
4 0x4011a0
5 0x401050
我可以运行1000次,0、1、3、4和5的值始终相同。 仅数字2的值会更改,我认为这意味着它用于存储地址。
通过读取objdump -D的输出并分析GCC生成的代码,可以获得准确的信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.