プロが教えるわが家の防犯対策術!

ある変数に何かある値を設定する際にユーザ定義関数を作成・使用する場合に、 まずは関数内部で生成(計算)した値をその関数の戻り値にして設定対象変数に代入することを考えます。 「まずは」というのは、この作成指針で不都合が生じた場合には別の指針を検討することを意味します。 例えばint型変数xに、 乱数を設定する際にユーザ定義関数myRandを作成・使用する場合に、 まずは
int myRand(void){
int result;
/***乱数を計算してresultに設定するプログラム***/
return result;
}
のように関数myRandの内部で生成した値resultを戻り値にして、main関数などで
int x=myRand();
のように関数myRandの戻り値をint型変数xに代入することを考えます。そしてこの指針で目的を達成できるので別の指針を検討する必要はありません。

一方で、1回の関数呼び出しで配列の全要素に何かある値を設定するためのユーザ定義関数を作成・使用する場合には、 設定対象配列をユーザ定義関数の引数にします。 このとき、ユーザ定義関数内部で生成(計算)した値を戻り値にして 設定対象配列に代入することは考えません。 例えば数学ではベクトル値関数があり、, とすると、のように、5次元ベクトルを入力としてが何か5次元ベクトルを生成し、それをに代入することができます。 しかしながら、C言語では
/***何か関数fの定義***/
double x[5], y[5];
/***何かxの要素の設定***/
y=f(x);
のように書くことはできません。 その理由を説明して下さい。

上の問題を教えてもらえますでしょうか?

A 回答 (5件)

今は構造体の値返しは可能になりましたが、それ以前の話



関数から返る値はどこにあるか?

アセンブラベースで考えます
アキュムレータレジスタ(386系なら EAX RISC系ならR0) が関数の返り値を
置く場所であると決められました
レジスタ渡しです(レジスタ返しと言うべきか?)
レジスタには 整数か浮動小数点が1個しか入りません(bit幅は、、、)(ポインタの実態は整数です)
サブルーチンの呼ぶ側/呼ばれる側の関係をこう決めたのです
呼ばれる側としては、最後に何かやった結果はアキュムレータレジスタに入る事が大部分なので
返値受け渡し領域にコピーすると言う無駄な手間が省けます

・標準の返値受け渡し方式としてレジスタ渡しを採用する
・1個のレジスタで受け渡せる値は1個である

以上により Cの関数は、「返値を1個しか返せない」のです

→ この標準では出来ない事を開発したのが構造体の値返しですね
    • good
    • 0

回答になっていないこと予めお詫びします



Cはコンパイラ言語ですので、最終的には機械語に翻訳されます。
何か疑問に思ったら、質問する前にそのコードをコンパイルして機械語になった(アセンブラ言語になった)コードを読まれることおすすめします。
そうすれば、この種の疑問も、質問者さんが納得する形での説明が見つかる気がしています。
    • good
    • 0

#2 に勝手に補足すると, この質問文のケースの場合 ISO 規格では


構造体の中に配列を作る
ことで回避できなくもない.

たとえば
typedef struct {
double element[5];
} DArray5;
とかやればこの DArray5 はコピーできて, その結果として配列の全要素が勝手にコピーされる.
    • good
    • 0

malloc された領域に格納して、その領域のポインタを返せばいいだけです。


代替手段があるのに面倒な処理をするようなことはCはしません。
ANSIになってからは、コンピュータの処理能力が上がったので、
構造体のような大きなものも返却値にできるようにはなりましたが、
配列はサポートしていません。
そんなのが欲しいなら、ほかの言語なり、自作言語なりで、
自由に作ってくださいというのが、Cのスタンスです。

C++などの、vector などを使ってください。
    • good
    • 0

そのように設計されたから.

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!