定数アドレスをポインターに割り当てる方法を尋ねましたが、(a) ひどく移植性がなく、(b) ポインターをインクリメントする効果を確認するという目的に必ずしも役立つとは限りません。
これは、未定義の動作が原因で爆発する可能性がなく、好奇心を満足させるプログラムです。
#include <iostream>
int main() {
const int len = 10;
char char_array[len];
int int_array[len];
char *cp = char_array;
for (int i = 0; i <= len; i ++) {
std::cout << "cp = " << static_cast<void*>(cp) << "\n";
cp ++;
}
std::cout << '\n';
int *ip = int_array;
for (int i = 0; i <= len; i ++) {
std::cout << "ip = " << static_cast<void*>(ip) << "\n";
ip ++;
}
}
私の(64ビット)システムでの出力は次のとおりです。
cp = 0x7fffaa5ddc30
cp = 0x7fffaa5ddc31
cp = 0x7fffaa5ddc32
cp = 0x7fffaa5ddc33
cp = 0x7fffaa5ddc34
cp = 0x7fffaa5ddc35
cp = 0x7fffaa5ddc36
cp = 0x7fffaa5ddc37
cp = 0x7fffaa5ddc38
cp = 0x7fffaa5ddc39
cp = 0x7fffaa5ddc3a
ip = 0x7fffaa5ddc00
ip = 0x7fffaa5ddc04
ip = 0x7fffaa5ddc08
ip = 0x7fffaa5ddc0c
ip = 0x7fffaa5ddc10
ip = 0x7fffaa5ddc14
ip = 0x7fffaa5ddc18
ip = 0x7fffaa5ddc1c
ip = 0x7fffaa5ddc20
ip = 0x7fffaa5ddc24
ip = 0x7fffaa5ddc28
これに関する注意事項:
各ポインターは常に適切な型の配列の要素、またはその末尾のすぐ後ろを指すため、ポインターのインクリメントは有効です。(配列の末尾のすぐ後ろにポインターを作成することは許可されていますが、そのようなポインターを逆参照することは許可されていません。)
タイプのポインターを印刷するときに生成される出力void*
は、実装定義です。私のシステムでは、ポインター値の 16 進数表現であり、整数であるかのように解釈されます。これはおそらく最も一般的な方法です。
char*
ポインターが毎回 1 ずつインクリメントされ、ポインターが 4 ずつインクリメントされているように見えることがわかりますint*
。私のシステム (およびおそらくあなたのシステム) では、ポインターはバイト アドレスとして格納されます。ポインター演算は、バイト単位ではなく、ポイント先の型の単位で定義されます。ポインタをインクリメントすると、以前の位置からバイト後のint*
メモリ位置sizeof (int)
(この場合は 4 バイト) を指すようになります。すべてのポインター演算はこのように定義されます。ptr2 - ptr1
2つのアドレス間の要素の数(タイプptr1
とptr2
ポイントに関係なく)を示します。
表示された特定の値は、システムでメモリ アドレスがどのように管理されているかを示しています。ポインターと整数の間のマッピングは、通常、システムのメモリ モデルを反映します。そのモデルは、主に実装固有です。