我正在从 K&R 书中学习 C,在第 5 章中它显示了 strcpy() 的实现,其中涉及指针(而不是使用数组索引)。它说:
while ((*s++ = *t++) != '\0')
和
while (*s++ = *t++)
两者都做同样的事情,并且这!= '\0'
部分不是必需的。但我不完全明白为什么。当指向该空字符的指针被取消引用时,是否'\0'
等于零?
*编辑:所以如果'\0'
等于零,那么这也可以吗?*
while (s[i] = t[i]) i++;
我正在从 K&R 书中学习 C,在第 5 章中它显示了 strcpy() 的实现,其中涉及指针(而不是使用数组索引)。它说:
while ((*s++ = *t++) != '\0')
和
while (*s++ = *t++)
两者都做同样的事情,并且这!= '\0'
部分不是必需的。但我不完全明白为什么。当指向该空字符的指针被取消引用时,是否'\0'
等于零?
*编辑:所以如果'\0'
等于零,那么这也可以吗?*
while (s[i] = t[i]) i++;
是的,'\0'
nul char 是0
.
要理解条件表达式,请考虑以下几点:
一:因为关联赋值运算符=
是从右到左的因此表达式
a = b = c;
相当于:
a = (b = c);
在效果等价于:
b = c;
a = b;
二:指针赋值表达式:
*s++ = *t++;
相当于:
*s = *t;
t++;
s++;
三:和一个表达式:
con = *s++ = *t++;
相当于:
*s = *t;
con = *s;
t++;
s++;
四:
(*s++ = *t++) != '\0'
相当于:
*s = *t;
*s != '\0';
t++;
s++;
[答案]:
所以在第二个 while 循环中:
while (*s++ = *t++);
// ^ ^
// | |
// assign then increments
// then break condition = *s (updated value at *s that is \0 at the end)
指令将地址 by 处的值"*s++ = *t++
复制到地址 byt
处的值,s
然后该值在 while 循环中成为中断条件,因此循环运行直到\0
找到等于0
。
所以条件表达式(*s++ = *t++)
等价于 (*s++ = *t++) != '\0'
两个运行 until *s != 0
。
最后一段时间:
while (s[i] = t[i]) i++;
// ^ ^ ^
// | | increments
// assign then increments
// then break condition = s[i] (s[i] is \0 at the end)
指令s[i] = t[i]
首先将 的值复制t[i]
到s[i]
然后s[i]
使用的值作为 while 循环的中断条件,即\0
结尾为 (=0)。
两者都做同样的事情,并且这
!= '\0'
部分不是必需的。但我不完全明白为什么。
因为在 C 中,在需要条件表达式的地方,非 0 数字(整数和浮点值)和非NULL
指针被解释为真,而零NULL
被认为是假。但这与您问题的第二部分没有任何关系。
当指向该空字符的指针被取消引用时,'\0' 是否等于零?
在任何情况下,它总是等价于,。0
即使你这样做void *foo = '\0';
了,它也会设置foo
为NULL
,因为整数文字零是指针的合适初始值设定项,并且它被转换为NULL
。但是我不明白您为什么要询问指针,因为您只是将积分与积分进行比较(char
并且int
都是积分类型)。
如果你想要键入为 0 的字符,如 ascii 48,你自然会使用 '0'。
由于已经采用了“0”,因此要指定“特殊”NUL 字符,需要不同的序列。正如许多人理解 NUL 等于二进制值 0 一样,他们选择了 '\0'。
所以
'\0' == 0
返回真,但是
'0' == 48 // ASCII only, EBCDIC programmers need to lookup their own values ;)
也返回 true
是的,有很多方法可以编写strcpy()
内部代码。但是,指针和数组仅在表示上是等效的,有时(即使没有必要)显式比较器可以防止人们将注意力集中在演示示例的错误元素上。
因此,我相信,与其强迫读者理解循环将在偶然发现 NUL 字符时终止,不如他们只是在一个子句中编写(任何体面的编译器都可能会优化掉它),使终止显而易见。毕竟,他们真正关注的是复制方面,而不是int
映射的“布尔”。
反斜杠表示字符串中会有一些特殊情况,例如:
`\r` means carriage return and it is equal 13
`\n` means line feed and it is equal 10
there are more of these and in your mentioned case:
`\0` means null and is equal 0
这就是c
工作原理。
'\0'
和0
意思一样,所以使用前者只是语法糖。
关键是使代码更具可读性,因为我们在这里处理字符串,所以使用数字零的字符符号更加一致,用于终止 C 字符串。
如果您处理数字,则使用更好的样式0
,如果您处理字符,'\0'
则更好,如果您处理指针,NULL
则最好。所有 3 个符号的含义相同,只是为了清楚起见。