如何在C语言中通过指针获取整个字符串?

9
我刚接触C语言并正在了解指针。所以,我不明白如何通过指针获取整个字符串。如果指针只包含字符串中的第一个字符的地址,那么它如何返回整个字符串呢?
假设我们有这样的代码:char *s = "Test"; 因为它只是一个字符数组,所以它在内存中的位置如下:
字符串:T e s t \0
地址:100 101 102 103 104
所以,如果我没弄错,*s将保存100(第一个字符T的地址)。
那么当我们执行printf(s);时,为什么会在输出中得到整个字符串Test呢?
它是否扫描地址直到遇到\0,还是执行其他操作?

10
“它会扫描地址直到遇到\0吗?” 是的. (注意:这是对给定链接中的回答的简短翻译,链接提供了更多背景和相关信息。) - TypeIA
9
尽管这个问题看起来不太好,但它展示了我希望每个C语言初学者都能遵循的思考过程... - Eugene Sh.
4
看起来你已经克服了初学者常见的一个误解。char *指向单个字符,而不是字符串。然后可以找到字符串的其他字符,因为我们知道字符串中的字符占据连续的内存位置。 - M.M
3
@M.M 我刚才对打印指针感到困惑。现在我认为它的工作方式类似于这样(如果我错了,请纠正): char *s = "Test"; printf(s); printf内部的大致过程如下:while(*s!= '\0') { printf("%c", *s); s++; } - Coffemanz
1
非常正确,尽管这更接近于 puts;因为 printf 还必须检查字符串中的 % 符号。 - M.M
显示剩余2条评论
3个回答

6

如何通过指针获得整个字符串

是的,OP在评论中很好地理解了要打印字符串内容,输出从s [0]开始,直到s [i]为零。 字符串的最后一个元素,即空字符不会被打印。


注意:printf(s)不好的代码,因为printf()期望第一个参数不仅是指向字符串的指针,而且将其解释为格式。如果出现'%',后面的字符将被解释为说明符@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';
}

第一个代码片段编译可能无法看到每次迭代字符串的长度不会改变(因为字符串被更改),然后调用strlen(n) n次,每次调用需要n个操作或总共需要O(n*n)时间。第二个代码只需要n个操作,即O(n)时间。

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


1

除了逐个遍历整个字符串直到达到零,没有其他方法:

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

or

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++; } - Coffemanz
1
是的,它不使用printf,但它有一个函数可以输出字符串中的每个字符。 - 0___________
2
第二个 strlen() 多了一个。建议使用 while(*str) str++; 替换 while(*str++); - chux - Reinstate Monica
1
注意:标准的puts()最后会打印一个'\n'(并返回一个int),不同于这个puts()函数。 - chux - Reinstate Monica

1
请注意,字符串是字符数组,数组的名称对应于引用第一个元素地址的指针。
因此,当您执行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 函数的。以下是输出结果。
输出:

def ghij


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接