【问题标题】:I don't understand the following C code line我不明白以下 C 代码行
【发布时间】:2010-08-26 10:04:46
【问题描述】:

我找到了以下线程:
Calculate broadcast address from ip and subnet mask 以及指向http://lpccomp.bc.ca/netmask/netmask.c 的链接

谁能解释一下下面这行,我不明白:

for ( maskbits=32 ; (mask & (1L<<(32-maskbits))) == 0 ; maskbits-- )

尤其是mask &amp; (1L&lt;&lt;(32-maskbits))

【问题讨论】:

    标签: c bit-manipulation bit-shift bitwise-operators


    【解决方案1】:

    &lt;&lt; 是bitwise left shift operator;它将值的位向左移动给定的数量。因此 1L&lt;&lt;(32-maskbits) 将值 1 向左移动 32-maskbits 次。

    &amp; 是bitwise AND operator。

    所以循环表达式mask &amp; (1L&lt;&lt;(32-maskbits)) == 0 测试mask 值内的所有位,从低到高。循环将在mask 的第一个(最低)非零位处停止,此时maskbits 将包含高于(包括)该位的位数。

    例如

    • 如果 mask == 0xFFFF mask == 0xFFFFFFFF (== binary 11111111111111111111111111111111),循环将在第一次迭代时停止,maskbits 将为 32
    • 如果 mask == 0x0001 mask == 0x00000001 (== binary 00000000000000000000000000000001),循环将在第一次迭代时再次停止,maskbits 将是 32
    • 如果 mask == 0x1000 mask == 0x01000000 (== binary 00000001000000000000000000000000),循环将在第 24 次迭代时停止,maskbits 将为 8

    【讨论】:

    • 问题:我得到按位与运算来检查何时停止位计数,我不明白为什么要使用长整数左移。 1 还不够吗?
    • @dierre,以避免整数溢出。在某些平台上,int 只有 16 位长,如果您将任何int 值左移超过 16,则结果未定义(可以为 0)。将值声明为 long 可确保其长度至少为 32 位。
    • 还有一个问题:我对“1L”的说法有点困惑。它到底是什么?
    • @mspoerr:这是一个长整数。阅读以上彼得的评论。
    • 有符号值的移位很棘手,可能导致未定义的行为。在示例中,如果 long 的宽度为 32,则对于 maskbits 的值为 1,移位读取为 1L &lt;&lt; 31,它可能是 UB。所以这里的1L 应该至少被替换为1UL 以获得掩码的unsigned long 值。更好的是使用UINT32_C(1)。
    【解决方案2】:

    【讨论】:

      【解决方案3】:

      要查看发生了什么:运行它。

      #include <stdio.h> 
      #include <iostream>
      using namespace std;
      
      char *binary (unsigned int v) {
      static char binstr[33] ;
      int i ;
      
      binstr[32] = '\0' ;
      for (i=0; i<32; i++) {
      binstr[31-i] = v & 1 ? '1' : '0' ;
      v = v / 2 ;
      }
      
      return binstr ;
      }
      
      int main(void){  
      
        unsigned long maskbits,mask;  
      
      mask = 0x01000000;
      cout << "MASK IS: " << binary(mask) << "\n";
      cout << "32 is: " << binary(32) << "\n\n";
      for ( maskbits=32 ; (mask & (1L<<(32-maskbits))) == 0 ; maskbits-- ) {
      cout << "maskbits: " << binary(maskbits) << "\n";
      cout << "\t(32-maskbits): " << binary((32-maskbits)) << "\n";
      cout << "\t1L<<(32-maskbits): " << binary((1L<<(32-maskbits))) << "\n";
      cout << "\t(mask & (1L<<(32-maskbits))): " << binary((mask & (1L<<(32-maskbits)))) << "\n\n";
      
      }
      
      cout << "\nFinal maskbits: " << maskbits;
      
      return 0;
      }
      

      http://ideone.com/eB8Kp

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-23
        • 2021-11-12
        • 1970-01-01
        • 2021-12-07
        • 2012-09-01
        • 1970-01-01
        • 2016-12-07
        • 2023-03-10
        相关资源
        最近更新 更多