简体   繁体   English

C中的按位运算符

[英]Bitwise operators in C

I'm doing a project which is relevant to beautification code.Actually this programm i'm supposed to write is in C and works in same way as pretty print or index(if you're heard about them).My question is:I 've searched through the internet and found a similar code to my project but it uses bitwise operators.In which way can i modify my programm so not to use this operators?This is a code that i found through the internet..I hope someone can help me and tell me how can i get rid of these operators and instead write a code without them.Thanks a lot! 我正在做一个与美化代码有关的项目。实际上我应该写的这个程序是用C语言编写的,并且与漂亮的打印或索引(如果您听说过)的工作方式相同。我的问题是:我我在互联网上搜索后发现了与我的项目相似的代码,但是它使用按位运算符。我可以通过哪种方式修改程序,以免使用该运算符?这是我在互联网上找到的代码。可以帮助我并告诉我如何摆脱这些运算符,而无需使用它们就可以编写代码。非常感谢!

#define FLAG_PRINT          ( 1 << 0 )
#define FLAG_NEWLINE        ( 1 << 1 )
#define FLAG_TABS           ( 1 << 2 )

void print_tabs(int count)
{
  int i;
  for(i = 0; i < count; i++)
    putchar('\t');
}

int main()
{
int ch;
int fflags = 0;
int lflags = 0;
int tab = 0;
while ( (ch = getchar()) != EOF )
{
    //////////////// flag setting
    switch(ch)
    {
    case ';':
        fflags |= FLAG_PRINT;
        lflags |= FLAG_NEWLINE | FLAG_TABS;
        break;
    case '{':
        fflags |= 0 ;
        lflags |= FLAG_NEWLINE | FLAG_TABS | FLAG_PRINT;
        tab++;

        break;
    case '}':
        fflags |= FLAG_NEWLINE | FLAG_TABS;
        lflags |= FLAG_NEWLINE | FLAG_TABS | FLAG_PRINT;
        tab--;
        break;
    case ' ':
        fflags |= FLAG_PRINT;
        break;
    default:
        if(!isspace(ch))
            fflags |= FLAG_PRINT;
    }
    ////////////////////////////////////////

    /// first order flags
    if(fflags & FLAG_PRINT)
        putchar(ch);
    if(fflags & FLAG_NEWLINE)
        putchar('\n');
    if(fflags & FLAG_TABS)
        print_tabs(tab);

    // last order flags
    if(lflags & FLAG_PRINT)
        putchar(ch);
    if(lflags & FLAG_NEWLINE)
        putchar('\n');
    if(lflags & FLAG_TABS)
        print_tabs(tab);

    //reset
    fflags = 0;
    lflags = 0;
  }

return 0;
}

If all values are distinct single bits (so you never get carry), you can use '+' to achieve the effect of '|'. 如果所有值都是不同的单个位(因此您永远不会进位),则可以使用“ +”来实现“ |”的效果。

Shift can be replaced by multiplication/division by powers of two. 移位可由乘以除以二的幂来代替。

Some of the other operators are harder to replace while still doing bitwise operations. 其他一些运算符在仍然按位运算时更难替换。 You may be able to precompute, or implement your own functions using table lookup, or you might want to use something like an array rather than bit flags within an int. 您可能可以使用表查找进行预计算或实现自己的功能,或者可能要在int中使用类似数组的内容而不是位标志。

But the real-world answer is that bitwise operations exist for good reasons, and it's foolish not to use them when you need them. 但是现实的答案是按位操作是有充分理由存在的,并且在需要时不使用它们是愚蠢的。

Here are int values that are the same as the #defines at the top of the program. 这里的int值与程序顶部的#define相同。 However, the #defines are usable with more data types than the const int values 但是,与const int值相比,#defines可用于更多数据类型

#define FLAG_PRINT          ( 1 << 0 )
#define FLAG_NEWLINE        ( 1 << 1 )
#define FLAG_TABS           ( 1 << 2 )

can also be written as: 也可以写成:

const int FLAG_PRINT   = 0x01;
const int FLAG_NEWLINE = 0x02;
const int FLAG_TABS    = 0x04;

suggest, for good programing practice,
changing the names to something like:
flagPrint
flagNewline
flagTabs

Although using bits seems like the best way to do it, if you insist on not using bits, you can do it with bitfields like this: 尽管使用位似乎是最好的方法,但是如果您坚持不使用位,则可以使用以下位域来实现:

typedef union Flags {
    unsigned int allFlags;
    struct {
        unsigned int print   : 1;
        unsigned int newline : 1;
        unsigned int tabs    : 1;
    };
} Flags;

Flags fflags = {0};

// To set flags:
fflags.print   = 1;
fflags.newline = 1;

// To test a flag:
if (fflags.print) {
}

// To clear all flags:
fflags.allFlags = 0;

If you don't know anything about bitfields or unions, then do the completely simple way like this: 如果您对位域或联合一无所知,请执行以下完全简单的方法:

typedef struct Flags {
    int print;
    int newline;
    int tabs;
} Flags;

Flags fflags = {0};

// To set flags:
fflags.print   = 1;
fflags.newline = 1;

// To test a flag:
if (fflags.print) {
}

// To clear all flags:
memset(&fflags, 0, sizeof(fflags));

// Or if you never used memset:
fflags.print   = 0;
fflags.newline = 0;
fflags.tabs    = 0;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM