2015-04-03 154 views
0
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 
     ); 

} 

在這裏,我寫了一個功能,我試圖用字符指針讀取32位(4字節),並返回的32位(4字節)。我有個疑問如果這將正常工作。另外,我是通過定義4個不同的整數變量來使用/浪費太多的內存嗎?有沒有更好的方法來編寫這個函數。感謝您的時間。使用字符指針讀取一個int值,並將其返回

+0

我認爲它會返回'1'或者'0'。 – Himanshu 2015-04-03 05:34:26

+0

'read24'與「* ...試圖讀取32位*」:請解釋。 – alk 2015-04-03 09:21:44

+0

我讀了4個字節......但我讓最後一個字節爲零,因爲它對我來說不是那麼重要.....最後我返回返回4byte值......這實際上就像0x 00xxxxxx ...因此read24 – 2015-04-03 10:02:45

回答

0

考慮使用你的任務以下方法:

#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) 
     ); 
} 
+0

這個假設您的平臺排序與輸入數據相匹配。它還會對如果從int重寫三個字節並假定sizeof(int)> = 3'發生什麼情況做出不可移植的假設。 – bdonlan 2015-04-03 06:07:24

+0

@voland - 這裏int的大小是4字節...我也看到你已經聲明b0爲unsigned char,並且我使用了unsigned int ...你的意思是建議我應該使用unsigned char嗎? – 2015-04-03 08:03:43

+0

@tapanchawda:使用*運算符從(無符號字符*)讀取數據時,我更喜歡使用unsigned char類型的數據。當我做類似'b0&0x0ff'的結果時,由於類型爲'0x0ff'和類型提升 – VolAnd 2015-04-03 09:07:11

0

首先,降B3,因爲你顯然意味着讀取24位,你甚至不應該試圖訪問一個額外的字節(如果它沒有噸甚至分配?)。

其次,我認爲你有你的錯位。 b0將始終在[0..255]的範圍內,所以如果>> 24,它將變爲零。也沒有必要掩蓋任何東西,因爲你來自unsigned char,你知道你只會設置8位。你可能想要麼:根據您的數據的字節序

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

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

。至於使用這些中間整數,如果你有一個體面的編譯器,它不會有問題(編譯器會優化它們)。但是,如果您正在爲嵌入式平臺編寫代碼,或者編譯器的編譯狀態不足,則可能會忽略中間整數,這可能有助於您的性能。在這種情況下,不要在同一語句中放置多個ptr++,而應使用ptr[n]來避免多個增量中的未定義行爲。

+0

是的,我寫的是一個嵌入式平臺..我可以使用ptr [n]而不是ptr ++。你能幫我一下嗎 – 2015-04-03 08:08:55

0

那麼,我不太清楚你想要做什麼。如果我沒有弄錯,你想輸入一個char *(如果你正在運行一個32位系統,最有可能是4個字節),並得到與int相同的字節組織*(4字節)

如果你全部要的是整型*一個char *字節集可以使用的類型轉換的版本:

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); 

-Hexidicamal數字佔據每一個字節。因此,在你的代碼:

0x000000ff - > 8個字節的數據

0X意味着每個佔位的是一個十六進制值, 我想你所追求的是0x000F,這將讓所有的其它字節0除了至少顯著字節

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

希望這有助於!

0

當從單個指針構建您的號碼時,您必須將這些數值向左遞增,因爲您將這些值遞增在一起。 (用於小端機器)。在閱讀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