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(表达式)只要表达式的值不为零,code>就会保持循环;在本例中,直到我们写了一个值为零的字符
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 < /代码>的返回值几乎是无用的。