在 C 中,两个假(零)可以一起为真吗?

In C, Can two false (zero)'s be true together?

本文关键字:一起 两个      更新时间:2023-10-16

我知道一个语句只有当它通过任何方法(如OR/AND)计算为真时才有效。

我不明白为什么计算机不能很好地理解这些,至少是c++。

#include <stdio.h>
#include <stdbool.h>
int main(void) {
    // your code goes here
    if(false && false)
        printf("truen");
    else
        printf("falsen");
    return 0;
}

输出:假

我知道看这段代码,你很快就会发现2为假,它将为假。

但是如果它们作为与运算符同时为假,不就等于它们为真了吗?这里没有尝试NOT操作符,只是不明白为什么两个false一起检查并且都给出相同的输出而不为真?

现在我写了更多关于这个似乎会破坏很多程序,呵呵…

我想我只是在一瞬间好奇地变成了一种不同的思维方式,我不明白为什么它不是那样工作的。

编辑:嗯,我猜我会收到一堆不喜欢的票。我猜这就是电脑的构造方式,它们没有真正的逻辑。 编辑2:

我给你们举个例子

假设你必须将一堆数据包组合在一起,而不是将太多的小数据包垃圾化。但有一个问题,如果这些小数据包太大,你将无法将它们组合在一起,只能按原样发送。但是假设你已经开始组合数据包,在这个过程中出现了一个大数据包,所以你不可能继续下去,你必须在这里退出并发送当前组合的数据包。

当跳出列表中包的循环时,问题出现了。

我试图避免有两个循环提前检查列表,以知道该做什么,并试图使其尽可能优化对我来说非常重要。

所以我进入了一个程序

if(already building a combined packet boolean   AND    current_packet->size > MAX_COMBINE_PACKET)
  break;
else
  //don't try to combine the packets just send normally.

所以在这种情况下,我还没有开始组合数据包,数据包的大小可以放入一个组合数据包中。

但是在这种情况下,无论包是否已经开始组合或尚未开始组合但仍然可以组合,它都不会尝试组合。

我想我需要把它分成更多的if语句。

编辑3:实际代码

/* pull packets from packet list into buf, and erase/free them */
static int pull_packets(packet_list_t *l, uint8_t *buf, bool cluster) {
    int bytes_placed = 0;
    int offset = 0;
    bool building_cluster = false;
    int MAX_CLUSTER_SIZE = 0xFF; //maybe make this a constant? 0xFF bytes is the payload max.
    while(l->begin() != l->end()) {
        PACKET *p = *l->begin();
        /* if you are building a cluster and the packet can't be clustered you can't send a regular packet anymore */
        /* otherwise just send it as a regular packet, ignore any clustering */
        if(building_cluster && p->len > MAX_CLUSTER_SIZE) 
            break; 
        else  //else if(!building_cluster && p->len > MAX_CLUSTER_SIZE)
            cluster = false;
        /* if theres room in the packet for cluster+cluster len+[packet] */
        if(cluster && p->len <= (MAX_PACKET - offset)) {
            if(!building_cluster) {
                //starts a new cluster packet 
                bytes_placed = build_packet( buf, "BBBX", 0x00, 0x0e, p->len, p->data, p->len);
                offset += bytes_placed;
                building_cluster = true;
                free_packet(p);
                l->erase(l->begin());
            } else {
                //appends to existing cluster packet
                bytes_placed = build_packet( &buf[offset], "BX", p->len, p->data, p->len);
                offset += bytes_placed;
                free_packet(p);
                l->erase(l->begin());
            }
        } else {
            /* can't create cluster or cluster is filled up */
            if(building_cluster) //has a previous cluster in progress
                break;
            //cluster is filled up
            bytes_placed = build_packet(buf, "X", p->data, p->len);
            free_packet(p);
            l->erase(l->begin());
            return bytes_placed;
        }
    }
    return offset;
}

编辑4:最后使用

else if(!building_cluster && p->len > MAX_CLUSTER_SIZE)

我想你可能把false && false和双重否定混淆了。当双重否定变成肯定时,它在C和c++中的表达方式是!false!0


你的问题描述和代码有点模糊,但假设你真正想要的是:

  • 如果不是合并包,但当前包太大,
    则发送当前
  • 如果在一个合并包中,但是当前包太大,
    则发送合并包,然后发送当前
  • 如果不在合并包中,但当前包很小,则
    然后断开以进行合并
  • 如果在一个合并的数据包中,但当前数据包很小,
    则中断以进行合并

假设以上是正确的,那么你只需要检查你当前的数据包是否小并且适合,否则你需要转发东西。


查看您的实际代码,您是否正在构建集群,以及当前数据包是否适合您的集群,似乎存在一些令人困惑的逻辑。您将受益于遵循简化的结构。下面的伪代码大致遵循了我最初的建议,但根据循环的实际操作方式进行了调整。

bool start = true;
while (packet = head of list of packets) {
    if (packet will fit cluster) {
        if (start) {
            initialize cluster with packet;
            start = false;
        } else {
            add packet to cluster;
        }
        remove from head;
    } else {
        if (start) {
            initialize cluster with XL packet;
            remove from head;
        }
        break;
    }
} 

逻辑和具有以下值表:

  • 真实,,true => true
  • 真实,,false => false
  • 错误,,true => false
  • 错误,,false => false

只有当两个操作数都为真时,结果才为真。事情就是这样。就是真正的逻辑。如果你不相信我,你可以读读维基上关于布尔代数的文章。它如上所述定义了'and'。

如果你想在两个操作数都是相同值的情况下求值为真(例如都是真或都是假),那么你可以使用if(a == b) ..

&&操作不是关于协议

这里的false值不是关于的否定

这里的false值是

&&操作是一个函数,定义为true && true产生true,任何其他组合产生一个值false

简而言之,a && b

的简写
a && b = f(a, b)
where
f(a, b) = { false | a = false, b = false
          { false | a = true, b = false
          { false | a = false, b = true
          { true  | a = true, b = true

&&是一个计算机操作,表示布尔值和操作。它是在布尔数系统中正式定义的,通常用布尔逻辑来研究。

这不是关于那种逻辑的。它是关于处理逻辑的。在编程语言中,当你有这样的东西:

if (false && false) { ... }

编译器在if中看到选项,因为&&。然后计算第一个,即false。从这一点来看,对下一个表达式求值就没有意义了——因为第一个表达式求值为false,所以没有必要求&&之后的表达式,因为那是一个自动的false: false &&

这就是为什么下面是正确的:

  • 真实,,true => true
  • 真实,,false => false
  • 错误,,true => false
  • 错误,,false => false

…编译器看到它的方式(也就是它停止计算的地方)是:

  • 真实,,true => true
  • 真实,,false => false
  • 错误,,[这甚至没有计算]=> false
  • 错误,,[这甚至没有计算]=> false

查看这个"真值表":

http://en.wikipedia.org/wiki/Truth_table Truth_table_for_all_binary_logical_operators

您要查找的操作可能是"exclusive NOR",即"exclusive OR"的"NOT"。在数学中,异或用一个带+的圆表示,当用于位计算时,在基于c的语言中,用^符号表示。对于"逻辑"计算,排他或可以用"不等于"运算符表示("排他或"是"等于"运算符)。