当 a 是数字时 while(!a) 是什么意思?

What does while(!a) mean when a is a number?

试图破译这段 C 代码:

int WaitForPacket(uint16 milliseconds, Dexcom_packet* pkt, uint8 channel) {
uint32 start = getMs();
uint8 * packet = 0;
uint32 i = 0;
uint32 seven_minutes = 420000;
int nRet = 0;
swap_channel(nChannels[channel], fOffset[channel]);

while (!milliseconds || (getMs() - start) < milliseconds) {
    i++;
    if(!(i % 60000)) {
        strobe_radio(channel);
    }
    doServices();
    if((getMs() - start) > seven_minutes) {
        killWithWatchdog();
        delayMs(2000);
    }
    blink_yellow_led();
    if (packet = radioQueueRxCurrentPacket()) {
        uint8 len = packet[0];
        fOffset[channel] += FREQEST;
        memcpy(pkt, packet, min8(len+2, sizeof(Dexcom_packet)));
        if(radioCrcPassed()) {
            if(pkt->src_addr == dex_tx_id || dex_tx_id == 0 || only_listen_for_my_transmitter == 0) {
                pkt->txId -= channel;
                radioQueueRxDoneWithPacket();
                LED_YELLOW(0);
                return 1;
            } else {
                radioQueueRxDoneWithPacket();
            }
        } else {
            radioQueueRxDoneWithPacket();
            LED_YELLOW(0);
            return 0;
        }
    }
}
LED_YELLOW(0);
return nRet;
}

代码可读性很好,我知道大部分是怎么回事(除了 uint8 * packet = 0,那不是一个空指针吗?),但我不确定是怎么回事while 循环条件中的 !milliseconds。它只是按位不是吗?那是什么意思?如果不止一位,什么时候按位不为真,什么时候为假?

 !milliseconds

相当于:

  (milliseconds == 0)

根据 ! 运算符的定义:

(C11, 6.5.3.3p5) "[...] The expression !E is equivalent to (0==E)."

在 C 中,0 为假。而任何其他数字都被评估为 true。

因此,while(!a)while( a == 0 )

相同

逻辑:

(!a) 只会在 a == 0

时产生 true

(a == 0) 只会在 a == 0 时产生 true :)

while(!a)

括号中的部分当然是逻辑语句 - 通常类似于

(a==0)

代码的工作方式是,如果逻辑为真,则赋值为 1(或至少不为零),如果为假,则赋值为 0。

所以

(1)

表示 true 并且

(0) 

表示错误

现在!反转 true 和 false - 这是一个 'not' 命令

所以

(!1)

为假且

(!0)

是真实的并且....

(!a) 

如果 a==0 则为真,如果 a<>0

则为假

符号“!”意思是 "not" 你可能已经知道了, 当你有一个表达式时,如果它有一个正值,它将被转换为布尔值 "true" else(negative or 0),它会被翻译成布尔值 "false" 现在添加 "not" 符号,每一个你都会得到相反的结果, 例如 一个> 0: !a 将为假

a<0 或 a=0: !a 将为真

在对指针进行初始化、赋值或比较时,字面值0作为空指针值。空指针值仅与自身和文字 0 进行比较。它不指向任何东西,也不能取消引用。

指针可以与指针和文字进行比较 0 并且指向同一数组的指针可以与不等式进行比较。

IFWHILE中,如果()之间的表达式是== 0(算术或空指针值)则条件为假,否则为真。

运算符 ! return 在其参数为 == 0(算术或空指针值)时为 1,否则 return 为零。类似地,关系运算符 ==<<=>>= return 在条件为真时为一,在条件为真时为零假的。

因此对于 IF (!a)WHILE (!a)!a 将等于 1 或 0;如果 a 等于零,则 WHILE(!a)WHILE(1),否则为 WHILE(0)WHILE 以非零为真,以零为假。

请注意所有其他答案如何没有明确表达表达式的值与 IFWHILE 对零值与其他值的区别,即它如何将它们解释为条件。

这与位无关。数字作为数字进行比较,指针作为指针进行比较。

PS:uint8_t * packet = 0uint8_t * 类型的变量 packet 的定义,即 "pointer to uint8_t" 根据 = 初始化(建议赋值) 到 0.

PPS: while (!milliseconds || (getMs() - start) < milliseconds) 表示,如果毫秒为 0 则循环,否则如果时间 < 毫秒则循环。所以传递 0 毫秒意味着总是循环,而不测试时间 < 毫秒;并在毫秒内传递非零值意味着循环 while time < 毫秒。 (当时间 >= seven_minutes 时调用任何一种方式 killWithWatchdog()。)