问题是:
以更易读的方式重写以下C代码:
while (*dst++ = *src++);
我想检查一下我是否正确理解了这一行。通过将* src分配给* dst,它检查* dst(并且,通过扩展名,* src)是否为非零(或零)值。如果非零,则执行while
主体,否则跳过它。
我的回答,基于以上理解:
*dst = *src;
while (*dst) {
[do stuff]
*dst++;
*src++;
*dst = *src;
}
我意识到两个变量的后增量位置对于真实的程序很重要,但我认为这不重要。
答案 0 :(得分:3)
是的,这正是在单行代码上完成的工作(char
与null终结符一起复制)。但是在你的代码中
*dst++;
*src++;
可以替换为
dst++;
src++;
您不必要地取消引用。
为了进一步解释,分配的值是在while条件中检查的赋值表达式的值,当转换为\0
时终止循环但\0
被复制到dst
也是。
你写的实现也会做一个检查和一个赋值,即使它是空字符串就像原始字符串一样。
是的,在你的情况下,后期增量或预增量并不重要,但在原始实现中 它确实 。
在我的意思是最后一行,++dst;++src;
与 你的 dst++;src++;
相同 案例。
但是在最初的实施中如果你已经使用了
*++dst = *++src
出于复制目的,这将是错误且毫无意义。想想它是空字符串的情况。您将访问数组索引超出范围。
while(*dst++ = *src++);
这是可读 - 实际上对于您编写的第二个代码,我必须考虑边缘情况的两倍 - 这里是简洁的简单逻辑。减少代码减少混淆。 可读性并不意味着更多代码 - 它是更易读的干净代码。
答案 1 :(得分:2)
如您所知,原始循环是用于复制以零结尾的字符串的常见C语言。任何C程序员都应该一目了然。所以在这个意义上它已经非常可读了。
修改后的版本更难理解,循环内外重复分配。
如果你想以尽可能详细的方式一步一步地写出来,同时也保持与原版完全相同的行为,我建议这一点,假设src
和dst
是{ {1}}指针。
char*
顺便提一下原来的一个问题是许多现代C编译器会对作业发出警告,这个想法可能是预期// This extra pair of curly braces keeps the `char c` local to this code
{
char c; // Change this if the type is different
do {
c = *src;
*dst = c;
src = src + 1;
dst = dst + 1;
} while( c );
}
比较的错字。您通常可以使用一组额外的括号来抑制此警告:
==
答案 2 :(得分:1)
void
print_db_row(db_row_set_t *row)
{
printf("%s", row->row1name);
printf("\t%s", row->row2name);
printf("\t%s", row->row3name);
printf("\t%s", row->row4name);
}
与
相同 *dst++;
*src++;
答案 3 :(得分:1)
通过将* src分配给* dst,它正在检查是否* dst(并且,通过扩展, * src)是非零(或零)值。如果非零,则执行while主体,否则跳过它。
这是正确的,但就这些代码的目的而言,它错过了重点。代码功能的高级描述是:将src
指向的数组的连续元素复制到dst
指向的数组的连续元素,直到值为0的元素为止复制。特别是,如果src
和dst
是指向char
的指针,那么这是strcpy()
函数的可能实现。
但是你的表征并没有描述所有代码的影响,包括将src
和dst
指针递增到复制的最后一个元素之后的一个位置。您的版本与此不符。此外,您的版本在执行指针增量方面有点奇怪,因为在执行增量之后,它无意义地取消引用新指针值并忽略结果。 那是不好的风格。
我认为有很多替代方案可读性更强,但您的教练可能正在寻找一些特定的特征。我首先要求他们想要一个不在布尔上下文中使用赋值表达式的版本。我想他们也希望看到指针取消引用和指针增量在单独的表达式中执行。这是一个具有这些特性的版本,它产生原始代码的所有副作用,并最大限度地减少代码重复:
do {
*dst = *src;
dst++;
src++;
} while (*(src - 1));
答案 4 :(得分:0)
你对循环的作用的理解是正确的,但不是你对后增量的理解,后增量的优先级高于*,所以在原始的while循环中,后增量会增加指针(返回原始值),然后取消引用将原始* src分配给原始* dest。
的那些指针我建议将其作为for循环(虽然原作已经非常惯用):
for( ; *dst = *src; ++dst, ++src)
{ }