• ベストアンサー

C言語 #defineについて

C言語でどの様に考えれば良いか分からない事があるので、教えて下さい。 以下の様な行が出てきたのですが、どういう意味なのでしょうか? #define SYSTEM (*(volatile struct st_system *)0x80000) 現状分かっている事は 1.#define ABC 100   ならこれ以降で出てくるABCは100と読み替える。 2.volatileはコンパイラの最適化を抑制する様な意味。 とい事です。 以上、宜しくお願い致します。

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

#defineはマクロの定義です。 マクロは「プログラム中の文字列を単純に置き換える」だけのものです。 その意味については、「この時点では」関係ありません。 この例は >1.#define ABC 100 >  ならこれ以降で出てくるABCは100と読み替える。 とまったく同じです。 > 2.volatileはコンパイラの最適化を抑制する様な意味。 は、とりあえずマクロの処理の時点では考えなくてよいです。 プログラム中に SYSTEM とあったら (*(volatile struct st_system *)0x80000) と「置き換えるだけ」ものです。 置き換えたものがプログラムでどんな意味を持つかは、また別の問題です。 0x80000 を st_system構造体のポインタにキャストして、*でその実体を求めるものです。 名前からして、0x80000にあたる領域にはシステムに関する情報が記録されていて、st_system構造体の各メンバが、それぞれの状態を表わすようになっているのでしょう。例えば if ( SYSTEM.busy ) /* システムがビジー状態なら */ SYSTEM.reset = 1; /*システムにリセット信号を送る */ という感じで。システムの状態は刻々と変わるものですから、最適化で「定数」あつかいされないように、volatileを付けているのでしょう。

abcdef220
質問者

お礼

ありがとう御座いました。 難しいですね。 頑張って理解します。

関連するQ&A

  • マイコンのプログラム(C言語)について

    マイコンのサンプルプログラムの中に以下のような記述がありました。 ヘッダーファイル内 struct st_hudi { union { unsigned short WORD; struct { unsigned short TI:8; } BIT; }SDIR; }; #define HUDI (*(volatile struct st_hudi *)0xFFFE2000) そして、この構造体の使い方は HUDI.SDIR.WORD = 0; と、いった感じです。 通常は、構造体の宣言(struct st_hudi aなど)を行わないと使えないと思うのですが、以上のプログラムでエラーは出ません。 1.上記のような場合は、構造体の宣言はいらないのでしょうか? 現在は、#defineの部分でアドレスを指定してあるため、構造体の宣言はいらない、という認識を持っています。 2.volatileがなくても動きそうなのですが、これは必要なのでしょうか? アドレスを明記しているため、volatileがなくても正常に動きそうな気がします。 回答よろしくお願いします。

  • [C言語]変数のアドレスを直接指定する構文

    C言語でのマイコン開発環境に付属しているヘッダーファイルにはレジスタを共用体と構造体でアクセスできるようにしてあります。 アドレスを割り付ける部分の記述は一行ですが、意味を考えた時に構文が複雑すぎて躓いてしまいました。 #define PD (*(volatile struct st_pd *)0xFFFF83A0) /* PD Address*/ 後ろの"*"はst_pdのポインタ型だとして前の"*"はどういう効果になっているのでしょうか? また、複数行に分解して同じ効果を書くこと(例えば変数unsigned long valにアドレス0xFFFF83A0を割り付け)は出来るのでしょうか? 理解を助けるためにお願いします。

  • 構造体・ビットフィールドのvolatileに関して。

    以下のような構造体があったとする。 -(1) -----------------------------  typedef volatile struct ABC{    char x;    char y;  }stABC; -(2) -----------------------------   typedef struct ABC{    volatile char x;    volatile char y;  }stABC; --------------------------------- ■質問  -------------   stABC abc;   abc.x // ←volatileは有効?   abc.y // ←volatileは有効?  ------------- ・このとき、メンバx,y は(1)/(2)の構造体型宣言どちらでも  同じ意味合いになっているのでしょうか。  ※特に(1)の場合、volatileは有効になっているのでしょうか。 ・ビットフィールド時も同じと考えて問題ないでしょうか。   (1)typedef volatile struct ABC{      char x: 1 ;      char x: 7 ;    }stABC;   (2)typedef struct ABC{      volatile char x: 1 ;      volatile char x: 7 ;    }stABC;

  • ビットフィールドをクリアしたいのですが

    初歩的な質問をご容赦ください。 typedef struct tagStruct { ____int a: 2; ____int b: 2; } STRUCT; STRUCT st = {1, 2}; /*ビットフィールドをすべてクリア*/ (*int)st = 0; みたいなことはできないのでしょうか。 コンパイラに、intは必要ありません、と言われて削除すると*演算子の使い方が違う、と怒られてしまいます。 言語仕様レベルで不可能なことなのでしょうか?

  • C言語もしくはC++言語プログラマになれますか?

    私は30歳になったばかりです。諸事情によりずっと家にいます(母親の病気などです)。 5年ほど前JavaでWebシステムを作っていましたが、やめました。それ以降もJavaやPHP、VB.NETなどやってはいるんですが、なかなか腰を落ち着けられません。 私は本来の性格として基礎固めが大好きというか基礎がしっかりしていないと意味がないと考えてしまうタイプです。こと、プログラムに関しても、コンピュータの仕組みから理解してアセンブラやらの書物を読み、C言語を勉強したりするとコンピュータを根本から理解できて、やっと自分の役に立つという思考しかできないものです。いきなり高級言語のJavaやらC#やら.NETやらやっても、うわべだけさすってるようで、根本的な理解を得られないので(コンピュータに対する)、無駄だなあとどうしても感じてしまうのです。また、それよりも基礎からしっかり積み重ねた方が後々、新しい言語ができても理解の度合いというかどっしりと理解できるとおもうのです。 しかし、就職のことを考え、PHPやらC#やらJavaやらVB.NETやらを優先してきてどれもどっちつかずになってしまいました。当然Cなども合間をぬってやっていました。 で、私は、そのどっちつかずな状態がいやなので、CとC++に絞って勉強することにしました。で、低級コンパイラの中身やアセンブラも勉強していこうと決心しました。しかし、就職のことを考えると不安です。 あと、1年みっちり勉強するとして、CやC++の就職先はあるのでしょうか?自分としては、働ける限り年齢がいくつになってもがんばりたいとおもうのですが、なにしろ世間的にいうと全く遅い年齢です。もし、励ましになるような事もありましたら、ご回答していただければ、うれしいです。よろしくお願いします。

  • C言語について。

    C言語プログラマとしては、スタートアップコードは・・・ ・自分が書いたプログラムを、直接動かすために必要なライブラリ ・それはコンパイル後、リンカによって追加されるライブラリこれは、 どういう意味でしょうか?分かりやすく教えていただけると幸いです。すみません。で、 以下のかぶくんまんさんの回答です。 https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11247611941 で、 C言語におけるプログラミングとは「main関数を書くこと」に他ならない。なぜ「main関数を書く」ことがC言語におけるプログラミングに他ならないのかと言えば、それは偏に「C言語のコンパイラはmain関数を呼び出すプログラムを生成するから」です。それがmain関数を求めるので結果的にmain関数がリンクされ、そしてmain関数が求めるままに他の関数もリンクされていくわけです。 で、その「main関数を呼び出すプログラム」こそが、C言語における「スタートアップコード」。 という回答で、main関数以降は、プログラマが書くのですよね?プログラマが関数をリンクさせる様なプログラムを書くということでしょうか?教えていただけると幸いです。すみません。 という所が分かりません。教えていただけると幸いです。すみません。以下のURL https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12247932542

  • アスキー刊「入門 C言語」についての質問

    アスキーより刊行されている「入門 C言語」を読んで勉強してますが… この本での勉強でわからないところが出て来てしまいました。 この本の6章4節に「文字列を検索するプログラムと言うのがありますが、まずこのプログラムの冒頭で #define HTAB 0x09 とした上で、同プログラムの72、73行目にてタブコードを探して埋め込むと言う処理を行っています。 私がわからないのはまず、 HTABを0x09に置き換える処理をプログラムの冒頭にて行っていますが、単語をHTABではなく単にABCだとか他の言葉で行ってはだめなのだろうか?と言う事と、そして何故、わざわざタブコードを探して埋め込むと言う処理を必要とするのだろうか?と言ったこの二点です。 プログラムの他の部分は理解出来ましたがこの二点の理屈のみだけは理解が出来ず、立ち止まってしまいました。 どなたかこの本に目を通された事があってメカニズムを説明出来る方がおられましたらどうか御回答の程をお願いします。

  • C言語にて、XORの演算時間を取得するには?

    題名の通りです。 C言語で、XOR命令の演算時間を取得しようとしています。演算時間を取得する関数部分は下の通りで、a^=b, b^=aをひたすら繰り返すことで、命令の演算時間を取得する、というものです。この方法を使って、ADD命令については演算時間を取得できました。しかし、XORについては、計測時間がほぼゼロになり、XORが動いていないようです。 その理由は、同じ値をXORすると元に戻るというXORの原理のため、コンパイラの最適化によりfor文内のXOR命令が消えてしまったからだと考えられます。 かといって、t1とt2にvolativeを付けて宣言すれば、最適化によって消去はされませんが、volativeの性質上、メモリアクセスの時間を取得することになってしまいます。 どうすれば、XOR命令のみの演算時間を取得できるでしょうか。 アイディアや指摘がありましたら、どうかご教授下さい。 -------------------------------------------------------------- #define ADD(a, b) a+=b #define XOR(a, b) a^=b /* 10回反復するマクロ */ #define repeat10(S) S S S S S S S S S S /* 各命令の演算時間を計測する関数 */ void operation_test( unsigned int *out, unsigned int p1, unsigned int p2, int its) { /* volatileを付けた宣言だと、t1とt2はメモリに取られるため、目的を達成できない */ unsigned int t1 = p1; unsigned int t2 = p2; /* itsは反復回数 */ for(int i=0; i<its; i++){ /* いずれかの行を選択する。ADDはきちんと演算されているよ */ /* うだが、XORは最適化により消去されてしまっているらしい */ repeat10(ADD(t1, t2); ADD(t2, t1); ) //repeat10(XOR(t1, t2); XOR(t2, t1); ) } out[0]=t1+t2; } --------------------------------------------------------------

  • #define文等について質問です

    表題の件ですが、 プログラム読んでいて分からないことありましたので、 C言語の文法的なことですが、教えて下さいませ。 全然自信ないですが、自分の解釈も付けてみました… 質問(1) #define MP_RELEASEWIN(p) MP_FreeWin((IWindow **)&(p)) 中略 static void MP_FreeWin(IWindow ** ppif); 中略 static void MP_FreeWin(IWindow ** ppif) { 中略 } このような場合、最初の#defineは、 MP_RELEASEWIN(p)は、MP_FreeWin((IWindow **)&(p))だよ と定義しているけど、前方宣言にはなっていないから static voidでプロトタイプ宣言して、 最後に関数の定義を書いているって解釈で 合っているのでしょうか? 質問(2) #define MP_IWINDOW_SETVTBL(pVtbl, pfnEn, pfnRd, pfnHE, pfnDel) \ (pVtbl)->Enable = (pfnEn); \ (pVtbl)->Redraw = (pfnRd); \ (pVtbl)->HandleEvent = (pfnHE); \ (pVtbl)->Delete = (pfnDel) これって、 MP_IWINDOW_SETVTBL(pVtbl, pfnEn, pfnRd, pfnHE, pfnDel) を (pVtbl)->Enable = (pfnEn); \ (pVtbl)->Redraw = (pfnRd); \ (pVtbl)->HandleEvent = (pfnHE); \ (pVtbl)->Delete = (pfnDel) の4行部分で置き換えているのでしょうか? あと、(pfnDel)の最後だけ、「;」がないのは 約束事って理解でいいのでしょうか? 質問(3) #define CMediaPlayer_CancelRedraw(p) { CALLBACK_Cancel(&(p)->m_cbRedraw); (p)->m_bRedraw = FALSE; } こんなのがあるのですが、 これは質問(2)と同じ意味なのでしょうか? こっちにはカッコが付いているのですが、 これは、何か意味があるのでしょうか? 質問(4) QINTERFACE(IWindow) { // Releases the window resources void (*Delete)(IWindow * po); }; この void (*Delete)(IWindow * po); の部分は、どういう風に理解すればいいのでしょうか? カッコとか、*がついてますが… Delete(IWindow * po); とかいう関数に何かしているという意味なのでしょうか@@; 教えて下さい。 なんか、たくさん質問してますが、 よろしくお願い致しますm(__)m

  • 構造体の静的な初期化

    構造体の静的な初期化で、初期化が書かれていないメンバーは、 どうなるのでしょうか。。? たとえば・・・ // 構造体の宣言 strcut MY_STRUCT {    int data1 ;    int data2 ;    int data3 ;    int data4 ; } ; // 変数宣言&初期化 static strcut MY_STRUCT st = {    .data1 = 100,    .data3 = 300 } ; ネットで調べると、 初期化で指示されていないメンバーは0に初期化される、 という記述も一つだけ見つけたのですが・・・これはC言語(C99)の仕様でしょうか? それともコンパイラ依存の仕様でしょうか?

専門家に質問してみよう