【问题标题】:C programming strchr returns pointerC 编程 strchr 返回指针
【发布时间】:2016-04-20 21:17:00
【问题描述】:
#include <stdio.h>
#include <string.h>

int main ()
{
   const char str[] = "http://www.tutorialspoint.com";
   const char ch = '.';
   char *ret;

   ret = strchr(str, ch);

   printf("String after |%c| is - |%s|\n", ch, ret);

   return(0);
}

此代码是从tutorialspoint 复制的。

据我了解,ret 是一个指向字符的指针。要使用指针所指向的值/内容,我会使用*ret

但是,在本例中,只需调用ret,printf() 即可打印出.tutorialspoint.com。为什么不使用*ret来获取.tutorialspoint.com,因为字符串是ret中的值,*ret可以访问?

【问题讨论】:

  • 如果字符不在字符串中,则调用未定义的行为。
  • 为了避免它,他必须使用strchrnul

标签: c string pointers printf


【解决方案1】:

查看%s 转换说明符属性。当在printf() 中使用时,它需要一个char * 类型的参数,所以它得到了。一切都很好。

引用C11 标准,第 7.21.6.1 章

s
如果不存在l 长度修饰符,则参数应为指向初始值的指针 字符类型数组的元素。280) 数组中的字符是 写到(但不包括)终止空字符。 [...]

换句话说,要使用%s 打印出字符串,您必须提供指向字符串开头的指针,即res,而不是*res

【讨论】:

    【解决方案2】:

    要使用指针所指向的值/内容,我会使用*ret

    是的,如果代码需要使用该值(仅单个字符),这很有用。但是代码想要打印 string 的内容。 string 是一个字符序列(或数组),直到并包括空字符。

    为什么不使用*ret来获取".tutorialspoint.com",因为字符串是ret中的值,*ret可以访问?

    *ret 解析为单个字符。 printf("%s", ... 需要一个指向字符序列或数组的指针。通过使用printf("|%s|\n", ret);printf()知道字符串的开头地址,然后可以打印首字符'.',然后是后续的't''u''t' , ... 直到遇到空字符。


    更好的代码会在尝试printf()之前检查ret != NULL

    ret = strchr(str, ch);
    if (ret != NULL) {
      printf("String after |%c| is - |%s|\n", ch, ret);
    }
    

    【讨论】:

      【解决方案3】:

      "因为字符串是ret中的值,通过*ret访问"

      没有。 C 中的字符串是多个以\0 结尾的字符。所以*ret 将指向many 的第一个字符。字符串没有单一值,例如在 Java 中。

      * 是取消引用运算符。*ret 将给出.,因为您使用* 访问指向的元素。 %s-printf 格式使用指向字符的指针(该指针仅由名称 ret 表示)。它一直持续到遇到终止字符\0

      Linux man(3) 中的函数strchr

      strchr() 函数返回一个指向第一次出现的指针 字符串 s 中的字符 c。

      您可以使用 while 循环手动实现它并简单地增加指针。但是,您仍然需要 %s-specifier 来打印它。或者乏味的 for 循环和对每个字符的函数调用。 效率低下。

      注意:每个for循环都是用一个while循环来表示的,所以上面提到的循环并不是固定设置的。

      【讨论】:

      • "每个 for 循环都由一个 while 循环表示" 什么意思? forwhile 循环相似,在之前/内部添加了东西,但在某些情况下,使用 while 模拟相同的行为是很棘手的,真的,为什么还要尝试呢?
      • 理论上可行
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 2014-09-02
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 2012-08-01
      • 2011-02-19
      相关资源
      最近更新 更多