C++ C++;访谈功能

C++ C++;访谈功能,c++,C++,可能重复: 在一次采访中,我提出了以下问题。谁能给我解释一下吗 void question( char *s, char *t) { while (*s++ = *t++); } 将t指向s的字符串指针复制到内存中 运算符=将返回指定的值t应该指向以NULL结尾的字符串,s应该指向足够大的内存来存储该字符串 因此,while循环将在点击\0时停止,这是字符串的结尾,由t指向。在此while循环期间,t中的所有字符(不同于\0)都将复制到s中 稍微展开一点,如下所示: while( *

可能重复:

在一次采访中,我提出了以下问题。谁能给我解释一下吗

void question( char *s, char *t)
{
  while (*s++ = *t++);
}

t
指向
s
的字符串指针复制到内存中


运算符=
将返回指定的值
t
应该指向以
NULL
结尾的字符串,
s
应该指向足够大的内存来存储该字符串

因此,
while
循环将在点击
\0
时停止,这是字符串的结尾,由
t
指向。在此
while
循环期间,
t
中的所有字符(不同于
\0
)都将复制到
s


稍微展开一点,如下所示:

while( *t != '\0' ) // while the current char is not NULL
{
    *s = *t; // copy it into s
    ++s; // increment s, to point to the next byte
    ++t; // increment t, to point to the next char, that will be copied
}
*s = *t; // copy the last char of t - the '\0'

它将以null结尾的字符串
t
复制到
s
中。语义为strcpy

它在程序中引入了一个巨大的安全漏洞。在任何情况下都不要编写或使用这样的代码

如果我们分解代码,我们会得到:

  • *t++
    读取由
    t
    指向的字符,并递增
    t
    ;表达式的值是已读取的字符
  • *s++=expression
    将该字符写入
    s
    点的位置,并递增
    s
    ;表达式的值是写入的字符
  • while(表达式)就会保持循环;在本例中,直到我们写了一个值为零的字符
因此,该函数不断将字符从
t
复制到
s
,直到达到零值字符。无法判断
s
是否指向一个足够大的数组来容纳这些数据,因此通常情况下,它会写入超出数组末尾的数据,并导致未定义的行为;从没有有害影响的细微行为到崩溃,再到恶意代码的执行


只有在事先知道要复制的字符数(上限)时,才能调用此函数;如果您知道这一点,那么(通常)有比检查每个数据的值更有效的方法来复制数据。因此,您不应该(几乎)使用这个函数,也不应该使用它近似的C库函数(
strcpy


这种使用零值字符来终止字符串的用法在C语言中很常见;在C++中,通常使用<代码> STD::String 类来表示字符串更方便。在这种情况下,等效代码将是简单的<代码> s= t<代码>,它可以安全地管理字符串的内存。

他们通过在C++面试中问C问题来欺骗你。C++使用<代码> STD::String ,很少是代码> char */COD> >看,你想解释什么问题?他们可能想看看你是否读过K& R.@ FrdoVFLUW:或者他们想开始讨论缓冲区溢出、安全漏洞以及检查输入的重要性。我们永远不会知道。除了strcpy被声明为
char*strcpy(char*,constchar*)。谢谢John,但是语义-函数的作用-仍然相同-它将第二个参数指向的以null结尾的字符串复制到第一个,足够大。您的循环和紧凑的循环不一样。您的不会复制终止字符串的空字符。简洁的一款。@DavidHammen-谢谢,你说得绝对正确。同样,它也相当简单易读(但可能是糟糕的风格,因为我们讨厌
break
,它需要我们的精确):
而(1){*s=*t;if(*s==0)break;++s;++t}
。Kiril的循环和我的循环在一边,而问题中的循环在另一边,两者之间还有一个细微的区别,这在本例中并不重要,因为函数立即退出:我们离开指向nul终止符的
s
t
,而问题中的循环将它们推进过去。“只有事先知道将复制多少个字符,才能调用此函数“-错。如果你事先不知道确切的字符数,但知道一个上限,你可以使用它。@SteveJessop:是的,我想增加这个限制,但没有麻烦。我现在真的应该知道,我不能在这个网站上逃避简化。我们一直在关注,我们这些书呆子。我怀疑(但不能证明),在非常罕见的情况下,你实际上会考虑使用它,你无论如何都要“代码> STPCPY 而不是<代码> StrucP,因为来自代码> STRCPY < /代码>的返回值几乎是无用的。