如何解决strncpy 函数的循环不理解
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'\0' at the end of dest.
// But I don't know how if (n) while (--n) works.
if (n) while (--n) *dest++ = '\0';
return start;
}
http://www.jbox.dk/sanos/source/lib/string.c.html#:38
解决方法
这个循环
while (n && (*dest++ = *source++)) n--;
在条件表达式中有两个子表达式。
第一个是子表达式 n
,可以等效地重写为 n != 0
。
因此,如果 n 不等于 0,则计算第二个子表达式 (*dest++ = *source++)
,将指针 source 指向的字符复制到指针 dest
指向的目标数组的元素.
你可以想象这个子表达式
(*dest++ = *source++)
如下操作顺序
( *dest = *source++,*dest++ != '\0' )
表达式的结果是被复制的字符的值。因此,如果复制的字符不是终止零字符 '\0'
,则子表达式的逻辑值为真。否则为假,因为等于零 ('\0')
。
所以这个循环要么复制 n 个字符,要么如果遇到一个零字符,那么这个零终止字符之前的所有字符,包括零终止字符本身。
下一个循环用零附加目标字符串,直到表达式 --n
等于 0。
该函数对于它如何处理 n
的值有点模糊。
但是,我想您知道 if (...) { something; }
的作用是什么,如果里面只有一个语句,它就不需要大括号?
if (n) while (--n) *dest++ = '\0';
只是一个嵌套在 while
中的 if
,它与以下内容完全相同:
if (n) {
while (--n) {
*dest++ = '\0';
}
}
,
第一个 while
循环最多将 n
个字符从 source
复制到 dest
。当 n == 0
或 (*dest++ = *source++)
的计算结果为 NUL ('\0'
) 时,此循环停止,这意味着已找到源字符串的结尾。
然后测试 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 '\0',indicating that we've just copied
// a '\0' 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 '\0' to the return string
* dest++ = '\0';
}
}
return start;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。