簡體   English   中英

如何從char [4]創建int? (在C中)

[英]How to make int from char[4]? (in C)

我有char [4]並且在其中: a[0] = 0x76 a[1] = 0x58 a[2] = 0x02 a[3] = 0x00我想打印它為int ,你能告訴我怎么做那?

這可行,但根據int,endian等的大小給出不同的結果。

#include <stdio.h>

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

    char a[4];
    a[0] = 0x76;
    a[1] = 0x58;
    a[2] = 0x02;
    a[3] = 0x00;
    printf("%d\n", *((int*)a));
    return 0;
}

這是更干凈,但你仍然有端/大小的問題。

#include <stdio.h>

typedef union {
    char c[4];
    int i;
} raw_int;

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

    raw_int i;
    i.c[0] = 0x76;
    i.c[1] = 0x58;
    i.c[2] = 0x02;
    i.c[3] = 0x00;
    printf("%d\n", i.i);
    return 0;
}

要強制使用某個字節序,請手動構建int

int i = (0x00 << 24) | (0x02 <<< 16) | (0x58 << 8) | (0x76);
printf("%d\n", i);

我認為工會是這樣做的合適方式。

#include <stdio.h>
#include <stdint.h>

union char_int {
    char chars[4];
    int32_t num;
};

int main() {
    union char_int tmp;

    tmp.chars[0] = 0x76;
    tmp.chars[1] = 0x58;
    tmp.chars[2] = 0x02;
    tmp.chars[3] = 0x00;
    printf("%d\n", tmp.num);
}

其他選項可以使用按位運算符| <<左移,如下(了解閱讀評論):

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

  char a[4];
  int32_t  i = 0;  // 32 bits = 4 bytes
  a[0] = 0x76;
  a[1] = 0x58;
  a[2] = 0x02;
  a[3] = 0x00;

  i = 0;   // initial  value must be `0`
  i = i | a[0] << ( 3 * 8); // 0x76 => 0x76 00 00 00, gives i = 0x76 00 00 00  
  i = i | a[1] << ( 2 * 8); // 0x58 => 0x00 58 00 00, gives i = 0x76 58 00 00
  i = i | a[2] << ( 1 * 8); // 0x02 => 0x00 00 02 00, gives i = 0x76 58 02 00
  i = i | a[3] << ( 0 * 8); // 0x02 => 0x02   
                            //      => 0x00 00 00 02, gives i = 0x76 58 02 00 

  printf("Hex: %x\nDec: %d \n", i, i);
  return 0;
}

輸出繼電器:

$ gcc  -Wall -pedantic yy.c 
$ ./a.out 
Hex: 76580200            <- "hex decimal"
Dec: 1985479168          <- "decimal"

注意: i = i | a[3] << ( 0 * 8); i = i | a[3] << ( 0 * 8); 可以只是i = i | a[3]; i = i | a[3]; ,我這樣寫,以保持代碼統一。

編輯:

哦,你可以這樣做:

i = 0 | 
     a[0] << ( 3 * 8) | 
     a[1] << ( 2 * 8) |
     a[2] << ( 1 * 8) |
     a[3] << ( 0 * 8);

看看這里: Codepade的工作代碼。

值是以big-endian還是little-endian順序存儲在數組中的? 可移植的方法是基於移位和掩碼,注意在一般情況下,將設置一些高位,並且您的普通char類型可能是有符號或無符號的。

小端

int i = (a[3] << 24) | ((a[2] & 0xFF) << 16) | ((a[1] & 0xFF) << 8) | (a[0] & 0xFF);

大端

int i = (a[0] << 24) | ((a[1] & 0xFF) << 16) | ((a[2] & 0xFF) << 8) | (a[3] & 0xFF);

您可以更改這些,以便每個術語始終具有形式((a[n] & 0xFF) << m) 如果您知道plain char是無符號的,則可以刪除掩碼操作。 你也可以使用強制轉換: unsigned char *u = (unsigned char *)a; 然后取消引用u而不是a

如果你想把它讀成大端或小端整數,只需做一些位移:

char a[4] = {0x76, 0x58, 0x02, 0x00};

// Big-endian:
uint32_t x = ((uint8_t)a[0] << 24) | ((uint8_t)a[1] << 16) | ((uint8_t)a[2] << 8) | (uint8_t)a[3];

// Little-endian:
uint32_t y = (uint8_t)a[0] | ((uint8_t)a[1] << 8) | ((uint8_t)a[2] << 16) | ((uint8_t)a[3] << 24);

如果要將其作為native-endian整數讀取,可以將數組轉換為指向整數的指針並取消引用。 請注意,前者允許char數組-這是任何其他類型的,這樣做打破了C'S嚴格別名規則,所以這不會是安全的或便攜式的。 例如:

char a[4] = {0x76, 0x58, 0x02, 0x00};

// Cast to pointer to integer and dereference.  This is only allowed if `a' is an
// array of `char'.
uint32_t x = *(uint32_t *)a;

或者,您可以直接使用union,或者只使用memcpy()數據。 這兩個都是安全和可移植的,只要char是8位(其大小以位為單位由宏CHAR_BIT給出)。

char a[4] = {0x76, 0x58, 0x02, 0x00};
uint32_t x;

// Copy the data directly into x
memcpy(&x, a, sizeof(x));

// Use a union to perform the cast
union
{
    char a[4];
    uint32_t x;
} u;
memcpy(u.a, a, sizeof(a));
// u.x now contains the integer value

請注意,我在上面的所有示例中都使用了uint32_t ,因為在所有系統上都不保證int為4個字節。 uint32_t類型在頭文件<stdint.h>定義,如果它由編譯器定義,則保證為32位寬。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM