経緯
苦手なC(C++)で入力したchar型のアドレス内の情報をint型の整数で表示するプログラムを作成したのでメモとして残しておきます。
このプログラムを作成した理由はchar型とint型でどのようにアドレス配置しているかを確認するためでしたが、コメントで多くの高度なプログラムをご教授頂いたので、記事を修正させていただきました。
(自分含む)初学者向けです。
環境
Visual Studio Community 2017
具体的なプログラム
1234567890(16進数で0x499602D2)を要素数4のchar型の配列として宣言し、10進数のint型としてキャストしprintfで出力するプログラム
簡易的な解決方法
このプログラムを作成するにあたり直面する問題として、エンディアンとポインタがあると思います。
エンディアン
int型で0x499602D2を
unsigned char c[4] = { 0x49, 0x96, 0x02, 0xD2 }; // 0x499602D2 = 1234567890
と1バイトずつ格納するビッグエンディアンの場合です。
別の方法として、
unsigned char c[4] = { 0xD2, 0x02, 0x96, 0x49 }; // 0x499602D2 = 1234567890
と格納するリトルエンディアンがあり、こちらが今回の環境で正解となります。
蛇足ですが聞いたところによるとビッグエンディアンはネットワーク機器やAMD製CPUで採用されているらしく、Intel製CPUだとリトルエンディアンでメモリに格納されているらしいです。
ポインタ
出力の際のポインタは留意しておく必要があります。
最初の頃ポインタを理解するのは難しいので間違えがちですが、上記の入力の場合以下の出力が正解です。
printf("%u\n", *(unsigned int *)&c);
自分も完璧に理解している訳ではないのですが、&cと(unsigned int *)、*は、
「char型変数cの先頭アドレスを取得」「その先頭アドレスをunsigned int型に変換」「その先頭アドレスの情報を読み取る」
と処理していると思われます(ここは自信ない…)
完成形
#include <stdio.h>
#include <stdlib.h>
int main()
{
// 入力
unsigned char c[4] = { 0xD2, 0x02, 0x96, 0x49 }; // 0x499602D2 = 1234567890
// 出力
printf("%u\n", *(unsigned int *)&c); // unsigned intでcを出力する
system("pause"); // 一時停止
return 0;
}
のように入力することで、
1234567890
と出ると思われます。
より良い解決方法
コメントしてくださっている方々のおっしゃる通り、int型は必ずしも4バイトであるとは限りません。
当方で提案されたコードをコンパイルしようとしたのですが、std::copyの仕様上安全ではない!ってコンパイラーに怒られて解決方法がわからずに挫折しました…
ほぼCの知識しかないのが悔やまれる…。