• ベストアンサー

C言語 関数の戻り値と自動変数

hi-mi-tsuの回答

回答No.8

> 現実的に考えると、プログラムが関数から出て、呼び出した側の関数が戻り値を受け取るまでの瞬間に、その領域が書き換えられる可能性は極めて低いと思うのですけど、C言語の仕様としてはどうなのでしょうか? この問題はマルチスレッドにしない限り起りません。 (厳密には他にもあると思いますが) > 関数内で宣言した戻り値に使う変数には、必ずstaticをつけた方が良いのでしょうか? 基本的にする必要はないと思いますが、 ケースバイケースだと思います。 個人的に必要がある思うケースは、 ある関数とあるデータの関係を密接にしたい場合は必要だと思います。 staticの変数を返す関数ではないですが string.h にある、strtokとstrtok_rの違いについて考えてみてください。 strtokは確実に、staticな変数を使っています。 (もしかするとスレッドローカル変数かもしれませんが)

tadasuke2002
質問者

お礼

マルチスレッドを考慮に入れていたわけではないので、基本的には心配する必要がないということですね。 いろいろと勉強になりました。 ご返答ありがとうございます。

関連するQ&A

  • C言語 関数の戻り値について

    C言語で関数を作る場合に最後にreturnで戻り値を設定しますよね? 自分はあまりそれがわかりません。 関数で出た答えを返すって言うのはわかるんですが、 returnが無くても大丈夫だったりreturnはあってもその後に戻り値を設定していなかったり。 何故returnがなくても動作するのでしょうか? 何故returnまであるのに戻り値は設定されていないのか? 教えてください。

  • C言語のStatic変数について

    現在、C言語の勉強しながらゲームプログラムにチャレンジしています。 二つの関数で利用する変数を作りたかったので、Static宣言された変数を容易しました。 ですが、この変数、一度処理が終わると当面使わない変数なのです。 (ただし、処理途中は何度も呼び出されるので値は保持しなければいけません) よって、メモリ上に延々居座られるのが邪魔に思えて仕方ありません。 実際、大したことないだろうとは思うのですが。 このStaticで宣言された変数を、自分の好きなタイミングでメモリ上から解放するような処理はできませんか? もしくはメモリ上に居座ることのない処理の仕方などありましたら、 考え方を教えていただけるとうれしいです。よろしくお願いします。

  • 関数内、ファイルのstatic変数

    関数内で、static変数を宣言した場合に、その値は保持されると 思いますが、その関数の外からポインタで見る場合にその値は 保証されるのでしょうか? (必ず同じメモリ上に配置されるのでしょうか?) また、関数とファイル内static変数においてスコープ以外に 取り扱いが変わったりするのでしょうか? (配置されるメモリ空間等) よろしくお願い致します。

  • 戻り値で返したオブジェクトの寿命について

    Ruby初心者です。 【前置き】 メソッドで宣言した変数(以下arr)に値(以下[1,2,3])を代入し戻り値として返した場合、 メソッドの戻り値(以下retArr)には、[1,2,3]への参照(arr.object_id)が設定されると認識しております。 ----------------------- def method arr = [1,2,3] return arr end retArr = method() ----------------------- 【質問】 C言語の場合、関数内で宣言したローカル変数のアドレスを戻り値として返却した場合、 関数を抜けた時点で、そのアドレスの内容は保障されなくなりますが、 1.Rubyではその様な問題がなく動作するのは、何故でしょうか? 2.また、メソッド内で宣言したオブジェクト(上記[1,2,3])の寿命はいつまでなのでしょうか? 【備考】 いろいろと調べてみたのですが、オブジェクトの参照(object_id)は、ポインタに近い概念であることは記載されているのですが、その仕組みを理解できずに悩んでします。

    • ベストアンサー
    • Ruby
  • 関数への変数の受け渡しについて

    関数に変数を受け渡すとき、配列とそれ以外の変数では受け渡すものが違いますよね。 変数の場合は、変数の値を関数側の変数にコピーする。 配列の場合は、配列そのもの(配列のポインタ)を関数に渡す。 なぜ配列の場合は値のコピーではなくて、ポインタを渡す仕様になっているんでしょうか。 ひとつめは、どのような意図でそのような仕様になっているのかという質問です。 もうひとつは、関数に配列の値だけを渡すにはどうすればいいのか、つまり元の配列のほうの値は書き換えないで欲しいというときはどうすればよいのかという質問です。 よろしくおねがいします。

  • 関数内で数値入力したときの戻り値は?

     数値を入力して変数に格納する、という作業を複数回繰り返すような数値入力のための関数をつくったとします。そのような場合、関数の宣言や戻り値はどのようにすればよいのでしょうか?  グローバル変数を用いたときにはうまくいったのですが、ローカル変数にかえようとしたらmain関数の中で値が割り当てられていません、となってしまいました。  教えてください。お願いします。

  • 関数の戻り値による変数の初期化

     関数の戻り値で変数を初期化すると、予期せぬ動作をする可能性があると聞いたのですが、実際にそのようなことがあるのでしょうか? また、予期せぬ動作をする場合、そのような現象が起きる環境と原因は何なのでしょうか?    使用している言語はC++なので、例えば下のような動作です。   int a = f();   ・対象の関数が標準関数かどうかは不明です。   ・変数はローカルを想定しています。  ちなみに私は、C,C++を2,3年勉強しており、会社での実践経歴が1年程度です。

  • C言語のメモリ領域確保

    ポインタ変数ををmain関数で宣言し、関数test()にて必要分だけ領域確保してそのアドレスをmain関数のポインタ変数に渡して利用することは可能でしょうか。 (サイズのわからないテキストデータを、十分に大きな配列に入れるのではなく、関数でメモリを動的確保して無駄の無い配列に入れたい等) C言語ではやはり無理で、構造体のリストにするのが一番でしょうか。 初歩的なことで申し訳ありませんがどなたかお願いいたします。

  • プロトタイプ宣言について

    C言語で関数を作成しプロトタイプ宣言するときの質問です。 関数実体の引数に構造体のポインタを宣言します。 プロトタイプ宣言には,構造体のポインタを宣言したのと同じ位置にvoid *を宣言します。 関数実体とプロトタイプ宣言は,異なるファイルです。 このように作成した関数は,VC++2008では,コンパイルできるのですが, なぜ関数実体の宣言とプロトタイプ宣言の型が異なるのにコンパイルできるのでしょうか? また,この関数を別ファイルの関数から呼び出した場合,正しく引数を理解し,正しく処理されます。 これは,言語仕様として正しい書き方なのでしょうか? それとも環境依存の書き方なのでしょうか? ご存知の方がいましたらお答えお待ちしています。

  • スプレッドシートのGASの関数で複数戻り値取得

    googleのスプレッドシートを使っています。 Google Apps Scriptでデータの取得を行っているのですが、 1つの関数から複数の戻り値を得るような方法はありますでしょうか? マイコンのC言語などをやった際に、ポインタ変数を関数の引数に設定して、その関数の引数に配列変数などをアドレス指定で設定することで複数の戻り値を得るような方法があったと思うのですが、GASでも同様の方法などはありますでしょうか? どうぞ、ご教示の程よろしくお願い致します。