char *strncpy(char *dest, const char *source, size_t n) {
char *start = dest;
while (n && (*dest++ = *source++)) n--;
// I don't understand from the code below this
// I know I put' ' at the end of dest.
// But I don't know how if (n) while (--n) works.
if (n) while (--n) *dest++ = ' ';
return start;
}
http://www.jbox.dk/sanos/source/lib/string.c.html: 38
这个函数处理n
值的方式有点混乱。
但是,我想你知道if (...) { something; }
是怎么工作的,如果里面只有一条语句,它不需要大括号?
if (n) while (--n) *dest++ = ' ';
只是一个while
嵌套在if
中,它完全相同:
if (n) {
while (--n) {
*dest++ = ' ';
}
}
第一个while
循环最多将n
个字符从source
复制到dest
。当n == 0
或(*dest++ = *source++)
求值为NUL (' '
)时,该循环停止,这意味着找到了源字符串的末尾。
n
,看看是否仍然有预期的操作——也就是说,调用者期望复制更多的字符,但是source
字符串提前结束。第二个循环通过放置NUL字节,填充dest
以匹配n
的大小来实现这一点。
这个循环
while (n && (*dest++ = *source++)) n--;
在条件表达式中有两个子表达式。
第一个是子表达式n
,可以等价地像n != 0
一样重写。
因此,如果n不等于0,则计算第二个子表达式(*dest++ = *source++)
,该子表达式将指针源指向的字符复制到指针dest
指向的目标数组的元素。
你可以想象这个子表达
(*dest++ = *source++)
作为以下操作序列
( *dest = *source++, *dest++ != ' ' )
表达式的结果是被复制字符的值。因此,如果复制的字符不是终止零字符' '
,则子表达式的逻辑值为true。否则为false,因为等于0(' ')
。
所以这个循环要么复制n个字符,要么如果遇到一个零字符,那么在这个结束零的字符之前的所有字符,包括结束零的字符本身。
下一个循环在目标字符串后面添加0,直到表达式--n
等于0。
这段代码的风格决定使新开发人员很难阅读。快速运行一个美化器就会得到这个结果(加上我自己的评论)。
//takes a destination string, a source string, and a size (count) of characters to copy
char * strncpy(char * dest, const char * source, size_t n) {
//create a pointer to the start of the destination string
char * start = dest;
//run this loop until one of two things happens:
//- n hits 0, meaning we've copied the required number of characters
//- the assignment operator '=' returns ' ', indicating that we've just copied
// a ' ' into dest - this means we've hit the last character in source.
while (n && ( * dest++ = * source++)) {
n--;
}
//this checks to see if n still has leftover value - if it does, it means that
//source had fewer characters than we were asked to copy
if (n) {
//we will now go through the remaining characters and pad the returned string
while (--n) {
//add ' ' to the return string
* dest++ = ' ';
}
}
return start;
}