簡體   English   中英

使用char指針讀取int值並將其返回

[英]Read an int value using a char pointer and return it

static unsigned int read24(unsigned char *ptr)
{
  unsigned int b0;
  unsigned int b1;
  unsigned int b2;
  unsigned int b3;

  b0 = *ptr++;
  b1 = *ptr++;
  b2 = *ptr++;
  b3 = *ptr;

  return ( ((b0 >> 24) & 0x000000ff) |
           ((b1 >> 8)  & 0x0000ff00) |
           ((b2 << 8)  & 0x00ff0000) |
           (b3 << 24)  & 0x00000000     // this byte is not important so make it zero
         );

} 

在這里,我編寫了一個函數,嘗試使用char指針讀取32位(4字節)並返回這32位(​​4字節)。我懷疑這是否可以正常工作。此外,我正在使用/浪費過多的內存定義4個不同的整數變量嗎?是否有更好的方法編寫此函數。 感謝您的時間。

考慮將以下方法用於您的任務:

#include <string.h>

unsigned int read24b(unsigned char *ptr)
{
    unsigned int data = 0;
    memcpy(&data, ptr, 3);
    return data;
}

如果您要直接對位進行排序,這是一種情況,但是我想您不...

關於您的代碼-您必須應用遮罩然后進行移位,例如:

unsigned int read24(unsigned char *ptr)
{
  unsigned char b0;
  unsigned char b1;
  unsigned char b2;

  b0 = *ptr++;
  b1 = *ptr++;
  b2 = *ptr;

  return ( (b0 & 0x0ff) >> 16 |
           (b1 & 0x0ff) >> 8  |
           (b2 & 0x0ff)
         );
} 

首先,刪除b3,因為您顯然是要讀取24位,所以您甚至都不應該嘗試訪問該額外的字節(如果還沒有分配該字節怎么辦?)。

其次,我認為您的班次錯了。 b0始終在[0..255]范圍內,因此,如果>> >> 24,它將變為零。 也不需要屏蔽任何內容,因為您來自未簽名的字符,所以您知道只會設置8位。 您可能想要:

return (b0 << 16) | (b1 << 8) | b2;

要么

return (b2 << 16) | (b1 << 8) | b0;

取決於數據的字節序。

至於使用這些中間整數,如果您有一個不錯的編譯器,那就沒關系了(編譯器會對其進行優化)。 但是,如果您是為嵌入式平台編寫的,或者在其他方面的狀態低於are編譯器,則省略中間int可能有助於提高性能。 在這種情況下,請勿在同ptr[n]語句中放置多個ptr++ ,而應使用ptr[n]來避免多個增量帶來的未定義行為。

好吧,我不太清楚你要做什么。 如果我沒記錯的話,您想輸入一個char *(如果您正在運行32位系統,則很可能為4個字節),並獲得與int *相同的字節組織(4個字節)

如果您想要的只是char *字節集的int *版本,則可以使用類型轉換:

unsigned int* result = (unsigned int*)ptr;

如果您希望使用相同的字節集合,但您希望最高有效字節等於0,則可以執行以下操作:

unsigned int* result = (unsigned int*)ptr & 0x0FFF;

一些其他信息:

- 類型轉換是一種通過使用將變量轉換為類型的臨時副本,將變量臨時“轉換”為所需類型的方法,如果將其轉換為類型,則可以使變量充當所需的任何類型:示例:

unsigned int varX = 48;
//Prints "Ascii decimal value 48 corresponds with: 0" 
printf ("Ascii decimal value 48 corresponds with: %c\n", (char)varX);

-十六進制數字每個占據一個字節。 因此,在您的代碼中:

0x000000ff-> 8字節數據

0x表示每個占位符都是十六進制值,我想您要使用的是0x000F,這將使除最低有效字節外的所有其他字節為0

ANSI-C可以處理十六進制(前綴-> 0x),八進制(前綴-> 0)和十進制

希望這對您有所幫助!

從各個指針構建數字時,必須在遞增的同時將數字向左移動Or將值一起移動。 (適用於小端序機)。 這樣想,在您讀取b0之后,它將是最終數字中的最低有效字節。 更重要的字節在哪里? (向左轉)。

當您將指針值讀入b0, b1, b2, b3 ,它們所持有的全部都是一個字節。 他們無法知道原始數字的來源,因此不需要“相對”轉換。 您只需從最低有效字節開始,然后將每個連續字節向左遞增一個比最后一個字節多1個字節。

下面,我以無符號字符指針中的無符號值的構建中的所有字節為例。 您可以簡單地省略不需要的字節以滿足您的需求。

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

#if defined(__LP64__) || defined(_LP64)
# define BUILD_64   1
#endif

#ifdef BUILD_64
# define BITS_PER_LONG 64
#else
# define BITS_PER_LONG 32
#endif

char *binstr (unsigned long n);
static unsigned int read24 (unsigned char *ptr);

int main (void) {

    unsigned int n = 16975631;
    unsigned int o = 0;

    o = read24 ((unsigned char *)&n);

    printf ("\n number : %u    %s\n", n, binstr (n));
    printf (" read24 : %u    %s\n\n", o, binstr (o));

    return 0;
}

static unsigned int read24 (unsigned char *ptr)
{
    unsigned char b0;
    unsigned char b1;
    unsigned char b2;
    unsigned char b3;

    b0 = *ptr++;  /* 00001111000001110000001100000001 */
    b1 = *ptr++;  /* b0      b1      b2      b3       */
    b2 = *ptr++;  /* b3      b2      b1      b0       */
    b3 = *ptr;    /* 00000001000000110000011100001111 */

    return ((b0 & 0x000000ffU)         |
           ((b1 << 8 )  & 0x0000ff00U) |
           ((b2 << 16)  & 0x00ff0000U) |
           ((b3 << 24)  & 0xff000000U));
}

/* simple return of binary string */
char *binstr (unsigned long n)
{
    static char s[BITS_PER_LONG + 1] = {0};
    char *p = s + BITS_PER_LONG;

    if (!n) {
        *s = '0';
        return s;
    }

    while (n) {
        *(--p) = (n & 1) ? '1' : '0';
        n >>= 1;
    }
    return p;
}

輸出量

$ ./bin/rd_int_as_uc

 number : 16975631    1000000110000011100001111
 read24 : 16975631    1000000110000011100001111

暫無
暫無

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

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