C语言 按位连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16073943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:04:11  来源:igfitidea点击:

Bitwise Concatenation

cbitwise-operators

提问by John Smith

I have the following:

我有以下几点:

char *pointer = decimal_to_binary(192) // yields 11000000
char *pointer2 = decimal_to_binary(168) // yields 10101000

I am trying to concat them into:

我试图将它们连接成:

1100000010101000

I was referencing: Concatenate binary numbers of different lengthsand am currently using:

我正在参考:连接不同长度的二进制数,目前正在使用:

unsigned long pointer3 = (*pointer << 16) | *pointer2;

which gives the output:

这给出了输出:

1100010000000000110001

What am I doing wrong?

我究竟做错了什么?

回答by Claudio

Ok, first you shouldn't initialize a pointer with an integer; the compiler will probably warn you like this:

好的,首先你不应该用整数初始化一个指针;编译器可能会像这样警告你:

warning: initialization makes pointer from integer without a cast [enabled by default]
   char* pointer1 = 0xc0;

If you're not familiar with hexadecimal notation, please refer to this; you'll see converting from binary to hex is much more straightforward than from decimal to hex, for instance.

如果你不熟悉十六进制表示法,请参考这里;例如,您会看到从二进制转换为十六进制比从十进制转换为十六进制要简单得多。

If you want to represent these 8-bit numbers you could assign them directly to unsigned charvariables, like I did down here (paste this code in a file "test.c", for example):

如果您想表示这些 8 位数字,您可以将它们直接分配给unsigned char变量,就像我在这里所做的一样(例如,将此代码粘贴到文件“test.c”中):

#include <stdio.h>

void main() {
  unsigned char num1 = 0xc0; /* Same as binary 11000000 in hex */
  unsigned char num2 = 0xa8; /* Same as binary 10101000 in hex */

  unsigned long result = (num1 << 8) | num2;
  printf("0x%x\n", result);
}

You can compile this with gcc -o test test.c, which outputs this when run: 0xc0a8(this is the same as 1100000010101000).

您可以使用 编译它gcc -o test test.c,它在运行时输出:(0xc0a8这与 1100000010101000 相同)。

If you assign the numbers to pointers like you did, you'll likely get a "segmentation fault" or "access violation" when you try to dereference them with *pointerand *pointer2, because that means you want the value stored at the pointer address, which probably doesn't lie in your program address space.

如果像您那样将数字分配给指针,当您尝试使用*pointerand取消引用它们时,您可能会遇到“分段错误”或“访问冲突” *pointer2,因为这意味着您希望将值存储在指针地址处,这可能是不在你的程序地址空间中。

Since resultis a long (32-bit), it can surely hold your 16-bit number just fine, but num1and num2have to be unsigned char, so when you left shift and OR them it doesn't make the whole thing negative - in a signed binary number the leftmost bit set to 1 means it is a negative number, so if you use a plain charinstead it will sign extend the 32-bit result so it remains negative: 0xffffffa8

由于result是长(32位),它一定能够把你的16位数字就好了,但num1num2必须unsigned char的,所以当你离开移,或将它不会使整个事情负-在一个符号二进制number 最左边的位设置为 1 意味着它是一个负数,所以如果你使用一个普通的,char它会符号扩展 32 位结果,所以它仍然是负数:0xffffffa8

回答by Jonathan Leffler

You don't show how you print anything, which makes it difficult to interpret your question. However, this statement is irretrievably broken in that it does nothing to concatenate the strings pointed at by pointerand pointer2:

你没有展示你如何打印任何东西,这使得很难解释你的问题。但是,该语句不可挽回地被破坏,因为它没有连接pointerand指向的字符串pointer2

unsigned long pointer3 = (*pointer << 16) | *pointer2;

This takes the first character that pointerpoints at (a 1) and shifts the value left 16 bits, and then adds (ors) in the first character that pointer2points at (another 1), and assigns the integer thus format to the misnamed pointer3. Thus, it gets the value:

这需要pointer指向 (a 1)的第一个字符并将值左移 16 位,然后在pointer2指向 (another 1)的第一个字符中添加 (or ),并将整数分配给错误命名的pointer3. 因此,它得到的值:

pointer3 = 0x00310031;

The question takes some interpretation, but making some plausible (but not necessarily accurate) assumptions, this code might do what you're after:

这个问题需要一些解释,但做出一些合理(但不一定准确)的假设,这段代码可能会做你所追求的:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static char *decimal_to_binary(unsigned char byte)
{
    char *result = malloc(9);
    if (result != 0)
    {
        char *digit = result;
        for (int i = 0; i < 8; i++)
            *digit++ = ((byte >> (7 - i)) & 0x01) + '0';
        *digit = '
P1 = <<11000000>>; P2 = <<10101000>>; P3 = 0x00310031; C = <<1100000010101000>>
'; } return result; } int main(void) { char *pointer1 = decimal_to_binary(192); char *pointer2 = decimal_to_binary(168); char concatenated[17]; unsigned long pointer3 = (*pointer1 << 16) | *pointer2; strcpy(&concatenated[0], pointer1); strcpy(&concatenated[8], pointer2); printf("P1 = <<%s>>; P2 = <<%s>>; P3 = 0x%08lX; C = <<%s>>\n", pointer1, pointer2, pointer3, concatenated); free(pointer1); free(pointer2); return(0); }

Output:

输出:

void decimal_to_binary(unsigned char byte, char buffer[9]);

Note that the code using decimal_to_binary()does not take care to avoid (mis)using null pointers. The design of decimal_to_binary()is also less than stellar; those free()calls are easily forgotten. A better design would be:

请注意,代码 usingdecimal_to_binary()没有注意避免(错误)使用空指针。的设计decimal_to_binary()也不尽如人意;这些free()电话很容易被遗忘。更好的设计是:

unsigned long pointer3 = (*pointer << 16) | *pointer2;

where the calling code provides the buffer into which the binary output is written. There are also other ways of writing the loop in decimal_to_binary(); some might even be more efficient than the one chosen here.

其中调用代码提供了写入二进制输出的缓冲区。还有其他方法可以在decimal_to_binary();中编写循环。有些甚至可能比这里选择的更有效。

回答by umang2203

First only assign one number in pointer like unsigned long pointer3 = *pointer;after this left shift this pointer316 times. pinter3=pointer3<<16;pointer3=pointer3|*pointer2;

首先只在指针中分配一个数字,就像 unsigned long pointer3 = *pointer;在这个左移这pointer316 次之后。 pinter3=pointer3<<16;pointer3=pointer3|*pointer2;

this will work i think

我认为这会起作用

回答by Vineet Kapoor

There is not need to shift by 16 as you are doing in

不需要像你在做的那样移动 16

#include <stdio.h>
#include <string.h>

void print_binary(int num) {
    short rem[16] = {0};
    for (short i = 1; i <= 16; i++) {
        rem[16-i] = num%2;
        num = num >> 1;
    }
    for (short int i = 0; i < 16; i++) {
        printf("%d", rem[i]);
    }
    printf("\n");
}

int main (int argc, char* argv[]) {

    unsigned char num1 = 192;
    unsigned char num2 = 168;
    int num3 = 0;
    num3 = (num1 << 8) | num2;
    printf("first number: %d\n", num1);
    print_binary(num1);

    printf("second number: %d\n", num2);
    print_binary(num2);

    printf("The number is %d\n", num3);
    print_binary(num3);

    return 0;
}

pointeronly needs to be shifted by 8.
Following code will achieve what you are trying to do.

指针只需移动 8。
以下代码将实现您想要做的事情。

 #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    using namespace std;



    int main()
    {
    int a = 32; // 100000
    int b = 5; // 101
    int step=0;
    int siz=0;
    while(1){
    if(pow(2,step) < b){
    step++;
    continue;
    }
    else{
    siz = step;
    break;
    }

    }
    a = a<<siz;
    a = a | b;
    cout<<a;
    }

回答by Mr. Hello_world

This one looks easy to understand)

这个看起来很容易理解)

##代码##