【问题标题】:How to see if an element is null in an array in C?如何查看C中数组中的元素是否为空?
【发布时间】:2010-11-14 17:58:37
【问题描述】:

如何在 C 中检查数组中的元素是否为空?

if(array[i] == NULL) 

好像没用。

【问题讨论】:

  • 什么不起作用?那一行代码没有多大帮助。 array是什么,在哪里初始化?
  • 请定义“不起作用”的含义——它不能编译吗?运行时行为是否与您预期的不同? (也许你忘了先将数组内容初始化为 NULL?)
  • 我认为这是 cdhowie 的问题,因为我习惯了 java 一切都被初始化为 null。 C 中元素的默认初始化是什么。
  • @Alex:没什么。或者说垃圾。 C 不会为你做任何初始化,如果你也不做,那么它只是那个时间点内存中发生的任何事情。
  • 下次尝试使用memset。默认情况下不使用它,因为您可能需要在其中放置其他东西并且不需要此开销。

标签: c


【解决方案1】:

是什么意思?

在执行 C 程序时,未显式初始化的变量具有不可预测的值。

您需要将所有数组单元格设置为 NULL(或设置为 0,或设置为程序逻辑中表示为空的任何值),然后您可以按照您的方式检查它:

int *array[3] = { NULL, NULL, NULL }; // array of three "empty" pointers

...

for( i = 0; i < 3; ++ i ) {
  if( array[i] == NULL ) {
    // i-th cell is "empty"
  }
}

【讨论】:

  • +1 指出缺少初始化错误——可能是这里发生了什么。
  • int *array[3] = { NULL } 应该足以使所有数组元素无效。
  • @Uila:实际上是的,但我认为它可能不太清楚和误导,因为这只适用于将数组初始化为 0。你不能使用这样的快捷方式来初始化数组的所有元素为 1,而且NULL 可能与 0 不同。
【解决方案2】:

问题答案:

您发布的是正确的代码。

阐述:

如果它“似乎不起作用”,则问题可能不在于代码中的此位置。如果您想发布一个更完整的示例,说明您所拥有的代码的预期行为和实际行为,我们或许可以为您提供帮助。

【讨论】:

    【解决方案3】:

    假设array 确实是一个指针数组,那么提供的单行代码确实应该验证索引i 处的元素是否为NULL。

    但请注意,如果您的数组未正确初始化(即:为每个单元格提供初始值),则该数组很可能包含垃圾,并且您的条件很可能最终为假。

    【讨论】:

      【解决方案4】:

      起初我在想, “他们需要使用指针算法,所以 对象不会被自动取消引用 "[ ]" 运算符。

      然后我意识到,不... C 中的数组没有 空槽

      我的结论是,提问者是:

      1. 使用结构数组。

      2. 像使用数组一样使用它 指向结构的指针。

      peoro 的解决方案 很不错。但我建议稍微修改一下。 如果您想以懒惰/简单的方式进行操作,请将“.exists”属性添加到您的结构中。 简单并不是一件坏事,机器中的零件越多,可能出错的事情就越多。

      下面的代码演示了两件事:

      1. 使用 .exists 标志修改的 peoro 解决方案伪造一个稀疏数组

      2. 使用双指针的实际稀疏数组


      #include<stdlib.h> //:for: malloc(...)
      #include<stdlib.h> //:for:   free(...)
      #include <stdio.h> //:for: printf(...)
      int main( void ){
          printf("[BEG:main]\n");
      
          typedef struct MyStruct{
              int whatever;
          } MyStruct;
      
          int        num = 16; //:sixteen_elements
      
          //:USE CALLOC HERE! If you use malloc you'll
          //:end up with something even worse than
          //:null pointers... Pointers that point to
          //:random places in memory. 
          //:
          //: It will make your:
          //: if( arr[i] != NULL )... 
          //: look before you leap check worthless.
          MyStruct** arr =(
              calloc(
                  1 //:allocating 1 item: arr
      
                  //:Amount of memory taken up by
                  //:all 16 MyStruct pointers in array.
              ,   sizeof(MyStruct*)*num
              )
          );;
      
          //:Initialize only the EVEN slots:
          for(int i = 0; i < num; i+=2 ){
              //:Create new MyStruct in slot i,
              //:initialized with junk data.
              arr[i]= malloc(sizeof(MyStruct));
          };;
      
          //:If element not null, set it's whatever:
          for(int i = 0; i < num; i++){
              if(NULL != arr[i]){
                  arr[i] -> whatever = i;
              };;
          };;
      
          //:Loop and print to confirm:
          for(int i = 0; i < num; i++){
              if(NULL != arr[i]){
                  printf("whatever: %d\n", arr[i] -> whatever);
              };;
          };;
      
          //:ALTERNATIVELY:
          //:If we were going to use peoro's method,
          //:I would advise adding a ".exists" flag
          //:to your struct.
      
          typedef struct DoublePointersAreTooMuchWork{
              int exists;
      
              //:Because we are going to use malloc this
              //:time, we have no guarantee what this
              //:value will be. but you will probably
              //:see all of them == 0. If you set
              //: num=1000 you'll probably see a non-zero
              //: entry somewhere. But, no guarantees!
              int mystery_value;
          } MyStruct02;
      
          MyStruct02* arr2 = malloc(sizeof(MyStruct02)*num);
          for(int i = 0; i < num; i++ ){
      
              if( i%2 ){ //:evens
                  arr2[i].exists = 1;
              }else{
                  arr2[i].exists = 0;
              };;
          };;
      
          for(int i = 0; i < num; i++ ){
              if( arr2[i].exists ){
                  printf("Exists:val:%d\n", arr2[i].mystery_value);
              }else{
                  printf("[Pretend_I_Dont_Exist]\n");
              };
          }
      
          printf("[END:main]\n");
      } //[[main]____________________________________]//
      
      /** ****************************************** ***
      OUTPUT:
      [BEG:main]
      whatever: 0
      whatever: 2
      whatever: 4
      whatever: 6
      whatever: 8
      whatever: 10
      whatever: 12
      whatever: 14
      [Pretend_I_Dont_Exist]
      Exists:val:0
      [Pretend_I_Dont_Exist]
      Exists:val:0
      [Pretend_I_Dont_Exist]
      Exists:val:0
      [Pretend_I_Dont_Exist]
      Exists:val:0
      [Pretend_I_Dont_Exist]
      Exists:val:0
      [Pretend_I_Dont_Exist]
      Exists:val:0
      [Pretend_I_Dont_Exist]
      Exists:val:0
      [Pretend_I_Dont_Exist]
      Exists:val:0
      [END:main]
      *** ****************************************** **/
      

      当我在做的时候。如果要从命令行运行,请将文件命名为: “NAE.C99”,然后创建一个名为“NAE.SH”的 bash 文件并将其放入其中。 双击脚本运行它,或者使用它所在的“./NAE.SH” git bash 终端。

      ##################################################
      ############################# SC[ hkmf-strict ] ##
      ##################################################
      base_name_no_extension="NAE"
      ##################################################
      MY_COMMAND_STRING=$(cat << GCC_COMMAND_01
          gcc                                     
          -x c                                    
          -c $base_name_no_extension.C99          
          -o my_object_file.o                     
          -m64                                    
      GCC_COMMAND_01
      )                                       
      C=$MY_COMMAND_STRING  ############################
      C=$C"-Werror        " ## WarningsAreErrors      ##
      C=$C"-Wfatal-errors " ## StopAtFirstError       ##
      C=$C"-Wpedantic     " ## UseStrictISO_C         ##
      C=$C"-Wall          " ## WarnAboutAnyWeirdCode  ##
      C=$C"-Wextra        " ## "-Wall" WarningsExtra  ##
      C=$C"-std=c99       " ## VersionOf_C_ToUse      ##
      MY_COMMAND_STRING=$C  ############################
      
      echo $MY_COMMAND_STRING
           $MY_COMMAND_STRING
      
      C1=" gcc -o EXE.exe my_object_file.o "    
      C2=" ./EXE.exe                       "    
      C3=" rm my_object_file.o             "    
      C4=" rm EXE.exe                      "  
      $C1 && echo "OK:"$C1 || "FAIL:$C1"
      $C2 && echo "OK:"$C2 || "FAIL:$C2"
      $C3 && echo "OK:"$C3 || "FAIL:$C3"
      $C4 && echo "OK:"$C4 || "FAIL:$C4"
      ##################################################
      read -p "[END_OF_BUILD_SCRIPT:PressAnyKey]:"
      ##################################################
      ############################# SC[ hkmf-strict ] ##
      ##################################################
      

      顺便说一下,这是C99代码。我尝试编写它以避免任何 C99 特定功能。

      【讨论】:

        猜你喜欢
        • 2010-09-22
        • 2015-01-13
        • 2023-03-18
        • 1970-01-01
        • 1970-01-01
        • 2013-07-20
        • 2019-05-14
        • 1970-01-01
        • 2020-12-14
        相关资源
        最近更新 更多