c++ - 一些随机的 C 问题(ascii 魔法和位运算符)

标签 c++ c bit-manipulation bitwise-operators

我正在尝试学习 C 编程,我正在研究一些源代码,但有些东西我不明白,尤其是关于位运算符。我阅读了一些关于此的网站,我对它们的作用有了一些了解,但是当我回头查看这些代码时,我无法理解它们使用的原因和方式。

我的第一个问题与按位运算符无关,而是一些 ascii 魔术:

  1. 谁能给我解释一下下面的代码是如何工作的?

    char a = 3;
    int x = a - '0';
    

    我知道这样做是为了将 char 转换为 int,但我不明白其背后的逻辑。为什么/如何运作?

  2. 现在,关于按位运算符,我真的迷失在这里。

    • 这段代码是做什么的?

      if (~pointer->intX & (1 << i)) { c++; n = i; }
      

      我在某处读到 ~ 反转位,但我看不出这条语句在做什么以及为什么要这样做。

      与此行相同:

      row.data = ~(1 << i);
      
    • 其他问题:

      if (x != a)
        {
          ret |= ROW;
        }
      

      |= 运算符到底在做什么?根据我的阅读,|= 是 OR 但我不太明白这条语句在做什么。

      有没有什么方法可以重写这段代码,使其更容易理解,从而不使用这种按位运算符?我发现它们很难理解,所以希望有人能为我指明正确的方向,让我了解它们如何更好地工作!


我现在对按位运算符有了更好的理解,整个代码现在也更有意义了。

最后一件事:如果有一种“更干净”的方式以一种更容易理解且可能不是“位级别”的方式重写此代码,显然没有人回应。有什么想法吗?

最佳答案

这会产生垃圾:

char a = 3; 
int x = a - '0';

这是不同的 - 请注意引号:

char a = '3'; 
int x = a - '0';

char数据类型存储标识字符的数字。数字 0 到 9 的字符在字符代码列表中都是相邻的,所以如果你从 '9' 的代码中减去 '0' 的代码,你会得到答案 9。所以这将变成一个数字字符代码转化为数字的整数值。

(~pointer->intX & (1 << i))

这将由 if 解释如果它非零,则声明为真。使用了三种不同的位运算符。

~ 运算符翻转数字中的所有位,所以如果 pointer->intX01101010 , 然后 ~pointer->intX将是 10010101 . (请注意,自始至终,我都在说明一个字节的内容。如果它是一个 32 位整数,我必须写出 32 位 1 和 0)。

& 运算符通过分别处理每一位来将两个数字合并为一个数字。如果两个输入位均为 1,则结果位仅为 1。因此,如果左侧为 00101001右边是00001011 ,结果将是 00001001 .

最后,<<表示左移。如果您从 00000001 开始并将其左移三位,您将得到 00001000。因此表达式 (1 << i) 产生一个值,其中第 i 位打开,其他位都关闭。

将它们放在一起,它测试位是否为 ipointer->intX 中关闭(零) .

所以你也许能弄清楚是什么~(1 << i)做。如果i4 , 括号中的内容将是 00010000 ,所以整个事情将是 11101111 .

ret |= ROW;

那个相当于:

ret = ret | ROW;

|运算符就像 &除了如果任一输入位为 1,则结果位为 1 .所以如果ret00100000ROW00000010 ,结果将是 00100010 .

关于c++ - 一些随机的 C 问题(ascii 魔法和位运算符),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/678829/

相关文章:

c++ - 顶部内存泄漏分析

java - 如何构造 JNI 调用以避免内存泄漏?

c - 我的循环在某种程度上是错误的,通过在 while 循环中使用 Y/N 选项

c - 初始化指向结构的指针数组

bit-manipulation - 如何旋转一个字中的位

c++ - 安全地将字节写入流

c++ - 在 C++ 中返回一个数组

c++ - 如何使用winapi更改标题栏图标

java - 为什么我应该总是使用 ||而不是 |和 && 而不是 &?

c - 查找具有相同设置位数的下一个更大的数字