在我正在阅读的一本书中,有一段代码:
string x;
size_t h=0;
for(const char* s=x.c_str();*s;++s)
h=(h*17)^*s;
关于此代码,我有两个问题:
*s
如何成为一个条件?这是什么意思?
"h=(h*17)^*s"
是什么意思?
感谢您的帮助!
答案 0 :(得分:16)
- 怎么可能是一个条件?这是什么意思?
醇>
这意味着“虽然s
指向的值不为零。” C字符串以空值终止,因此c_str()
返回的字符串中的最后一个字符将是空字符(\0
,由所有位零表示)。
- “h =(h * 17)^ * s”是什么意思?
醇>
它将h
乘以17
,然后将xor
与s
指向的值相乘。
答案 1 :(得分:3)
*s
检测字符串终止字符'\ 0'(h*17)^*s
就是这样说的:h乘以17和xor-ed与s指向的字符的内容。 似乎是一个简单的哈希功能。答案 2 :(得分:3)
在C(或C ++)中,任何值都可以用作“布尔”。数字值0或NULL指针表示“false”。其他任何意思都是“真实”。
此处,*s
是“s
当前指向的字符值”。如果该字符为0(不是“0
”数字,ASCII编码为48,而ASCII编码为0的字节,则循环停止)。这通常是“字符串结束”标记,因此循环在到达字符串末尾时停止。
“^
”是按位XOR运算符。左边的“*
”是一个简单的乘法,而另一个“*
”是指针取消引用操作符(即取指针s
的东西,并查看该值的值指针点)。 “=
”是作业。简而言之,h
的值乘以17,然后与s
指向的字符进行异或,结果将成为h
的新值。
答案 3 :(得分:3)
正如其他答案所解释的那样,基本答案是任何计算结果为0的表达式都会被解释为C或C ++中的“错误”条件,*s
将在s
时计算为0指针到达字符串的空终止字符('\ 0')。
您可以等效地使用表达式*s != 0
,并且一些开发人员可能会争辩说这应该是应该使用的,给出“更全面”表达更清晰的观点。无论您是否同意该意见,您都需要能够理解简洁替代方案的使用,因为它在C / C ++代码中非常常用。即使你更喜欢使用更明确的比较,你也会遇到很多这些表达。
标准中更严格的解释(由于某种原因,我觉得有必要将其纳入讨论,即使它没有真正改变或澄清任何事情。事实上,它可能会为某些人不必要地混淆事情 - 如果你不想进入这个级别的琐事,你现在点击后退按钮就绝对没有错过......):
在C中,*s
表达式是标准调用for
语句的'expression-2',而这个特定的for
语句示例正在利用标准的for
语句的定义。 for
语句被归类为'迭代语句',并且在任何迭代语句的语义中都是(6.8.5 / 4“迭代语句”):
迭代语句会导致重复执行一个称为循环体的语句 直到控制表达式比较等于0。
由于for
语句的'expression-2'部分是控制表达式,这意味着for
循环将重复执行,直到*s
比较等于0。
C ++标准对事物的定义略有不同(但结果相同)。在C ++中,for
语句是根据while
语句定义的,while
语句的条件部分控制着迭代(6.5.1 / 1“while语句” ):
直到条件的值变为
false
在C ++标准的早期,下面描述了表达式如何转换为bool
(4.12“布尔转换”):
算术,枚举,指针或指向成员类型的指针的右值可以转换为bool类型的右值。零值,空指针值或空成员指针值转换为false;任何其他值都转换为true
标准中的类似措辞(两种语言)适用于所有选择或迭代语句的控制表达式/条件。所有这些语言 - 法律都归结为这样一个事实,即如果表达式的计算结果为0,则与评估为false相同(在英语意义上,因为C没有内置的false
关键字)
这就是对这个简单概念的漫长而混乱的解释。
答案 4 :(得分:1)
答案 5 :(得分:1)
1)条件中的*s
检查*s!=NUL
2)h=(h*17)^*s
意味着将h
乘以17并使用s指向的值执行exclusive-OR
运算。
答案 6 :(得分:1)
在C和C ++中,true
和false
与非零相同,为零。因此,if (1){
下的代码将始终执行,if (-1237830){
下的代码也将执行,但if (0){
始终为false
。
同样,如果指针的值为0,则条件与false
相同,即您将退出循环。