按位和C编程

时间:2014-04-01 16:37:49

标签: c

我可以请一些帮助理解一下,如果是速记吗?我评论了我的想法。

//Bitwise AND not sure how it decides 32 or 0, then set board[i]    
board[i] = (randNum & 1024) ? 32 : 0;

//it the j variable j in the neighborOffset array, then mods it by 2048
//then takes that variable from the board array, then shifts 1 to 32
//then bitwise and of those 2 variables.
if(board[(i + neighborOffset[j]) % 2048] & (1 << 5))

//Not sure about this one. Can someone please explain it? 
board[i] |= ((board[i] ^ 34) && (board[i] ^ 35)) ? ( (board[i]^3) ? 0 : (1<<4)) : (1<<4);

//Not sure how it decides if it uses 'X' or ' '
putchar(board[i] ? 'X':' ');

-----------------------------------------------

我想出了这一个。

    putchar(board[i] ? 'X':' ');

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <stdlib.h>
//#include <dos.h>


int main()
{
    int board[2048] = {0};
    board[0] = 5;
    board[1] = 9;
    board[2] = 0;
    board[3] = 2;

    putchar(board[0] ? 'X':' ');
    putchar(board[1] ? 'X':' ');
    putchar(board[2] ? 'X':' ');
    putchar(board[3] ? 'X':' ');
    printf(" \n");
    return (0);

}

输出

XX X 

成功的原因是putchar返回1。 http://www.cplusplus.com/reference/cstdio/putchar/

2 个答案:

答案 0 :(得分:51)

  

不确定这个。有人可以解释一下吗?

board[i] |= ((board[i] ^ 34) && (board[i] ^ 35)) ? ( (board[i]^3) ? 0 : (1<<4)) : (1<<4);

不要问鱼,问怎么钓鱼。不要向你解释,让我教你如何向自己解释。

我现在不了解这个疯狂的代码,所以我将写下我将用来理解这段代码的过程。

我们首先通过重新格式化它来开始理解它,以便缩进为我们提供线索:

board[i] |= 
    ((board[i] ^ 34) && (board[i] ^ 35)) ? 
        ((board[i]^3) ? 
            0 : 
            (1<<4)) : 
        (1<<4);

好的,那不是更好。让我们试着通过引入两个解释变量来理解它

int original = board[i];
int result =  
    ((original ^ 34) && (original ^ 35)) ? 
        ((original ^ 3) ? 
            0 : 
            (1<<4)) : 
        (1<<4);
board[i] = original | result;

那还不是很清楚。让我们试着通过将条件表达式转换为条件语句来解决它。

int original = board[i];
int result;
if ((original ^ 34) && (original ^ 35))
{
    if (original ^ 3)
        result = 0;
    else
        result = 1 << 4;
}
else
    result = 1 << 4;

board[i] = original | result;

仍然不是很清楚,但现在我们可以注意到“if”语句的结构很奇怪:我们有两个可能的结果,其中一个必须满足所有三个条件,那么为什么我们嵌套if声明呢?重写。

int original = board[i];
int result;
if ((original ^ 34) && (original ^ 35) && (original ^ 3))
    result = 0;
else
    result = 1 << 4;
board[i] = original | result;

好的,我们现在变得更加简单了。让我们考虑这三个条件。什么

(original ^ 34) && ...

意思?那么,当且仅当结果不为零时,条件才会被认为是真的,所以让我们再引入三个解释变量并明确说明。

int original = board[i];
int result;
int condition34 = (original ^ 34) != 0;
int condition35 = (original ^ 35) != 0;
int condition3 = (original ^ 3) != 0;
if (condition34 && condition35 && condition3)
    result = 0;
else
    result = 1 << 4;
board[i] = original | result;

好的,现在让我们问自己“(x ^ y) != 0甚至意味着什么?在什么情况下这可能是假的?只有x^y为零。在x^y为零的情况下是吗?仅当xy 所有相同的位时。xy在什么情况下所有位都相同?< strong>只有它们相等。所以条件为假当且仅当操作数相等时,因此当且仅当它们不相等时才是真的。所以我们可以将其重写为:

int original = board[i];
int result;
int condition34 = (original != 34);
int condition35 = (original != 35);
int condition3 = (original != 3);
if (condition34 && condition35 && condition3)
    result = 0;
else
    result = 1 << 4;
board[i] = original | result;

现在我们到了某个地方。现在让我们看看board[i]上的操作。如果result为零,则original|result为无操作。唯一的另一种可能性是result是16.所以让我们再次重写,这次是消除 result

int original = board[i];
int condition34 = (original != 34);
int condition35 = (original != 35);
int condition3 = (original != 3);
if (condition34 && condition35 && condition3)
{ /* do nothing */ }
else
   board[i] = original | 16;

现在让我们注意到我们可以反转if并消除“无所事事”的情况:

int original = board[i];
int condition34 = (original != 34);
int condition35 = (original != 35);
int condition3 = (original != 3);
if (!(condition34 && condition35 && condition3))
   board[i] = original | 16;

现在我们可以使用

这一事实
!(a && b)

相同
!a || !b

所以:

int original = board[i];
int condition34 = (original != 34);
int condition35 = (original != 35);
int condition3 = (original != 3);
if ((!condition34) || (!condition35) || (!condition3))
   board[i] = original | 16;

但是现在我们正在反转一个看似愚蠢的不平等。将它们变为等于并消除反转。

int original = board[i];
int condition34 = (original == 34);
int condition35 = (original == 35);
int condition3 = (original == 3);
if (condition34 || condition35 || condition3)
   board[i] = original | 16;

现在让我们再次消除解释变量:

if ((board[i] == 34) || (board[i] == 35) || (board[i] == 3))
   board[i] |= 16;

你去吧。现在我们以一种可以理解的形式获得程序片段。 如果电路板位置为34,35或3,则设置16位,否则不执行任何操作。

我不知道为什么有人会想要编写原始程序片段,因为我所展示的方式更加清晰,但有时人们会编写奇怪的代码。

当您遇到无法理解的代码时,您就会这样做:将其重写为您可以理解的完全等效的代码。通过将子表达式提取为解释变量来简化复杂表达式是一种很好的技术。

答案 1 :(得分:0)

  

//按位并且不确定它如何决定32或0,然后设置板[i]
  board[i] = (randNum & 1024) ? 32 : 0;

&amp;运营商正在执行bitwise AND operation

   xxxxxxxxxxx
 & 10000000000
 --------------
   ?0000000000 

?如果数字在1024位置有1,则为1,否则为0。 如果结果为1则执行此测试,则返回anser 32,否则返回0。此if else条件是使用? ternary operator.

执行的
  

//不知道它是如何决定它是否使用'X'或''   putchar(board[i] ? 'X':' ');

这里使用?三元检查进行了类似的测试。如果board [i]的元素评估true,那么X else ' '