【问题标题】:How do we get the whole string by pointer in C?我们如何在 C 中通过指针获取整个字符串?
【发布时间】:2018-12-20 22:13:41
【问题描述】:

我是 C 语言的新手,我对指针越来越熟悉。所以,我不明白我们如何通过指针获取 WHOLE 字符串。 如果指针只包含字符串中第一个字符的地址,它如何返回整个字符串?

假设我们有这样的东西char *s = "Test";

因为它只是一个字符数组,所以它位于内存中的某个位置,如下所示:

字符串:T e s t \0

地址:100 101 102 103 104

所以,如果我猜对了,*s 将持有 100(第一个字符 T 的地址)。

那么为什么当我们执行printf(s); 时,我们会在输出中得到整个字符串Test

它会扫描地址直到遇到\0,还是做其他事情?

【问题讨论】:

  • "它会扫描地址直到遇到 \0 还是什么?" Yes.
  • 尽管这看起来不是一个很好的问题,但它展示了我希望每个 C 初学者都遵循的思考过程......
  • 值得+1的问题,我非常同意尤金的观点。
  • 看起来您已经克服了初学者普遍存在的误解。 char * 指向单个字符,而不是字符串。然后可以找到字符串的其他字符,因为我们知道字符串中的字符占用连续的内存位置。
  • @M.M 我只是对打印指针感到困惑。现在我认为它的工作原理是这样的(如果我错了,请纠正):char *s = "Test"; printf(s); printf 内部大约发生了什么:while(*s!= '\0') {printf("%c", *s); s++; }

标签: c string pointers


【解决方案1】:

我们如何通过指针获取整个字符串

是的,OP 在comment 中很好理解,要打印 string 内容,输出从s[0] 开始,一直持续到s[i] 为零。 字符串的最后一个元素,空字符不打印。


注意:printf(s)bad 代码 printf() 期望第一个参数不仅是指向 string 的指针,而且会解释为 格式。如果出现'%',则后面的字符将被解释为说明符@M.M。而是:

printf("%s", s);
// or
fputs(s, stdout);

  • 影响

strlen(), strcpy(), strcat() 之类的函数也会花费大量时间遍历 字符串 的长度以确定其长度。对于长字符串,这可能需要相当长的时间。

这种繁琐的字符串长度运行可能会产生严重影响。考虑s 指向一个长度为n 的字符串。

for (i=0; i<strlen(s); i++) {
  s[i] = 'x';
}

for (i=0; s[i] != '\0'; i++) {
  s[i] = 'x';
}

第一个代码sn-p编译可能看不到每次迭代字符串长度没有变化(随着字符串变化)然后调用strlen(n)n次,每次调用都采取n操作或者总计O(n*n) 时间。第二个代码只需要 n 操作 O(n) 时间。

高效的 C 代码可以识别这一点并避免重复的长度计算。

【讨论】:

    【解决方案2】:

    没有其他方法可以遍历整个字符串直到达到零:

    size_t strlen(const char *str)
    {
        size_t len = 0;
        while(*str++)
        {
            len++;
        }
        return len;
    }
    

    size_t strlen(const char *str)
    {
        const char *start = str;
        while(*str++);
        return str - start;
    }
    

    char *strcpy(char *dest, const char *src)
    {
        char *saveddest = dest;
    
        while(*src)
        {
            *dest++ = *src++;
        }
        *dest = 0;
        return saveddest;
    }
    
    void puts(const char *s)
    {
        char c;
        while((c = *s++))
            putc(c);
    }
    

    【讨论】:

    • 谢谢。这背后是什么:char *s = "Test"; printf(s); 它像这样工作吗?:while(*s!= '\0') { printf("%c", *s); s++; }
    • 是的,它不使用 printf,但它有一个函数可以输出字符串中的每个字符
    • 第二个strlen() 差一。建议while(*str++); --> while(*str) str++;
    • 注意:标准puts() 最后打印一个'\n'(并返回一个int),不像这个puts()
    【解决方案3】:

    请注意,字符串是字符数组,数组的名称对应于引用第一个元素地址的指针。

    所以当您执行 printf("%s",s) 时,这意味着您将 char 数组的第一个元素的指针传递给 printf 函数。

    printf函数会从传入的地址开始遍历数组,直到找到'\0'

    #include<stdio.h>
    int main(){
      char *s= "abcdef ghij";
      char *s2;
      s2 = &s[3];
      printf("%s",s2);
      return 0;
    }
    

    请注意我是如何将引用数组第 4 个元素的指针传递给 printf 函数的。这是输出。

    输出:

    定义 ghij

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-19
      • 2019-09-07
      • 1970-01-01
      • 1970-01-01
      • 2022-08-05
      • 1970-01-01
      • 2017-08-04
      • 1970-01-01
      相关资源
      最近更新 更多