没有便携式方法可以检测到这一点。您必须进行指针比较,并且这些比较仅在同一对象内定义。 IE。如果两个字符串不重叠并且实际上是不同的对象,则指针比较会给出未定义的行为。
我会让标准库通过使用来处理这个问题memmove(a, b, strlen(b) + 1)
.
EDIT:
正如 Steve Jessop 在评论中指出的那样,实际上有一个便携式但slow在这种情况下检测重叠的方法。比较 b 中的每个地址与 a 的第一个和最后一个地址是否相等。等式比较==
总是被明确定义的。
所以你有这样的东西:
l = strlen(b);
isoverlap = 0;
for (i = 0; i <= l; i++)
{
if ((b + i == a) || (b + i == a + l))
{
isoverlap = 1;
break;
}
}
编辑 2:案例 2 的可视化
您有类似以下数组和指针的内容:
S t r i n g 0 _ _ _ _ _ _ _
^ ^
| |
b a
注意b + strlen(b)
结果是指向终止符 \0 的指针。从后面开始,否则你需要额外处理边缘情况。在那里设置指针是有效的,只是不能取消引用它们。
src = b + strlen(b) + 1;
dst = a + strlen(b) + 1;
S t r i n g 0 _ _ _ _ _ _ _
^ ^ ^ ^
| | | |
b a src dst
现在复制循环也复制 \0。
while (src > b)
{
src--; dst--;
*dst = *src;
}
第一步给出:
src--; dst--;
S t r i n g 0 _ _ _ _ _ _ _
^ ^ ^ ^
| | | |
b a src dst
*dst = *src;
S t r i n g 0 _ _ _ 0 _ _ _
^ ^ ^ ^
| | | |
b a src dst
依此类推,直到src
最终等于b
:
S t r i S t r i n g 0 _ _ _
^ ^
| |
b a
src dst
如果你想要它更黑客一点,你可以进一步压缩它,但我不推荐这样做:
while (src > b)
*(--dst) = *(--src);