[英]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.