我是C语言的新手,但是我对指针的使用已经不多了。因此,我不了解如何通过指针获取 WHOLE 字符串。 如果指针仅包含字符串中第一个字符的地址,那么它如何返回整个字符串?
假设我们有这样的char *s = "Test";
由于它只是一个字符数组,因此它位于内存中的某个位置,如下所示:
字符串:T e s t \ 0
地址:100101102103104
因此,如果我理解正确,*s
将保留100
(第一个字符T
的地址)。
那为什么当我们做printf(s);
时,会在输出中得到整个字符串Test
?
它会扫描地址直到遇到\0
还是做其他事情?
答案 0 :(得分:5)
我们如何通过指针获取整个字符串
是的,OP在comment中很好地了解到要打印 string 内容,输出从s[0]
开始并一直持续到s[i]
为零。 字符串的最后一个元素,即空字符,不会被打印。
注意:printf(s)
是坏代码,因为printf()
期望第一个参数不仅是指向 string 的指针,而且还会解释作为格式。如果发生'%'
,以下字符将被解释为指定符@M.M。相反:
printf("%s", s);
// or
fputs(s, stdout);
诸如strlen(), strcpy(), strcat()
之类的函数还花费大量时间沿着 string 的长度来确定其长度。对于长的字符串,这可能会花费大量时间。
这种繁琐的字符串长度运行会产生严重影响。考虑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
次,每次调用占用{{1 }}次操作或总计n
时间。第二个代码只需要O(n*n)
个操作O(n)时间的顺序即可。
高效的C代码可以识别这一点,并避免了重复的长度计算。
答案 1 :(得分:1)
没有其他方法可以遍历整个字符串直到达到零:
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);
}
答案 2 :(得分: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