【问题标题】:C - Pointer points to random valuesC - 指向随机值的指针
【发布时间】:2017-08-20 11:08:33
【问题描述】:

总的来说,我对指针感到很困惑,我不知道为什么会发生这种情况。通常,指向数组的指针只会打印出数组的值,但我不知道为什么会这样。有人可以解释原因或建议正在发生的事情吗?

char *showBits(int dec, char *buf) {
    char array[33];
    buf=array;
    unsigned int mask=1u<<31;
    int count=0;
    while (mask>0) {
        if ((dec & mask) == 0) {
            array[count]='0';
        }
        else {
            array[count]='1';
        }
        count++;
        mask=mask>>1;
    }
    return buf;
    }

期望它返回 dec 的二进制表示,但打印它会产生随机垃圾。

【问题讨论】:

  • val 没有在任何地方定义。
  • '返回 buf;'返回指向具有自动存储的本地数组的指针 - UB。
  • array 超出范围。
  • 'char *showBits(int dec, char *buf)' 传入 'buf' 是没有意义的,因为你用 'buf=array;' 覆盖它
  • 似乎还有一个问题:您也没有以空值终止字符串。

标签: c arrays pointers


【解决方案1】:

问题是您正在返回对本地数组的引用。相反,让调用者分配缓冲区。我还修复了代码中的一些其他问题:

#define MAX_BUFFER_LENGTH (sizeof(unsigned int) * CHAR_BIT + 1)

char *to_bit_string(unsigned int n, char *buf) {
    unsigned int mask = UINT_MAX - (UINT_MAX >> 1);
    char *tmp;

    for (tmp = buf; mask; mask >>= 1, tmp++) {
        *tmp = n & mask ? '1': '0';
    }

    *tmp = 0;
    return buf;
}

首先,我们在这里使用 unsigned int 而不是signed int,因为signed int 与unsigned int 一起使用时会被转换为unsigned int。其次,无符号整数可以有不同的位数;所以我们使用sizeof(unsigned int) * CHAR_BIT + 1 来获得绝对最大位数。第三,我们使用UINT_MAX - (UINT_MAX &gt;&gt; 1) 作为一种方便的方法来获取一个只设置了最高有效位的值,无论该数字有多少个值位。第四:我们使用移动指针代替索引。第五 - 我们记得以空结尾的字符串。

用法:

char the_bits[MAX_BUFFER_LENGTH];
puts(to_bit_string(0xDEADBEEF, the_bits));

输出

11011110101011011011111011101111

【讨论】:

    【解决方案2】:

    你有

    char *showBits(int dec, char *buf);
    

    并且该函数应“返回 dec 的二进制表示”。

    假设int 是 32 位,那么做

    #define INT_BITS (32) // to avoid all those magic numbers: 32, 32-1, 32+1
    

    进一步假设函数是这样调用的:

    int main(void)
    {
      int i = 42;  
      char buf[INT_BITS + 1]; // + 1 to be able to store the C-string's '0'-terminator.
    
      printf("%d = 0b%s\n", i, showBits(i, buf));
    }
    

    您可以按如下方式更改您的代码:

    char *showBits(int dec, char *buf) {
      // char array[INT_BITS + 1]; // drop this, not needed as buf provides all we need
      // buf=array; // drop this; see above
    
      unsigned int mask = (1u << (INT_BITS - 1));
      size_t count = 0; // size_t is typically used to type indexes
    
      while (mask > 0) {
        if ((dec & mask) == 0) {
          buf[count] = '0'; // operate on the buffer provided by the caller. 
        } else {
          buf[count] = '1'; // operate on the buffer provided by the caller. 
        }
    
        count++;
    
        mask >>= 1; // same as: mask = mask >> 1;
      }
    
      buf[INT_BITS] = '\0'; // '0'-terminate the char-array to make it a C-string.
    
      return buf;
    }
    

    也可以像这样使用该函数:

    int main(void)
    {
      ...
    
      showBits(i, buf);
      printf("%d = 0b%s\n", i, buf);
    }
    

    两种情况下打印的结果都应该是这样的:

    42 = 0b00000000000000000000000000101010
    

    【讨论】:

      【解决方案3】:

      稍加修改的代码 - 调用者应提供 buff 以适应字符串

      char *showBits(unsigned int dec, char *buf) {
          unsigned int mask = 1u << 31;
          int count = 0;
          while (mask>0) {
              if ((dec & mask) == 0) {
                  buf[count] = '0';
              }
              else {
                  buf[count] = '1';
              }
              count++;
              mask = mask >> 1;
          }
          buf[count] = '\0';
          return buf;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-26
        • 2015-02-13
        • 1970-01-01
        • 2021-12-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多