【问题标题】:Logical value of an assignment in CC中赋值的逻辑值
【发布时间】:2010-12-22 08:04:08
【问题描述】:
while (curr_data[1] != (unsigned int)NULL &&
    ((curr_ptr = (void*)curr_data[1]) || 1))

两部分问题。

从逻辑上讲,(curr_ptr = (void*)curr_data[1]) 的计算结果是什么。 TRUE?

另外,我知道它相当 hack-ish,但 while 声明合法 C 吗?我必须经过极大的扭曲才能将作业放在代码中的其他位置,所以如果我可以把它留在那里,我会非常好,但如果它太令人震惊以至于让每个人的眼球都燃烧起来,我会改变它.

【问题讨论】:

  • 我觉得你应该把这个发给“The Daily WTF”。
  • 为那些不得不读这些台词的可怜人发心,甚至可能在 6 个月后成为你
  • 嗯……流血的眼睛。是的,绝对是流血的眼睛。
  • 安迪,看看你的脸书。也许你知道这是谁的名字(对不起大家来自垃圾评论)。

标签: c coding-style logical-operators variable-assignment


【解决方案1】:

赋值是 C 中的表达式,所以你有什么工作。将; 更改为{} 意味着完全相同的事情并且更清晰,至少要进行更改。当您有更清晰的替代方案(通常是正确的)时,应避免在条件中分配,但如果在这个地方这是最清楚的,那么就使用它。

赋值的结果是被赋值的对象。 a = value 将完成分配,然后评估为 a。这用于执行a = b = 0 之类的操作。

为了进一步清理代码,不需要 void 强制转换,如果这是字符,请使用 '\0'(空字符)而不是 NULL(应该只与指针一起使用)。

【讨论】:

    【解决方案2】:

    你不必经历“大扭曲”,这完全等同于

    while (curr_data[1]) {
        curr_ptr = (void *)curr_data[1];
    

    【讨论】:

    • 不幸的是,这是 do-while 循环的一部分。
    • @Andy - 啊啊啊!在这里,我们遇到了真正的问题。我想知道为什么我们没有做任何工作就循环到最后。
    【解决方案3】:

    (curr_ptr = (void*)curr_data[1]) 将评估为 TRUE,除非它是空指针。

    假设curr_data 是一个指针数组,而您要做的是在这些指针中的第二个不为空时运行循环,同时将其值分配给curr_ptr,我会这样做:

    while ((curr_ptr = (void*)curr_data[1]) != NULL) { ... }
    

    【讨论】:

    • 哦,所以我的初始检查是多余的,那么?我最初的检查是查看 curr_data[1] 是否包含 null,但你是说这会做同样的事情?
    • 否,因为如果初始检查失败,则分配将永远不会发生(&& 具有“提前退出”语义),并且 while 循环将退出。而 || 1 将使 while 循环永远继续,如果您删除初始检查。 || 1 是多余的。
    【解决方案4】:

    回答您的问题:

    1. 如果 curr_ptr 未设置为 NULL(即 curr_data[1] 不为 0),它将评估为 true。
    2. 我认为这是合法的,但是这行代码存在更大的问题。

    无论如何,我假设您没有编写此代码,因为您正在争论将其保留还是取出。所以我想让你找出这行代码是谁写的,然后把他们介绍给一个笨重的对象。

    1. (unsigned int)NULL 太荒谬了。你为什么要这样做?这可能与写0 相同(不确定标准是否保证)。
    2. 如果curr_data[1] 被转换为指针(并且指针被转换为它),它是什么类型的数据?如果它应该将指针作为整数类型保存,则应为此使用<stdint.h> 中提供的类型intptr_tuintptr_t(如果您的编译器不支持C99,ptrdiff_t 可能是可接受的替代品)。
    3. 最后的|| 1 似乎是多余的。如果 curr_ptr = (void*)curr_data[1] 的评估结果为 false,我们就会在第一个条件下发现它。

    这可能会让人头疼,但请认真重新考虑重写这一行。它看起来像是 IOCCC 中的一个条目。

    【讨论】:

    • 哈哈,重重的钝物已经以踢门的形式被施加在此人身上。无论如何... 1. 将NULL 转换为unsigned int 可防止警告warning: assignment makes integer from pointer without a cast。我只是把它留在里面以避免重新输入一半的程序。 2. 好主意。我会看看我是否可以在不破坏太多其他内容的情况下做出改变。 3. 是的,我想知道这一点,尤其是考虑到我得到的第一反应。
    • 如果您必须在那里进行转换,请将curr_data[1] 转换为指针类型以更好地反映您将如何使用它。但是,如果它保持为 0,则将其转换为指针将产生 NULL,因此您可以轻松地执行 curr_data[1] != 0 甚至 curr_data[1] 并进行相同的逻辑检查。我个人的,希望更易读的重写:while(curr_data[1]) curr_ptr = (void *)curr_data[1];
    • 知道这是do {} while循环的一部分而工作的版本:do { ... } while(curr_ptr = (void*)curr_data[1]); 或者,如果您需要在循环结束后拥有一个非垃圾curr_ptrdo { ... } while(curr_data[1] && curr_ptr = (void*)curr_data[1]);希望这应该有效。
    猜你喜欢
    • 2011-09-26
    • 1970-01-01
    • 1970-01-01
    • 2015-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    相关资源
    最近更新 更多