我查看了一堆问题并且看不到这个,虽然我已经确定它已经在某个地方了。所以我道歉并认为这将被关闭,但希望有人会先确认我的答案!
我认为这是正确的:
while (--len > -1 && ptr = str[len])
定义良好(未定义!)行为?我理解这一点的方式是&&是一个序列点,短路的工作方式意味着应该首先评估--len > -1
,如果它不安全则不会发生第二部分。
我不确定我在这个思考过程中是否正确。
答案 0 :(得分:5)
这是定义的行为,因为&&
是sequence point,您理解它的方式是正确的。从链接的维基百科页面:
在C [2]和C ++中,[3]序列点出现在以下地方:
在评估&&和/或(逻辑AND),|| (逻辑OR)和逗号运算符。例如,在表达式* p ++!= 0&& * q ++!= 0,在尝试访问q之前,子表达式* p ++!= 0的所有副作用都已完成。
但是,这并不能确保--len
不会导致索引超出str
的范围。如果str
是以空值终止的str
,您可以更改为:
while (--len > -1 && len < strlen(str) && ptr = str[len])
答案 1 :(得分:1)
是的,这是正确的。订单是:
len
递减len
与-1
ptr = str[len]
答案 2 :(得分:0)
如果ptr = str[len]
为false,则认为--len > -1
未执行是正确的(可能是未定义的行为,对于索引数组,len太大了,我认为它不是你的恐惧)。如果len事先是INT_MIN,那么--len
可能是一个未定义的行为(如果len是一个sanely,则再次不可能)因为带符号算术的溢出是一个未定义的行为。
答案 3 :(得分:0)
while (--len > -1 && ptr = str[len])
在len = 1的例子中(如果len是int),事情是这样的:
1) len = len-1=0
2) ptr = str[0]
2)是因为if if语句的第一部分减少了len。 那是你想要的吗?
但行为被定义,首先检查第一部分。
答案 4 :(得分:0)
这实际上没问题。这里的关键是你不是不止一次写len
。
首先你预先递减len
。然后检查len
的递减值是否至少为0.接下来,将str[len]
(使用递减的len
)分配到ptr
。最后检查ptr
是否为非null,如果是,则执行while
循环语句。
请注意,如果len
是无符号的-1
将被提升为无符号,并且循环肯定会在第一次迭代时失败。此外,即使len
已签名,如果它具有未指定的最小int值(std::numeric_limits<int>::min()
)递减。