我有这段代码:
int i = 0;
char s[12];
strcpy(s,"abracadabra");
cout << strlen(s);
while(i < strlen(s))
{
if (s[i]=='a') strcpy(s+i, s+i+1);
else i++;
}
cout << " " << s;
但我不明白为什么输出是 brcdbr
。
我认为 s+i
的意思是 s[n+i]
或类似的意思?
有人可以向我解释这是如何工作的吗?
答案 0 :(得分:0)
在您的终端输入 man strcpy
<块引用>char *strcpy(char *dest, const char *src);
<块引用>strcpy() 函数复制 src 指向的字符串, 包括终止空字节 ('\0'),到指向的缓冲区 到 dest。 字符串不能重叠,目的地 字符串 dest 必须足够大以接收副本。提防 缓冲区溢出! (请参阅错误。)
所以你正在从你的字符串中复制所有字节,
注意:正如评论中所述,摆脱“a”是一种非常低效的方式和未定义的行为,但我猜你是来这里解释s+i
的,这意味着{{1} } 甚至 &s[i]
。
阅读有关“指针算法”的更多信息
如果您想要一种有效的方式,请查看 this post
答案 1 :(得分:0)
有人可以向我解释这是如何工作的吗?
它不起作用,程序的行为是undefined。关于结果没有任何意义可言(即使在某些特定情况下看起来是正确的)。
例如,在 godbolt 上,输出不是 brcdbr
而是 brcdrr
。
那是因为使用重叠的源指针和目标指针调用 strcpy
是非法的:
C11 §7.24.2.3 strcpy 函数
strcpy 函数复制 s2 指向的字符串(包括 终止空字符)到 s1 指向的数组中。 如果 复制发生在重叠的对象之间,行为是 未定义。
(注意:C++ inherits C 标准库函数的 C 规则)
无论如何,如果您只是想知道 strcpy(s+i, s+i+1)
背后的意图,在 C++ 表达式中,数组会自动衰减到一个指针。所以 char s[12]
变成了 char* s
。然后表达式 s+i
变成指针算术 - 取 i
th 元素指向的地址 s
。相当于写&s[i]
,即取i
中s
th元素的地址。这同样适用于 s+i+1
- 它计算为指向 i+1
中的 s
th 元素的指针。 strcpy
调用的目的是将字符串 after a
的剩余部分复制到内存 are starting at a
,即,将剩余的字符向前移动一位,从而覆盖a
。
在 C++ 中更好的方法是使用 std::string
和 erase-remove idiom 从字符串中删除字符 a
:
#include <iostream>
#include <algorithm>
#include <string>
int main() {
std::string s = "abracadabra";
s.erase(std::remove(s.begin(), s.end(), 'a'), s.end());
std::cout << s << std::endl;
}
打印:
brcdbr