繁体   English   中英

C语言中指针数组的默认值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM