【问题标题】:C++ interview function [duplicate]C ++面试功能[重复]
【发布时间】:2012-08-30 06:57:04
【问题描述】:

可能重复:
How does “while(*s++ = *t++)” work?

我在面试时有以下问题。谁能给我解释一下?

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

【问题讨论】:

  • 他们在 C++ 面试中问了一个 C 问题来欺骗你 :)。 C++ 使用std::string,很少使用char *
  • 你想解释什么问题?
  • 他们可能想看看你是否读过 K&R。
  • @FredOverflow:或者他们想开始讨论缓冲区溢出、安全漏洞以及检查输入的重要性。我们永远不会知道。

标签: c++


【解决方案1】:

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

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

  • *t++读取t指向的字符,并递增t;表达式的值是读取的字符。
  • *s++ = expression 将该字符写入s 指向的位置,并递增s;表达式的值是写入的字符。
  • while (expression); 只要表达式的值非零,就会一直循环;在这种情况下,直到我们写了一个值为 0 的字符。

因此该函数不断将字符从t 复制到s,直到它到达一个零值字符。没有办法判断s 是否指向一个足够大的数组来保存这些,所以通常它会超出数组的末尾并导致未定义的行为;从没有不良影响的微妙行为到崩溃,再到执行恶意代码。

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

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

【讨论】:

  • "只有事先知道要复制多少个字符,才能调用此函数" - false。如果您事先不知道确切的字符数,但知道上限,则可以使用它。
  • @SteveJessop:是的,我想添加那个资格,但没有打扰。我现在真的应该知道,我无法摆脱对这个网站的简化。
  • 我们一直在关注,我们这些书呆子。我怀疑(但无法证明)在极少数情况下您实际上会考虑这样使用它,无论如何您都会想要stpcpy而不是strcpy,因为来自@987654336的返回值@ 几乎没用。
【解决方案2】:

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


operator= 将返回分配的值。 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'

【讨论】:

  • 你的循环和紧凑的不一样。您的不会复制终止字符串的空字符。紧凑的可以。
  • @DavidHammen - 谢谢,你完全正确。
  • 同样等价且易于阅读(但可能风格不佳,因为我们讨厌break,它想要我们的宝贝):while(1) { *s = *t; if (*s == 0) break; ++s; ++t}。在 Kiril 的循环和我的循环之间还有另一个细微的差别,另一方面,问题中的循环在这种情况下并不重要,因为函数会立即退出:我们让 st 指向 nul终止符,而问题中的循环将它们推进过去。
【解决方案3】:

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

【讨论】:

  • 除了strcpy被声明为char* strcpy(char*, const char *);
  • 谢谢约翰,但语义 - 函数的作用 - 仍然相同 - 它将第二个参数指向的以空字符结尾的字符串复制到第一个足够大的字符串中。
猜你喜欢
  • 2017-09-01
  • 2020-05-13
  • 1970-01-01
  • 2014-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多