我是C初學者。無法理解這段代碼發生了什么:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint64_t num = 99999;
uint64_t *num_ptr = #
uint8_t first_byte = ((uint8_t *)num_ptr)[0];
printf("%hhu", first_byte);
return 0;
}
這列印159。
我在看uint8_t first_byte = ((uint8_t *)num_ptr)[0];
我試圖以這種方式理解它: uint64_t 指標num_ptr首先被轉換為 uint8_t 指標,然后我們用方括號對其進行索引以獲得第一個位元組。這是一個正確的解釋嗎?如果是這樣,是否可以在不取消參考的情況下索引指標以獲取其部分內容?
uj5u.com熱心網友回復:
99999=0x1869F或者如果您愿意作為 64 位數字0000 0000 0001 869F- Intel/PC 計算機使用小端序。什么是 CPU 位元組序?
- 因此,您的 64 位數字在記憶體中存盤為
9F86 0100 0000 0000. - C 允許我們通過指向字符型別的指標逐位元組檢查更大的資料型別。
uint8_t是所有非外來系統上的字符型別。 ((uint8_t *)num_ptr)[0];將 64 位指標轉換為 8 位(字符)指標,然后使用[]運算子取消參考該指標。- 我們得到第一個位元組
0x9F= 159 dec。 %hhu用于列印unsigned char。要使用的最正確的轉換說明符uint8_t將"%" PRIU8來自inttypes.h
uj5u.com熱心網友回復:
考慮一個類似作業的程式:
#include <stdio.h>
#include <stdint.h>
typedef union td_USixtyFour
{
uint64_t whole;
uint8_t parts[sizeof(uint64_t)];
} USixtyFour;
int main( int argc, char **argv )
{
USixtyFour number;
number.whole = 99999;
printf( "number.parts[0] is %u / 0xx\n", number.parts[0], number.parts[0] );
return 0;
}
哪個輸出:
number.parts[0] is 159 / 0x9f
這里有一個C union,它模擬了 OP 代碼中所做的事情。.parts覆寫與 相同的記憶體.whole。所以本質上是在沒有任何指標取消參考的情況下parts訪問記憶體中位元組的內容。uint64_t
由于位元組順序,這種操作會存在可移植性問題, 通常應避免。當然,可以通過使用類似的函式打包成網路位元組順序來緩解這種情況htonl(),因此保留了已知的順序。
uj5u.com熱心網友回復:
- 你所做的是“指標雙關語”。通常這是一個危險的操作,可能會呼叫未定義的行為并違反嚴格的別名規則。但是,當您以
chars 的身份訪問其他資料時,就可以了。
int main(void)
{
uint64_t num = 99999;
uint64_t *num_ptr = #
printf("6"PRIx64"\n", num);
for(size_t index = 0; index < sizeof(num); index )
{
printf("Index = %2zu, value= hhx\n", index, ((unsigned char *)num_ptr)[index]);
}
return 0;
}
最安全的方法是使用memcpy
int main(void)
{
uint64_t num = 99999;
uint64_t *num_ptr = #
unsigned char arr[sizeof(num)];
printf("6"PRIx64"\n", num);
memcpy(arr, &num, sizeof(num));
for(size_t index = 0; index < sizeof(num); index )
{
printf("Index = %2zu, value= hhx\n", index, arr[index]);
}
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/493278.html
上一篇:了解指標
