web-dev-qa-db-ja.com

*(uint32_t *)とは

*(uint32_t*)を理解するのに苦労しています。

私が持っていると言ってみましょう

uint32_t* ptr;
uint32_t num
*(uint32_t*)(ptr + num); //what does this do? does it 
7
Hoa.N

uint32_tは32ビットを保証する数値型で、値は符号なしです。つまり、値の範囲は0から2になります32 -1。

この

uint32_t* ptr;

タイプuint32_tのポインターを宣言しますが、ポインターは初期化されていません。つまり、ポインターは特定の場所を指していません。そのポインターを使用してメモリにアクセスしようとすると、未定義の動作が発生し、プログラムがクラッシュする可能性があります。

この

uint32_t num;

uint32_t型の変数です。

この

*(uint32_t*)(ptr + num);

ptr + numは、新しいポインターを返します。これはポインター算術と呼ばれ、コンパイラーが型のサイズを考慮することのみが通常の算術のようなものです。 ptr + numは、元のptrポインターとnumuint32_tオブジェクトのバイト数に基づくメモリアドレスと考えてください。

(uint32_t*) xはキャストです。これは、式xunit32_tであるかのように扱う必要があることをコンパイラーに伝えます。この場合、ptr + numはすでにuint32_t*であるため、必要さえありません。

先頭の*は、ポインターを介してメモリにアクセスするために使用される逆参照演算子です。式全体は次と同等です

ptr[num];

この変数はいずれも初期化されていないため、結果はゴミになります。ただし、次のように初期化する場合:

uint32_t arr[] = { 1, 3, 5, 7, 9 };
uint32_t *ptr = arr;
uint32_t num = 2;

printf("%u\n", *(ptr + num));

ptr[2]は5であるため、これは5を出力します。

21
Pablo

uint32_tstdint.hで定義されているため、含める必要がある場合があります

#include <stdint.h>
3
user7610

これは実際には何もしません。別の例を挙げましょう。

uint32_t data;
void *pointer = &data;
*(uint32_t *)pointer = 5;

まず、void*は「汎用」ポインターを意味します。任意のタイプのオブジェクトを指すことができます。

現在、(uint32_t *)は、_uint32_t型のオブジェクトへのポインターとしてpointerを解釈することを意味します。

式の残りの部分は、単に「このポインターによって保存された場所に5を保存する」ことを意味します。

uint32_tが何かを知りたい場合、それは正確に32ビットの符号なし整数です。 pointer + numpointer[5]のアドレスと同じです。

1
giusti