• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ポインタ変数を変数に渡す方法)

ポインタ変数を変数に渡す方法

このQ&Aのポイント
  • ポインタ変数からアドレスを取得し、int型変数に代入する方法を説明してください
  • 特殊な操作を使って与えられたアドレスに補正を加え、メモリアクセスを行う方法について教えてください
  • C言語でポインタ変数を扱う際に注意すべき点や実際のサンプルコードを紹介してください

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

このままでも問題はないと思います。 ただ、C言語全体としては、*int を int に代入したときの挙動は保証されていないので、一度アセンブラレベルで確認をとるのはいいと思います。 さらに、わざわざ、変数を介在させなくても、 unsigned int *p; // ポインタ変数宣言 unsigned int value; p= (unsigned int *)0x00001F00; // メモリの0x1F00番地 value = p; // <-- ここが心配 value |= 0xCC << 16; // 与えられたアドレスから value &= 0x4 << 12; // 「補正アドレス」生成 *(volatile unsigned int *)value = 0xA5A5A5A5; // 「補正アドレス」にA5A5... をライト でもいいです。 さらに、 #define intAddress(x) (volatile unsigned int *)(x) という定義があれば、 *intAddress(value) = 0xA5A5A5A5; というのも、見た目がきれいかもしれません。 * の有無は好みというところもあり、 #define intAddress(x) *(volatile unsigned int *)(x) なら、 intAddress(value) = 0xA5A5A5A5; です。 あとアドレスの操作が、「オフセットを加える」ということだけですむのであれば、(上記の例ではビット演算がありますが) unsigned int *p; // ポインタ変数宣言 unsigned int offset; // offset にいろいろとオフセットを算出 p[offset] = 0xA5A5A5A5; でOKです。 ただし、この場合、offset は、int のデータサイズずつ変化しますから、 p = 0x00001F00; として、int が 32bit なら、多くの場合、 p[0] は、0x00001F00 をポイント p[1] は、0x00001F04 をポイント p[2] は、0x00001F08 をポイント と、4byte ずつアドレスが変化します。

その他の回答 (3)

回答No.4

> (int * 型)ポインタ変数に代入されたアドレスを、(普通の)int 型変数に代入したい なぜ??? > 想定しているケースは、与えられたメモリ番地に対して、アドレスオフセットを加えるなどの操作を施して「補正アドレス」を生成し、メモリアクセスを行う、というような特殊な操作を実現するような場合です。 > ※ メモリ番地がポインタ宣言で与えられる、という制約があります。 特殊なケースとは思えないし、制約にも見えない。 メモリ番地がポインタ型なのは自然だし、アドレスに操作を加えるのもそれほど特殊な事ではない。 今回の場合、int型変数を使う必要は全くない。 事故の可能性を承知で使うのも不可能ではないが、全てポインタ型で操作するのが(intにはしない)良さそうに感じた。 ポインタとして扱って問題が発生したなら、ポインタで操作しながら発生した問題に対処すれば良いのでは。

tk_1980024
質問者

お礼

ありがとうございます。 ご指摘のとおり、通常ならばこのような型変換を行う必要はないのですが、関数定義を既存の関数と併せるためにあえてポインタ渡しの必要がありました。 本来は、アドレスとして与えられた「値」を加工したものが、メモリへアクセスする際の値となるのでデータとして受け取るの方が自然ではあります。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

int にしろ int * にしろその大きさは処理系依存なので, あなたの使っている処理系によって正しいか正しくないかが決まる. 規格上は (int でも long でもいいけど) 「ポインタ値を入れることができる大きさの整数型」であれば「行って帰ったときに元の値に戻る」ことが保障されていたと思う. その際キャストはしなくてもいい. C99 なら int_ptr/uint_ptr という「ポインタ値を入れることができる」と保証された型があるので, それを使えるなら使うのが安全.

回答No.1

アドレス長と unsigned int 長は大丈夫なの? アドレスが 24bit 、 unsigned int 16bit って具合なら根本的にだめで、 unsigned long 32bit を使わないとまずいですよ。 int はパソコンでは 32bit ありますが組み込みでは 16bit しかないこともあり得ることなので注意が必要です。 詳しくはシニアエンジニア、仕様担当、スペックシートで確認してみてください。 >value = p; // <-- ここが心配 キャストがないとまずかったかもしれない。 ・・・。昔やったけどすっかり忘れている(^^;) >unsigned int *p, *p1; // ポインタ変数宣言 たしか volatile を使います。 volatile unsigned int *p, *p1; こうだっけかな? こうしないと、コンパイラが最適化してCPUレジスタ内で処理を完結して、メモリにアクセスしないとかが起きたはずです。

関連するQ&A