我正在从K& R书中学习C,在第5章中,它展示了strcpy()的实现,其中包含指针(而不是使用数组索引)。它说:
while ((*s++ = *t++) != '\0')
和
while (*s++ = *t++)
两者都做同样的事情,并且!= '\0'
部分不是必需的。但我不完全理解为什么。当指向该空字符的指针被取消引用时,'\0'
是否等于零?
* 编辑:那么如果'\0'
等于零,那么这也会有效吗? *
while (s[i] = t[i]) i++;
答案 0 :(得分: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 (*s++ = *t++);
// ^ ^
// | |
// assign then increments
// then break condition = *s (updated value at *s that is \0 at the end)
指令"*s++ = *t++
将t
处的地址值复制到s
处的地址值,然后该值在while循环中变为中断条件,因此循环运行直至找到\0
等于0
。
因此,条件表达式(*s++ = *t++)
等同于(*s++ = *t++) != '\0'
,它们都运行到*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 )最后。
答案 1 :(得分:2)
两者都做同样的事情,并且
!= '\0'
部分不是必需的。但我不完全理解为什么。
因为在C中,在期望条件表达式的地方,非0数字(整数和浮点值)和非NULL
指针被解释为真,零为NULL
被认为是假的。但这与你问题的第二部分没有任何关系。
当指向该空字符的指针被取消引用时,'\ 0'是否等于零?
在任何情况下,总是等同于0
。即使您执行void *foo = '\0';
,也会将foo
设置为NULL
,因为整数文字零是指针的合适初始值设定项,并且会转换为NULL
。但我不明白你为什么要问指针,因为你只是将积分与积分进行比较(char
和int
都是整数类型。)
答案 2 :(得分:1)
如果你想要输入为0的字符,就像在ascii 48中一样,你自然会使用'0'。
由于已经采用'0',为了指定“特殊”NUL字符,需要不同的序列。由于许多人都知道NUL等于0的二进制值,因此他们选择了'\ 0'。
所以
'\0' == 0
返回true,但
'0' == 48 // ASCII only, EBCDIC programmers need to lookup their own values ;)
也返回true
是的,有很多方法可以编写strcpy()
内部。但是,指针和数组只是代表性的等价,有时(即使没有必要)显式比较器可以防止人们关注示范性例子的错误元素。
所以,我认为,不是强迫读者理解循环会在绊倒NUL字符时终止,而是在一个条款(任何体面的编译器可能会选择远离)中写入,这使得终止显而易见。毕竟,他们真的专注于复制方面,而不是int
映射的“布尔”。
答案 3 :(得分: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
的工作方式。
答案 4 :(得分:0)
'\0'
和0
意思相同,所以使用前者只是语法糖。
关键是要使代码更具可读性,因为我们在这里处理字符串,因此使用字符符号作为数字零来更加一致,用于终止C字符串。
如果你处理数字,那么使用0
的风格会更好,如果你处理字符,'\0'
会更好,如果你处理指针,NULL
是最好的。所有3个符号的含义相同,只是为了清晰起见。