【问题标题】:What is the difference between str==NULL and str[0]=='\0' in C?C中的str==NULL和str[0]=='\0'有什么区别?
【发布时间】:2012-01-09 10:10:49
【问题描述】:

我想知道str == NULLstr[0] == '\0'的区别:

int convert_to_float(char *str, double *num)
{
    if ((str == NULL) || (str[0] == '\0'))
        return(-1);

    *num = strtod(str, (char **)NULL);
    return(0);
}

我在 Linux 上使用 gcc。

【问题讨论】:

  • @julio.alegria 我不会说这个检查与你在 Java 中的检查有太大的不同。在 Java 中我会写 if (str == null || str.isEmpty()),它与 C 中的行很相似,只是长度测试的方式不同。
  • 请注意,NULL 和 '\0' 是完全相同的东西。 两者之间的唯一区别是您是否取消引用指针。 (NULL == '\0') 返回真。
  • ...警告:“在几乎(但不是)所有系统上,”NULL 被定义为 0。C 标准不要求这是真的,并且存在深奥的系统其中 NULL != 0. NULL = (void*) 0 /* 或其他数字,但绝对是 (void*) */; 0 = (int)0; 0.0 = (浮动)0; '\0' = (char)0.
  • 第一个和第三个答案完全不正确。这是个很大的差异。一种是将指针与 NULL 指针进行比较(无处指向),另一种是由 nul 字符分隔的合法 C 字符串,其中 str 是有效指针。
  • @MichaelAnderson: NULL 可以是0(void*)0;它的大小可以是指针的大小,也可以是int 的大小。 sizeof('\0') 不能为 0;它应该与sizeof (int) 相同,因为C 字符常量的类型为int

标签: c pointers gcc cstring


【解决方案1】:

str==NULL 告诉你指针是否为 NULL。

str[0]=='\0' 告诉你字符串是否长度为零。

在该代码中,测试:

if ((str == NULL) || (str[0] == '\0'))

用于捕获它为 NULL 或长度为零的情况。


请注意,短路在这里起着关键作用:测试的重点是确保 str 是长度至少为 1 的有效 c 字符串。

  • 第二个测试 str[0] == '\0' 仅在 str 不为 NULL 时才有效。
  • 因此,第一次测试str == NULL需要在str为NULL时提前爆发。

【讨论】:

  • str[0]=='\0' tells you if the string is of zero-length. 确定?
  • 如果您要打印它,则长度为零。事实上,它可以有更多的分配空间。
  • @Mysticial 我会说是因为您说“检查字符串是否为 NULL”。这是一个指针,您描述它的方式听起来有些不清楚。我也没有投反对票。我也不知道为什么这个答案被否决了。让我为你抵消那些反对票:)
  • @Nawaz:零长度意味着strlen(str) == 0
  • @Firstrock:我不会那样说;空字节不是字符串的第一个字符,而是表示该字符串甚至没有第一个字符。可能更好的方法是解释空终止字符串的一般工作原理(不仅仅是零长度字符串)。
【解决方案2】:

重要的是要记住str 并不是真正的“字符串”,而是指针 指向存储char(字符串的一部分)的内存位置.

接下来,我们必须了解编译器如何看待所有这些项目。让我们看看它们的类型:

  • str 属于 char * 类型(字面意思是“指向 char 的指针”)
  • NULL 是一个空指针常量(至少在我的系统上是((void*)0)
  • '\0' 是一个字符常量(它实际上是 int 类型,但不用担心;它通常用于需要 char 值的上下文中)

看到char *void * 中的*?这告诉编译器这些是指针类型(这是一种奇特的说法,即这种类型的变量不保存值,它们只是指向它)。因此,当编译器看到char *str 时,它知道您可能会要求执行*strstr[0] 之类的操作(它们都做同样的事情)。我们稍后再谈。

您看,当您在 C 程序中编写 str 时,编译器知道名为“str”的变量存储在内存位置,例如 0x0001。它生成的代码转到 0x0001 并获取该值。这样,如果你做类似的事情

str + 1

然后编译器会生成如下代码:

fetch the value from where str is stored (0x0001)
add 1 to that value

我相信你知道这一点。所以现在应该很明显这行说了什么:

str == NULL

由于NULL 是一个空指针常量,该行测试str 是否是一个空指针(即,一个不指向任何东西的指针)。

所以编译器通常会生成这样的代码:

fetch the value from where str is stored
check if that value is 0

现在请记住,如果您愿意,我们告诉编译器str 实际上是一个指针类型。所以我们可以这样写:

*str

这使得编译器生成这个:

fetch the value from where str is stored
now use that value as a memory address and fetch what is stored there

因此,如果 str 保持 0x0200,那么我们将从内存地址 0x0200 中获取值。请注意,编译器并不真正关心字符串是否真的存储在那里。

(我假设您知道str[0]*str 相同。这样更容易解释发生了什么。)

那么这个怎么样?

*str == '\0'

所以那条线确实有效:

*str == (char) 0

这使得编译器生成这个:

fetch the value from where str is stored
now use that value like a memory address and fetch the char that is stored there
check if the value of that fetched char is 0

总结一下:

  • str == NULL 告诉您指针str 是否指向
  • *str == '\0' 告诉您指针str 是否指向一个空字符串(实际上,指向一个包含零的内存位置)。

(根据定义,“字符串”是“由第一个空字符终止并包括第一个空字符的连续字符序列”,因此如果字符串的第一个字符是'\0',则该字符串是空字符串.)

【讨论】:

  • 我已编辑此答案以纠正一些事实错误。特别是,字符串不是指针。
  • 虽然答案更“正确”,但现在更令人困惑。有时必须使用简化来解释概念,不是吗?
  • 抱歉,说字符串是指针并不是简化。这是不正确的。
  • 你是 100% 正确的。这是不正确的。然而,当你在声明char* s 中询问人们s 是什么时,他们会说这是一个字符串。我宁愿说“为孩子们说谎”,以便概念清晰,而不是正确。这正是我的教学方式。
  • 我再次编辑了这个答案,试图保持你原来的精神。 (顺便说一句,我可能误解了一些以前的版本并反应过度。)
【解决方案3】:

基本上

  • str == NULL 判断 str 是否为 NULL 指针
  • str[0] == '\0' 判断 str 是否为 0 长度 c 样式字符串

当你组合它们时,你正在检查它是 NULL 还是空的。这允许函数在方法开始时消除两种形式的空数据

【讨论】:

  • +1 关键字是“指针”……另一个答案不见了
  • 另外:如果 str 为 NULL ,则不能取消引用 .. 这就是为什么需要首先对 NULL 进行测试的原因。第二个测试是检查 str 指向的内存位置中的值。
  • "str[0] == '\0' 确定 str 是否是长度为 0 的 c 样式字符串" 可能会让 C 新手相信字符串的第一个字符包含字符串的长度。相反,该条件指示字符串的第一个字符为 NULL,并且由于 C 字符串约定,长度为 0。
【解决方案4】:

str == NULL 检查 str 是否为 NULL 指针(指向无处的指针)

str[0] == '\0'(如果不是 NULL 指针)检查第一个 str 元素是否为 0 值(没有字符的字符串仅以 0 结尾)

【讨论】:

    【解决方案5】:

    str==NULL 告诉你字符串是否为NULL

    *str=='\0' 告诉你字符串是否长度为零。

    注意:这个答案是在 Mystical's 15 second answer 上玩的,它有 str=='\0'。当然,前 3 或 4 分钟所做的更改并没有显示出来,他修复了它ಠ_ಠ。

    【讨论】:

      【解决方案6】:

      str == NULL 表示“str 指向内存地址零”(或系统上的任何地址为 NULL)。通常这意味着根本没有字符串。

      str[0] == '\0' 表示“str 的第一个字符是字符零”(这标志着字符串的结尾)。这意味着有一个字符串,但它是空的。想想一个空杯子与根本没有杯子;同样的想法。

      在其他语言中,您可以写成 str == nullstr == ""。它们意味着两种不同的东西。理解 C 语言的区别尤其重要,因为尝试使用 NULL 指针会使程序崩溃。

      【讨论】:

        【解决方案7】:

        str == NULL表示该字符串没有字符串的引用,因为它的指针为空(表示字符串的地址为空)。

        str[0] == '\0'-- 表示长度为0的字符串。

        如果此解释有任何错误或您仍有疑问,请告诉我。

        【讨论】:

          【解决方案8】:
          str == NULL 
          

          表示str没有指向任何地址=指针为空。

          并且str[0] == '\0' str 指向一个有效的地址,这一行检查第一个字符(即 str[0])是否是数字 0('\0' 的 ascii 值),这意味着字符串的结尾.然后字符串为空。 (str 中没有字符:第一个是结束字符)

          【讨论】:

          • 抱歉,这完全不正确。对于“短路”操作数||&&,C 要求先计算左边的操作数。
          【解决方案9】:

          1 -> str == NULL 确定 str 是否为 NULL 指针 2 -> str[0] == '\0' 判断 str 是否为长度为 0 的 c 风格字符串

          所以在这个 if ((str == NULL) || (str[0] == '\0')) OR 运算符的短路出现了,因为它确保任何一个字符串都没有指向任何东西或空字符串..

          【讨论】:

            【解决方案10】:

            它的 C# 等价物是:

            if (string.IsNullOrEmpty(str))
            {
            
            }
            

            简单的意思就是字符串是NULL还是空字符串。

            【讨论】:

              猜你喜欢
              • 2010-09-27
              • 2021-06-16
              • 2017-06-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多