【问题标题】:What does while(!a) mean when a is a number?当 a 是数字时,while(!a) 是什么意思?
【发布时间】:2015-12-07 08:40:38
【问题描述】:

试图破译这段 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,那不是空指针吗?),但我不确定!milliseconds 发生了什么在while循环的条件下。它只是按位NOT吗?那是什么意思?什么时候按位不为真,什么时候为假,如果有多个位?

【问题讨论】:

  • 关于uint8_t * packet = 0,是的,它是一个空指针。
  • 这不是问题吗?
  • 我不太确定,空指针不是坏事吗?或者它只是指向内存中第一个位置的指针?
  • 空指针不是一件坏事,它取消引用空指针是一件坏事。这里packet指针被初始化为0只是为了给它一个已知的初始值,从程序中可以看出它后来被赋值给radioQueueRxCurrentPacket函数返回的值。
  • 啊哈,这是一个=,不是一个==。 =是赋值成功时返回true/1的函数吧?

标签: c while-loop conditional


【解决方案1】:
 !milliseconds

相当于:

  (milliseconds == 0)

根据! 运算符的定义:

(C11, 6.5.3.3p5) "[...] 表达式 !E 等价于 (0==E)。"

【讨论】:

  • 但是 == 表达式返回 0 或 1 并且 WHILE 使用 that
【解决方案2】:

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

所以,while(!a)while( a == 0 ) 相同

逻辑:

(!a) 只会在 a == 0 时返回 true

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

【讨论】:

  • 根据您的定义,while(!a)while( !(a != 0) ) 相同,即等同于 while( a == 0 )
  • @GrzegorzSzpetkowski 你是对的,修正了我的答案。
【解决方案3】:
while(!a)

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

(a==0)

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

所以

(1)

表示真实和

(0) 

表示错误

现在!颠倒真假 - 这是一个“非”命令

所以

(!1)

是假的,

(!0)

是真的并且....

(!a) 

如果 a==0 表示真,如果 a0

表示假

【讨论】:

    【解决方案4】:

    符号“!”意思是“不”,你可能已经知道了, 如果你有一个表达式,如果它有一个正值,它将被转换为布尔值“真” else(负数或 0),它会被翻译成布尔值“假” 现在添加“非”符号,每一个你都会得到相反的结果, 例如 a>0 : !a 将是错误的

    a

    【讨论】:

      【解决方案5】:

      在初始化、赋值或比较指针时,文字0 被视为空指针值。空指针值比较等于自身和文字0。它不指向任何东西,也不能被取消引用。

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

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

      运算符! 在其参数为== 0(算术或空指针值)时返回一,否则返回零。同样,关系运算符==&lt;&lt;=&gt;&gt;= 在条件为真时返回 1,在条件为假时返回 0。

      所以对于IF (!a)WHILE (!a)!a 将等于一或零;如果a 等于零,则WHILE(!a)WHILE(1),否则为WHILE(0)WHILE 将非零作为条件真,零作为条件假。

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

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

      PS:uint8_t * packet = 0uint8_t * 类型的变量packet 的定义,即“指向uint8_t 的指针”根据=(建议赋值)初始化为0

      PPS:while (!milliseconds || (getMs() - start) &lt; milliseconds) 表示,如果毫秒为 0 则循环,否则如果时间 killWithWatchdog() 都会在时间 >= 七分钟时调用。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-15
        • 2021-09-18
        • 2015-01-03
        • 2017-02-02
        • 2013-12-16
        • 1970-01-01
        • 2017-05-09
        相关资源
        最近更新 更多