• 締切済み

C言語:関数の返り値と引数について

C言語:関数の返り値と引数について C言語の関数を作るとき、ほしい値とかを引数にして渡す場合と、そのまま返り値で渡す場合の二種類がありますよね? 例えば、 ・void Smooth( Image *src, Image *dst, int param ); ・Image *Smooth( Image *src, int param ); みたいな感じで mallocとかは返り値で渡してますけど、opencvの関数(例えばcvSmooth)とかは引数にしてます これって使い分けとかあるんでしょうか?

みんなの回答

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

既にいろいろでているので、OpenCVに関して。 cvSmooth等はIn-Placeの変換(入力画像を結果を出力する)ができます。 他の(ガベージコレクション などで)自動解放する言語や、 = をオーバライドしてin-place版を実行できる言語なら src = Smooth(src) ; でもいいのですが、Cの場合、こんなことをしたら、実行前にsrcに入っていた領域が参照できなくなります。 参照できなければfreeできません。 void Smooth( Image *src, Image *dst, int param ); の型なら、 src == dst かどうかで、In-Placeかどうかを判定できます。

mist_to
質問者

お礼

なるほど 確かに、src=Smooth(src)の場合はそうなりますね 納得です ありがとうございました

  • php504
  • ベストアンサー率42% (926/2160)
回答No.5

関数内で動的に確保する場合はポインタで受けとれますがそうでない場合はポインタ引数で受け渡しになるということです

mist_to
質問者

お礼

あぁ、なるほど そういうことですか ありがとうございました

回答No.4

返すデータの数とか種類、意味合いとかによって様々でしょう。 (1)単独の値を返す場合  関数の返り値だけで事足ります。 (2)複数の結果を返さなければならない場合  構造体を返り値にするという方法もありますが、一般的な変数型の値が2、3個の場合は結果の格納先のポインタを貰う形の方がわかりやすいということもあります。 (3)ある程度の容量を必要とするデータを返す場合  関数内でmallocとかしてそのポインタを返すとかいう方法もありますが、返した先でメモリのサイズがわからないとか、freeし忘れがちになるとかいうことが起こるので、明示的に呼び元で領域確保した先に書き込む方が安全です。 (4)使い分け  関数の処理の成否を返り値で返し、処理結果そのものは指定のポインタ先に格納するというものもあります。  要は関数の設計しだいですが、一般的には(1)のような場合は返り値で返す方が好まれます。返り値で返した場合は関数の呼び出しそのものを分岐の評価式とすることができますが、アドレスを引数で渡すものはワンクッション置かなくてはなりません。(4)もそのような感じかな。

mist_to
質問者

お礼

なるほど… 確かに、処理の成否を返したりする場合は結構ありますね ありがとうございました

  • f272
  • ベストアンサー率46% (8019/17138)
回答No.3

戻したい値が二つ以上ある場合には,引数にする。 戻したい値が一つの場合には,戻り値にする。 というのが基本だと思います。とはいえ,これを無視して逆のやり方をすることも可能です。 戻したい値が二つ以上ある場合でも,構造体を用意して,関数内でその構造体に代入して戻り値にする。 戻したい値が一つの場合でも,引数にして戻り値を使わない。 結局のところ,ローカルルールで決めているだけですね。

mist_to
質問者

お礼

やっぱりローカルルールで決めてるだけなんですね ありがとうございました

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.2

特に規則はないと思います。好みの問題でしょう。 mallocの結果だって、引数で返す場合もあります。 void xx(void **p) {     *p = malloc(2048); }

mist_to
質問者

お礼

まぁそれは確かにできますね やっぱり好みの問題ですか ありがとうございました

  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

私は大きな構造体の場合はポインタの引数にして受け取ります (返り値で受け取ると値のコピーが無駄なので)

mist_to
質問者

お礼

それは返り値をポインタにすればいいような… ありがとうございました

関連するQ&A

  • C言語での関数の引数の受け渡しについて

    C言語での関数の引数の受け渡しについて教えてもらいたいのです。 char *p=Goo;  というポインタpがmain関数で定義され、このポインタpをある関数 void func(・・・) に渡すことは出来ますか? つまりポインタを実引数として扱うことはできるのかという事ですが・・・ int p=10; とかだったら、 void func(int test) の関数には、main関数で func(p) で仮引数testにわたせると思うんですが・・・ もし出来るようでしたら、関数の渡し方と定義の記述を教えてください。 どうか宜しくお願いします。

  • 返り値と引数が知りたいのですが。

    クラスCFileのメンバー関数の機能でOPENとREADの返り値と引数が知りたいのですが。 自分でも調べたんですが。 READの返り値はUINTで引数はvoid* pBufferとUINT nCountであってるでしょうか? OPENの返り値はBOOLでいいのでしょうか?引数がわかりませんでした。 それと機能の意味なんですがOPENはファイルを開く以外にも意味はあるのでしょうか。 よろしくお願いします。

  • C言語のポインタによる関数の引数の書き方について教えてください。

    C言語を今勉強中の大学生です。 一気に複数の値をmainに返せる、参照による呼び出しによる関数の引数の書き方で困っています。配列を自作関数に引き渡したいのですが、どう書けばいいのでしょうか。 下の3つは、それぞれ(1)mainからの呼び出し、(2)自作関数での引数の引き受け、です。どこをどう変えたらエラーが出なくなるのか、分かる方、お願いいたします! (1)school(&m,h); (2)void school(int *m, float *h){ ※ちなみに変数は int m,float h[10][10]

  • C言語です。コレを使ってなにかプログラミングを組んでください

    C言語です。コレを使ってなにかプログラミングを組んでください よろしくお願いします 何でも構いません #include<stdio.h> void str_copy( char dst[], char src[] ) { int i; for (i =0; src[i] != '\0'; i++) { dst[i] = src[i]; } dst[i]= '\0'; }

  • 値を返り値に返すのと参照渡しした引数に格納することの違い

    プログラミングをしていて、次のような2種類の形式の関数をみることがあります。 void sum(int a, int b, int& c); //aとbの和をcに格納する int sum(int a, int b); //aとbの和を返す 上の例のint &cは参照渡しされる引数という意味で、CやC++、PHPなどで同様です。 この、計算結果を参照渡しした引数に格納するのと、返り値に返すことの違いがよく分かりません。計算結果が複数ある場合は、前者の方が便利でしょう。しかし計算結果が1つだけなのに前者の方法を採っている関数も多く見かけます。個人的には、計算結果を返り値として返す後者の方法の方が感覚的に自然だと思うのですが、なぜ前者のような関数が存在するのか、教えていただきたく存じます。

  • C言語の標準関数の引数の順番について

    C言語標準関数の引数についての質問です。 strcpy、memsetなど C言語の標準関数の引数に注目したところ 前に出力パラメータを持ってきているものが多いように思えます。 例えば、 char *strcpy(char *dest, const char *src); の場合、 第1引数の"dest"が出力パラメータで 第2引数の"src"が入力パラメータとなっています。 入力よりも出力を前に持ってきている理由が何かあるのでしょうか。 今後、自分が設計をするときの参考にしたいと考えているので 理由を知っている方がいたら教えて下さい。

  • c言語

    (c++ではなくC89準拠) c言語について質問 (1) 関数名()と関数名(void)は違う意味 (2) mainの引数の型は(void)か(int argc, char *argv[]) (3) K&Rは標準c準拠でmain()という表記があります ということは、(1)の関数名とはmain以外の関数名で、 main()とmain(void)は同じなんでしょうか。

  • C言語の関数について。

    学校の課題がわからないので教えてください。 1. 次の関数recfunc()は関数内で自分自身を呼び出す再起関数である。 int recfunc(int x){ if(x<=0)return -1; else if(x==1) return 3; else return 3*recfunc(x-1)-2; } 引数に1,2,3,4,5,...を与えたときの返り値を求めよ。その結果から、一般に 整数値nが与えられたとき、どのような値が計算されるか推測せよ。 一体何を返す関数だろうか?またどのようにその計算が実現されているか を簡潔に述べよ。 2.どのような再帰関数も、再帰を用いない関数に書き換えることができる。 問題1の関数recfunc()と同じ引数、同じ返り値をもつ再帰を用いない関数 func()を作成せよ。 2問も質問してすみません。 このプログラミングのレポートを提出しなくてはならないので困ってます。 何卒よろしくお願いします。

  • C言語の関数の実引数と仮引数の名前について

     C言語で関数を使う場合、実引数と仮引数の名前(変数名)は、変えなければならないのでしょうか、同じでもいいのでしょうか。C言語のルールでは、どうなっているのでしょうか。よろしくお願い致します。

  • C言語(引数)

    はじめまして。 C言語を習い始めたものです。 関数を定義するとき、よく耳にする、仮引数や実引数があると思います。 仮引数は関数の定義内で値をうけとる変数のことであり 実引数は関数を呼び出す際に渡す値を実引数というらしいのですが どこからどこまでを仮引数と呼ぶのかわかりません。 例えば、 fの関数の定義内で ↓があるとします。 (関数にする意味はないのですが、確認のためあしからず・・・) double f(double x) {     x=5;     return(x); } この場合、仮引数とよばれるものは double f(double x)の xが仮引数であって x=5;のxは仮引数と呼ばないのでしょうか?? もしそうならば void f(double x) { printf("%f",x); } のprintf("%f",x);内のxは仮引数とよぶのでしょうか? 質問の内容が意味不明かもしれませんが よろしくお願いします。

専門家に質問してみよう