【问题标题】:Why does the char pointer not get updated to NULL为什么 char 指针没有更新为 NULL
【发布时间】:2021-09-29 10:42:48
【问题描述】:

'''

void calling (char *str)
{

    str = NULL;
    
}

int main()
{
    char str2[20];
    calling(str2);

    if(str2 == NULL)
    {
        printf("null");
    }


    return 0;
}

'''

只是想知道为什么 printf 没有运行。我能不能在声明后将 char-array 指针更改为 NULL。

【问题讨论】:

    标签: arrays c pointers implicit-conversion pass-by-value


    【解决方案1】:

    为什么char指针没有更新为NULL

    错误的结论。在calling(char *str) 内部,指针str 确实更新为NULL


    只是想知道为什么 printf 没有运行。

    因为&str2[0] 不是NULL
    str2 是一个数组,而不是一个指针。使用str2 == NULLstr2 被转换为第一个数组元素的地址的类型和值。第一个数组元素(&str2[0])的地址不是NULL

    char str2[20];
    ...
    if(str2 == NULL)
    {
        printf("null");
    }
    

    我可以不将 char-array 指针在声明后更改为 NULL。

    “字符数组指针”不清楚。

    数组 char str2[20]; 中的 str2 无法更改为 NULL。数组的地址永远不会改变。

    指针 char *str ... str = NULL; 中的str 可以分配给NULL


    calling(str2); 将数组str2 转换为第一个数组元素的地址的类型和值,就像是calling(&str2[0]); 并将那个指针 传递给calling()

    void calling(char *str) 接收到该指针的副本。由于calling() 在自身内部更改了该指针副本str,它不会影响调用代码的str2 的地址。


    记住:数组不是指针。指针不是数组。

    【讨论】:

      【解决方案2】:

      对于初学者,你有一个数组

      char str2[20];
      

      str2 不是指针而是数组。数组是不可修改的左值。您不能将一个数组分配给另一个数组,例如

      char str1[20];
      char str2[20];
      
      str1 = str2;
      

      在这个函数调用中

      calling(str2);
      

      数组指示符str2 被隐式转换为指向数组第一个元素的指针并表示一个右值。您可以想象函数定义及其调用方式如下

      calling(str2);
      
      //...
      
      void calling ( /*char *str*/)
      {
          char *str = str2;
          str = NULL;
      
      }
      

      如您所见,该函数处理表达式值的副本,该值产生数组str2 的第一个元素的地址值。

      在函数中改变的是局部变量(指针)str。 main 中声明的原始数组str2 保持不变。

      即使您将通过引用传递数组,您也无法更改它。例如这个程序不会编译

      #include <stdio.h>
      
      void calling (char ( *str )[20] )
      {
      
          *str = NULL;
          
      }
      
      int main()
      {
          char str2[20];
          calling( &str2 );
      
          if(str2 == NULL)
          {
              printf("null");
          }
      
      
          return 0;
      }
      

      因为在这个声明中

          *str = NULL;
      

      你正在尝试分配一个指向数组的指针。

      【讨论】:

        【解决方案3】:

        代码中有很多问题:

        char* calling (char *str)
        {
            str = NULL;
            return str;
        }
        

        您更改了调用者看不到的str 的本地副本。 你可以让一个普通的return NULL; 具有相同的效果。

        int main()
        {
            char str2[20];
            calling(str2);
        

        如上所述,函数的参数在函数之外不受影响。 您也不会对返回值做任何事情。 NULL 值被丢弃。 此外,main 中根本没有可以更新的指针。

        你有一个数组。数组不是指针,指针也不是数组。 您永远不能为数组变量赋值,因为它代表了存储数组成员的内存位置。

        正如 cmets 中所述,您应该阅读一本好书来学习 C。 特别是关于数组、指针和将数据传入和传出函数的章节应该与您相关。

        【讨论】:

        • 所以.. 我知道当你在 c 中传递一个数组时,整个数组不会被复制,而是数组类型分解为一个指针。因为它更像是通过指针/引用传递,所以我们能够在函数调用中更改数组的值。(它不会是本地副本?)我想知道的是C如何强制执行数组分解指针与整数指针之间的区别,如果我尝试更新函数调用中指针指向的地址..!
        • 你是对的关于传递数组。仅传递指向第一个元素的指针而不是所有元素。这就是所谓的“数组衰减到一个指针”。结果,我们确实可以修改该数组中的值。如果它是您传递给函数的指针,它也将是本地副本。但是在任何一种情况下都不能修改该指针。它只影响被调用函数内部的指针。
        • 这意味着如果你想更新指针本身,你必须通过引用传递指针,即使用int **param。然后你可以更新*param=new_addr;。由于数组不是指针,因此您不能将数组传递给需要指针地址的函数。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-08
        • 1970-01-01
        • 1970-01-01
        • 2022-07-16
        • 2011-08-22
        • 2010-10-16
        相关资源
        最近更新 更多