- ベストアンサー
構造体でデータをやり取り出来ないか
みなさん、こんにちは。質問させて頂きます。 関数に変数を渡すとき、変数のポインタを渡す方法が有ります。 この方法なら呼ばれた関数が、呼び出した関数の変数を直接操作出来ます。 これを構造体で出来ないでしょうか。 下記のプログラムで実験しました。(2)の所を色々と書き換えて試したのですが、エラーになります。 (1)は、エラーになりません。エラーで無く(2)の様に使えなければ、(1)の p はどのような使い道が有るのでしょう。 /*-----------------------------*/ struct Par { long a ; } ; /*-----------------------------*/ void sub1( struct Par *p ) ・・・(1) エラーにならない { p.a = 2 ; ・・・(2) 色々変えて試しても、エラーになる }
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
構造体のポインタへの各要素のアクセスにはアロー演算子を使用します。 p->a = 2; 変数のポインタと同じ用に*p.a = 2;も試したと思いますが、 こういう表記をする場合の場合、 (*p).a = 2; という表記になります。
その他の回答 (4)
- titokani
- ベストアンサー率19% (341/1726)
> 変数が少なければコンパイラはレジスタ渡しにするかなと思い実験しましたが、スタック領域を使っていました。 レジスタ渡しが有効なほど小さい関数なら、inlineが有効だと思います。 inlineが意味を持たないようなサイズの関数なら、せっかくレジスタ渡しにしても全体の高速化には貢献しないと思います。 C/C++の場合、人間があれこれ最適化を考えるよりも、いかにしてコンパイラに最適化をさせるかというテクニックが重要だったりしますね。 あと、static関数だと、呼び出し規約に縛られないので、レジスタ渡しに最適化してくれる可能性もありそうです。
お礼
回答有り難う御座います。 inline と static関数に付いて調べていたので、お礼が遅くなりました。 プログラム分割のために1箇所からしか使わない関数が多いので、inline は勉強になりました。 include で挿入した事も有ります。 static は変数だけでなく、関数でも使える事が分かりました。 有り難う御座いました。また質問したときは、宜しくお願いします。
- chie65536(@chie65535)
- ベストアンサー率44% (8802/19961)
>変数が少なければコンパイラはレジスタ渡しにするかなと思い実験しましたが、スタック領域を使っていました。 >「C言語で可能な事、不可能な事」が一つ分かり、勉強になりました。 「コンパイラ任せ」になってしまいますが、関数内で宣言する変数にregister修飾子を付加すると、高速なコードを生成する場合があります。 例: void sub(int para1,int para2) { register int eax = para1; register int ecx = para2; … 但し「場合がある」と言うだけなので「付けても付けなくても一緒」の場合もあります(例えば、速度最優先の最適化オプションを指定してコンパイルした時、など)
お礼
御回答有り難う御座います。 構造体に「register」は使えないだろうと思い実験してみましたが、 やはりエラーになりました。 三菱か何処かのCコンパイラの説明書に、「変数のアドレスが存在しないから、「&」が使えなくなるだけで、積極的にCPUのレジスタに割り当てる事はしていない」と言うような説明でした。
- php504
- ベストアンサー率42% (926/2160)
関数への引数の渡し方は呼出規約で決まっているため数が少ないからレジスタで渡すとか変わることはありません VisualC++なら呼出規約のfastcallを使えばレジスタ渡しになったと思います http://ja.wikipedia.org/wiki/%E5%91%BC%E5%87%BA%E8%A6%8F%E7%B4%84
お礼
回答有り難う御座いました。 「呼び出し規約」と言うのを初めて知りました。
- asuncion
- ベストアンサー率33% (2127/6290)
#1さんの補足です。 *p.a と書くと、*よりも.の方が優先順位が高いので、 *(p.a) という意味となります。 (*p).a と p->a とが同じ意味です。
お礼
asuncion さん、有り難う御座います。 パラグアイのアスンシオンに居たことが有るので懐かしいな。 >(*p).a と p->a とが同じ意味です。 アロー演算子を見た事は有るけれど、意味を深く考えた事が無かったので勉強になりました。 オパ! (パラグアイのグアラニー語で、「お終い」と言う意味)
お礼
有り難う御座います。この方法で解決しました。 「(*p).a = 2; 」も試したような気がするのですが、試していなかったようです。 構造体内の変数を増やして実験しました。アセンブル結果を見ると、期待通りの結果が得られました。変数はスタック領域に確保されていました。 実はアセンブラで書いたプログラムを、C言語に焼き直しています。 変数をレジスタ渡しで巧妙に作って有るのですが、レジスタの管理が面倒です。 C言語で書けばプログラムは長くなり、実行速度は遅くなると思いコンパイル結果を見て評価しています。 変数が少なければコンパイラはレジスタ渡しにするかなと思い実験しましたが、スタック領域を使っていました。 「C言語で可能な事、不可能な事」が一つ分かり、勉強になりました。 どうも有り難う御座いました。