1

我正在从 K&R 书中学习 C,在第 5 章中它显示了 strcpy() 的实现,其中涉及指针(而不是使用数组索引)。它说:

while ((*s++ = *t++) != '\0')

while (*s++ = *t++)

两者都做同样的事情,并且这!= '\0'部分不是必需的。但我不完全明白为什么。当指向该空字符的指针被取消引用时,是否'\0'等于零?

*编辑:所以如果'\0'等于零,那么这也可以吗?*

while (s[i] = t[i]) i++; 
4

5 回答 5

2

是的,'\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)。

于 2013-10-10T20:12:19.993 回答
2

两者都做同样的事情,并且这!= '\0'部分不是必需的。但我不完全明白为什么。

因为在 C 中,在需要条件表达式的地方,非 0 数字(整数和浮点值)和非NULL指针被解释为真,而零NULL被认为是假。但这与您问题的第二部分没有任何关系。

当指向该空字符的指针被取消引用时,'\0' 是否等于零?

在任何情况下,它总是等价于,。0即使你这样做void *foo = '\0';了,它也会设置fooNULL,因为整数文字零是指针的合适初始值设定项,并且它被转换为NULL。但是我不明白您为什么要询问指针,因为您只是将积分与积分进行比较(char并且int都是积分类型)。

于 2013-10-10T20:15:59.280 回答
1

如果你想要键入为 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映射的“布尔”。

于 2013-10-10T20:17:24.330 回答
0

反斜杠表示字符串中会有一些特殊情况,例如:

`\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工作原理。

于 2013-10-10T20:26:53.727 回答
0

'\0'0意思一样,所以使用前者只是语法糖。

关键是使代码更具可读性,因为我们在这里处理字符串,所以使用数字零的字符符号更加一致,用于终止 C 字符串。

如果您处理数字,则使用更好的样式0,如果您处理字符,'\0'则更好,如果您处理指针,NULL则最好。所有 3 个符号的含义相同,只是为了清楚起见。

于 2013-10-10T22:37:35.197 回答