strncpy函数的循环没看懂
The loop of the strncpy function is not understood
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'[=10=]' at the end of dest.
// But I don't know how if (n) while (--n) works.
if (n) while (--n) *dest++ = '[=10=]';
return start;
}
这个循环
while (n && (*dest++ = *source++)) n--;
条件表达式中有两个子表达式。
第一个是子表达式n
,可以等价重写为n != 0
。
因此,如果 n 不等于 0,则计算第二个子表达式 (*dest++ = *source++)
,将指针源指向的字符复制到指针 [=16] 指向的目标数组的元素=].
你可以对这个子表达式进行成像
(*dest++ = *source++)
如下操作顺序
( *dest = *source++, *dest++ != '[=12=]' )
表达式的结果是被复制字符的值。因此,如果复制的字符不是终止零字符 '[=17=]'
,则子表达式的逻辑值为真。否则为假,因为等于零 ('[=18=]')
.
因此此循环要么复制 n 个字符,要么如果遇到零字符,则此零终止字符之前的所有字符包括零终止字符本身。
下一个循环向目标字符串附加零,直到表达式 --n
等于 0。
该函数在处理 n
的值时有点混淆。
但是,我想您知道 if (...) { something; }
的工作原理,如果里面只有一个语句就不需要大括号?
if (n) while (--n) *dest++ = '[=10=]';
只是一个 while
嵌套在 if
中,它与:
完全相同
if (n) {
while (--n) {
*dest++ = '[=11=]';
}
}
第一个 while
循环最多复制 n
个字符,从 source
到 dest
。此循环在 n == 0
或 (*dest++ = *source++)
计算结果为 NUL ('[=16=]'
) 时停止,这意味着已找到源字符串的末尾。
然后测试n
看是否还有预期的操作——也就是说,调用者希望复制更多的字符,但是source
字符串提前结束。第二个循环通过放置 NUL 字节来实现这一点,填充 dest
以匹配 n
.
的大小
此代码的风格决定使新手开发人员难以阅读。通过美化器快速 运行 给出了这个结果(添加了我自己的评论)。
//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 '[=10=]', indicating that we've just copied
// a '[=10=]' 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 '[=10=]' to the return string
* dest++ = '[=10=]';
}
}
return start;
}
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'[=10=]' at the end of dest.
// But I don't know how if (n) while (--n) works.
if (n) while (--n) *dest++ = '[=10=]';
return start;
}
这个循环
while (n && (*dest++ = *source++)) n--;
条件表达式中有两个子表达式。
第一个是子表达式n
,可以等价重写为n != 0
。
因此,如果 n 不等于 0,则计算第二个子表达式 (*dest++ = *source++)
,将指针源指向的字符复制到指针 [=16] 指向的目标数组的元素=].
你可以对这个子表达式进行成像
(*dest++ = *source++)
如下操作顺序
( *dest = *source++, *dest++ != '[=12=]' )
表达式的结果是被复制字符的值。因此,如果复制的字符不是终止零字符 '[=17=]'
,则子表达式的逻辑值为真。否则为假,因为等于零 ('[=18=]')
.
因此此循环要么复制 n 个字符,要么如果遇到零字符,则此零终止字符之前的所有字符包括零终止字符本身。
下一个循环向目标字符串附加零,直到表达式 --n
等于 0。
该函数在处理 n
的值时有点混淆。
但是,我想您知道 if (...) { something; }
的工作原理,如果里面只有一个语句就不需要大括号?
if (n) while (--n) *dest++ = '[=10=]';
只是一个 while
嵌套在 if
中,它与:
if (n) {
while (--n) {
*dest++ = '[=11=]';
}
}
第一个 while
循环最多复制 n
个字符,从 source
到 dest
。此循环在 n == 0
或 (*dest++ = *source++)
计算结果为 NUL ('[=16=]'
) 时停止,这意味着已找到源字符串的末尾。
然后测试n
看是否还有预期的操作——也就是说,调用者希望复制更多的字符,但是source
字符串提前结束。第二个循环通过放置 NUL 字节来实现这一点,填充 dest
以匹配 n
.
此代码的风格决定使新手开发人员难以阅读。通过美化器快速 运行 给出了这个结果(添加了我自己的评论)。
//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 '[=10=]', indicating that we've just copied
// a '[=10=]' 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 '[=10=]' to the return string
* dest++ = '[=10=]';
}
}
return start;
}