また、オープンソース コードを 32 ビット システムで実行する場合、ポインタを uint8 *ptr にする必要があるのはなぜですか?
uint8_t
ポインター自体のサイズではなく、ポインターが指すもののサイズです。式 のタイプ*ptr
は ですuint8_t
。オブジェクト の型は でptr
、uint8_t *
システムが必要とする大きさ (32 ビット、64 ビットなど) です。
ポインター演算を計算するときは、基本型が重要です。与えられたポインタ宣言
T *p;
式はafter型の'th要素p + i
のアドレスに評価されます。がの場合、 に続く ' 番目の整数のアドレスが得られます。である場合、 に続く '番目の巨大な構造体のアドレスが得られます。例えば:i
T
p
T
int
p + i
i
p
T
struct humongous
p + i
i
p
#include <stdio.h>
#include <stdint.h>
int main(void)
{
uint8_t *p0 = (uint8_t *) 0x00004000;
uint32_t *p1 = (uint32_t *) 0x00004000;
printf("p0 = %p, (p0 + 1) = %p\n", (void *) p0, (void *)(p0 + 1));
printf("p1 = %p, (p1 + 1) = %p\n", (void *) p1, (void *)(p1 + 1));
return 0;
}
出力を生成します
p0 = 0x4000、(p0 + 1) = 0x4001
p1 = 0x4000、(p1 + 1) = 0x4004
ポインターはすべて同じサイズである必要はなく、同じ表現を持っている必要もありません。たとえば、ハーバード アーキテクチャでは、命令とデータはメモリの別々の領域に格納され、バスのサイズが異なる場合があるため、オブジェクト ポインター ( 、int *
、char *
)float *
は 1 つのサイズ (たとえば 8 ビット) であり、関数ポインター (int (*foo)(void)
サイズ (たとえば 16 ビット)。同様に、ワード アドレス アーキテクチャでは、achar *
は、ワードへのオフセットを指定するために、他のポインター型よりも数ビット広い場合があります。