- ベストアンサー
C言語によるメモリ読み書き
大学の授業でC言語を勉強しています。 下記のようなサンプルを頂いたのですがいまいち理解できません。 このサンプルは正しいのでしょうか。 Q) cpy_ptr_32はポインタ宣言で、"MEMORY_BASE"の"0x08000000"を入力していますが、その後for文中に"i"が入力されています。 これはデータが『0x08000000』、アドレスが『i』と認識して良いのでしょうか? 上記の場合、"MEMORY_BASE"はアドレスなのに、なぜデータとして扱っているのかが理解できません。 経験が浅いため、サンプルが正しいかも判断がつきません。 宜しくお願いします。 ================================================================ #define MEMORY_BASE 0x08000000 //MEMORYのベースアドレス int main (){ unsigned int* cpy_ptr_32 ; unsigned int read_data_32 ; unsigned int i ; while(1) { // Memory TEST cpy_ptr_32 = MEMORY_BASE ; for(i = 0 ; i < 0x2000000 ; i++){ *cpy_ptr_32 = i ; read_data_32 = *cpy_ptr_32 ; if (read_data_32 != i) { printf ("No Good !!! 32 bit access !!! error_address = %x \n" , cpy_ptr_32); WriteRead(LED ,0,0x0); return(0); } cpy_ptr_32++ ; WriteRead(LED ,0,0x1); } ================================================================
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#define MEMORY_BASE 0x08000000 //MEMORYのベースアドレス int main (){ unsigned int* cpy_ptr_32 ; unsigned int read_data_32 ; unsigned int i ; while(1) { // Memory TEST cpy_ptr_32 = MEMORY_BASE ; //ポインタにアドレス設定。ポインタ=即値とすることはできます。 for(i = 0 ; i < 0x2000000 ; i++){ *cpy_ptr_32 = i ; //cpy_ptr_32が示すアドレスに00000000~01ffffffの値を書き込む read_data_32 = *cpy_ptr_32 ; //正しく書き込まれているか確認するため読み出し if (read_data_32 != i) //読み出した値と書き込んだ値の比較 { printf ("No Good !!! 32 bit access !!! error_address = %x \n" , cpy_ptr_32); WriteRead(LED ,0,0x0); return(0); //32bitアクセスできないアドレスを表示して終わる } cpy_ptr_32++ ; //ポインタインクリメント WriteRead(LED ,0,0x1); } 例えば、4で割り切れるアドレスにしか32bitアクセスできない処理系がありますが、それを確認するプログラムのようです。 cpy_ptr_32++は、これが1byte加算されるのか4byteなのかは処理系(コンパイラ)によります。 ・・・というのがわたしの解釈です。
その他の回答 (2)
- jacta
- ベストアンサー率26% (845/3158)
> このサンプルは正しいのでしょうか。 なんとも言えません。 まず、コメントに // が使われていますが、C99でしょうか? また、main関数のreturn文が省略されているのも、C99だからでしょうか? 処理系を特定しないのであれば、C99でなければ、これらは間違いです。 > これはデータが『0x08000000』、アドレスが『i』と認識して良いのでしょうか? おそらく違います。 > cpy_ptr_32 = MEMORY_BASE ; 整数型をポインタ型に暗黙的に型変換しているわけですが、その場合の結果は処理系に依存します。
お礼
すみません。 "C99"が分かりません・・・。 他にも何種類かあるのでしょうか。
- venzou
- ベストアンサー率71% (311/435)
処理系が分からないので、何とも言えませんが、 文法的には間違っていないと思います。 >unsigned int* cpy_ptr_32 ; cpy_ptr_32は unsigned int へのポインタです。 つまり、cpy_ptr_32 にはアドレスが入り、 ポインタが指す先 *cpy_ptr_32 には unsigned int が入ります。 >cpy_ptr_32 = MEMORY_BASE ; これはアドレスの代入です。 >*cpy_ptr_32 = i ; これは、unsigned int の代入です。 * が付いてますよね、これが重要です。 ポインタが指している先に i を代入しています。 この代入で cpy_ptr_32 自体の内容は変化しません。 >これはデータが『0x08000000』、アドレスが『i』と認識して良いのでしょうか? 逆ですね、アドレスが『0x08000000』で、そのアドレスに入っているデータが『i』 1回目の代入が終わった段階のメモリマップのイメージは下記 アドレス データ 変数名 ???????? 08000000 cpy_ptr_32 ???????? 00000000 i 08000000 00000000 ← *cpy_ptr_32 ポインタの先 6回目の代入の後は下記のような感じ アドレス データ 変数名 ???????? 08000014 cpy_ptr_32 ???????? 00000005 i 08000000 00000000 08000004 00000001 08000008 00000002 0800000C 00000003 08000010 00000004 08000014 00000005 ← *cpy_ptr_32 ポインタの先 これでイメージは伝わるかな?(^^;
お礼
イメージ図まで添えてありがとうございます。 参考にさせて頂きます。
お礼
ありがとうございます。 各行に対しての説明、とても参考になります。