ページ 1 / 1
引数を減らす方法
Posted: 2011年4月30日(土) 01:40
by paw
何か月か以前にscanfについて質問させていただいた者です。
その時は「C初心者」という名前で質問させていただきました。
今回、どうしても解決できないことが再び発生しまして、質問させていただきます。
タイトルの通り、関数での引数の減らし方についてです。
ある関数で定義された変数を、他の関数をまたいで三つ目の関数へと持っていく時、全ての関数で引数を定義しなければなりませんよね。
グローバル変数を使わない前提で、どうにかして引数の数を減らすことができないものでしょうか?
例えば、下記のコードでmain関数内で定義されたhogeをfunc2まで持っていきたい場合のことですが、
コード:
#include <stdio.h>
int func2(int hoge_f2){
printf("hoge:%d",hoge_f2);
}
int func1(int hoge_f1){
func2(hoge_f1);
}
int main(void){
int hoge = 100;
func1(hoge);
}
と、func1,func2において二度にわたって引数を定義しなければなりません(実際にはプロトタイプ宣言を使ったり何度も呼び出したりするでしょうからもっと面倒なことになります)
直接func2を呼べばいいとかそういうことではなく、func1からfunc2を呼び出したいのです。
グローバル変数を使わずに、もっとうまく変数の寿命を操作する方法はないものでしょうか?
まだ初心者なもので、動的確保やリスト構造といった難しいそうな所はほとんど使い方が分かりません。
しかし、そういったところにこの問題を解決する手掛かりがありそうなので、質問させていただきました。
どうぞ何方かご教授ください。
Re: 引数を減らす方法
Posted: 2011年4月30日(土) 02:06
by a5ua
示されたコードでは、何が問題なのかよくわかりませんでした。
func1()は、int型変数を1個必要としているのでしょうし、func2()も同様です。
必要としている引数を書かないわけにはいきませんよね。
どのような結果を得たいのかもう少し具体的に教えてもらえませんか?
Re: 引数を減らす方法
Posted: 2011年4月30日(土) 02:21
by paw
説明不足でしたか、申し訳ありません。
要するに引数を使わずに関数間のデータをやりとりするか、引数をつかいながらも必要としている引数を書かずに使える方法がないものかと思い質問させていただきました。
勿論グローバル変数は使わない前提です。
無いというのなら上級者の方々はどのようにしてこれらの処理をされているのでしょうか?
上級者の方々が何度も同じことを書くという作業をされているとはどうしても思えません。
Re: 引数を減らす方法
Posted: 2011年4月30日(土) 03:03
by a5ua
すいません。まだよくわかりません。
>関数間のデータのやりとり
これは、どのようなことを指しているのですか?
>引数をつかいながらも必要としている引数を書かずに
矛盾しているように思います。そもそも関数に書かれていない引数を使うことは出来ません。
Re: 引数を減らす方法
Posted: 2011年4月30日(土) 03:48
by パコネコ
クラスなら同じクラス内の変数いじれますよ。
ただクラスはc++だった気がしますが。
(勉強中だから間違ってたらごめんなさい。)
減らすのと0にするのではちょっと違う気もしますが…
引数の数が2個以上なのを減らすのはできますよ。
(無理矢理ですが、*0個にはならないけど)
Re: 引数を減らす方法
Posted: 2011年4月30日(土) 09:36
by Dixq (管理人)
残念ながら面倒でも一つずつ関数に値を渡していく方が安全かと思います。
C++であればパコネコさんが仰るようにメンバ変数を使ってクラス間で同じ変数が参照出来ますが。
また、C++であればシングルトンを使う手もあります。
グローバル変数を使わずにということなので、反則かもしれませんが、
最初に作ったモジュールにポインタを渡しておくという手もあります。
プロジェクトファイルをこちらに用意しました。
http://dixq.net/code/Sample10.zip
[ sample.h ]
コード:
void SetPointer( int *p );
void func1();
[ sample.c ]
コード:
#include <stdio.h>
static int *ptr;
void SetPointer( int *p ){
ptr = p;
}
void func2(){
printf("%d\n", *ptr);
}
void func1(){
func2();
}
[ test.c ]
コード:
#include "sample.h"
int main(){
int a = 20;
SetPointer( &a );
func1();
return 0;
}
減らすということであれば構造体などにすることで引数を減らすことは出来るでしょう。
Re: 引数を減らす方法
Posted: 2011年4月30日(土) 09:43
by たかぎ
paw さんが書きました:勿論グローバル変数は使わない前提です。
単にグローバル変数を使わなければよいのであれば、次のようにすれば実現できます。
コード:
int *get_hoge(void)
{
static int hoge;
return &hoge;
}
あとは、*get_hoge()をグローバル変数と同じように使いまわせばよいのです。
それで済むのかどうか知りませんが...
Re: 引数を減らす方法
Posted: 2011年4月30日(土) 15:02
by paw
ご回答ありがとうございます。
>>C++なら
せっかく回答いただいたのに申し訳ありませんがまだC++はわかりません。
しかしこういったことは解消されているらしい?(気がする)ので近い将来やってみたいです。
その時に改めて参考にさせていただきます。
>>最初に作ったモジュールにポインタを渡しておくという手
サンプル拝見しました。
わざわざありがとうございます。
staticグローバル変数なんて知りませんでした。ありがとうございます。
smaple.c内で留めるローカル変数っぽいグローバル変数を使う訳ですか。
参考になる方法ですが、ややこしすぎることと、func2をsample内に入れなければならないことが問題かもしれません
>>構造体
それは理解しています。
ご承知の事と思いますが、それをした上でのことですので。
>>*get_hoge()をグローバル変数と同じように使いまわす
これはグローバル変数とまったく同じことができますね。
参考になります。ありがとうございます。
皆様に色々な方法を教えて頂きましたが、
>>それで済むのかどうか知りませんが...
>>残念ながら面倒でも一つずつ関数に値を渡していく方が安全かと思います。
>>減らすということであれば
という言葉から、どうもこれらの方法はそう使われてはいないのではないかと感じました。
特に「残念ながら面倒でも一つずつ関数に値を渡していく方が安全かと思います」
結局のところ、きちんと計画してから作り始めればこんなことで問題になることは無いということでしょうか?
上級者の方はどうしているのか、と自分が書きましたが、これが結論という事でしょうか。
Re: 引数を減らす方法
Posted: 2011年4月30日(土) 15:31
by softya(ソフト屋)
paw さんが書きました:という言葉から、どうもこれらの方法はそう使われてはいないのではないかと感じました。
特に「残念ながら面倒でも一つずつ関数に値を渡していく方が安全かと思います」
結局のところ、きちんと計画してから作り始めればこんなことで問題になることは無いということでしょうか?
上級者の方はどうしているのか、と自分が書きましたが、これが結論という事でしょうか。
どの関数がどの変数の内容を変更するかは出来るだけ明確にしないとバグの原因になります。
グローバル変数は、関数の呼び出し側のコードを見ただけでは何の変数が変更されるか分かりません。
引数や戻り値だと関数の呼び出し側のコードで引数で渡した物、返ってくるものが明確になるからです。
なので、グローバル変数が敬遠されて引数や戻り値による受け渡しが推奨されているわけです。
上級者が目指すのは、変数の変更の範囲の明確化、及び変数の受け渡す範囲のできるだけの局所化です。
これらはバグを減らし、修正を容易にします。
[追記]
paw さんが書きました:しかしこういったことは解消されているらしい?(気がする)ので近い将来やってみたいです。
C++のオブジェクト指向で求められるのは、よりパッケージ化、カプセル化した設計ですよ。
Re: 引数を減らす方法
Posted: 2011年4月30日(土) 15:53
by paw
どの方法を使うべきなのかという事も大体理解できました。
回答くださった皆様、ありがとうございました。
Re: 引数を減らす方法
Posted: 2011年4月30日(土) 15:56
by softya(ソフト屋)
OKなら解決チェックをよろしくお願いしますね。
Re: 引数を減らす方法
Posted: 2011年4月30日(土) 16:02
by paw
失礼しました