ID非公開

2020/9/21 14:23

66回答

C原語について質問です。 構造体は関数の引数で値渡しできますが、配列はできないのでしょうか?

C原語について質問です。 構造体は関数の引数で値渡しできますが、配列はできないのでしょうか?

C言語関連 | プログラミング83閲覧xmlns="http://www.w3.org/2000/svg">25

ベストアンサー

1

構造体では出来るのに、配列ではなぜできないのか? そこには、技術的な理由は無く、そういうふうに作ったからそうなった。 というだけなので、「なぜ」を追求しても何も得られません。 C言語的には、そもそも配列演算とはポインタ演算のシンタックスシュガーであり、 配列自体、実は存在していないというような、作りの言語です。 C言語的には プリミティブな型も、 構造体も、 ポインタ型も、 全て値渡しで行われます。 仕様としては全部同じです。

1人がナイス!しています

ID非公開

質問者

2020/9/21 17:26

構造体だけはmempyして渡しているような感じなので、他とは明らかに動きが違いませんか?

ThanksImg質問者からのお礼コメント

皆さんありがとうございました。

お礼日時:9/24 20:51

その他の回答(5件)

0

そもそもの話として、C言語は『配列』というモノを ・ポインタ ・自動的に確保される領域 ・オフセットを計算する演算子 という3つの要素で表現しています。 「表現している」だけで「そのような実体がある」わけではなく、また「実体のないもの」を引数にすることはできないのです。

0

C言語は、低級言語(それより低級な(機械語に近い)言語は、アセンブラしかないくらいの)をコンセプトに開発されてますので、スタックメモリ、ヒープメモリなどのハードウェアに近いことも、気にしながら使う必要があります。関数は、その関数が使ったスタックメモリは、その処理が完了したときに、すべて解放してしまうという仕様が、配列を返り値にできないことに、大きく関係していると考えられます。 なので、配列をヒープメモリに領域確保すれば、配列を関数の返り値にすることができます。malloc()関数を使う、というわけですね。サンプルコードを示します。 #include <stdio.h> #include <stdlib.h> int *add(int n, int number) { int *value = (int *)malloc(sizeof(int) * number); for (int i = 0; i < number; i++) { value[i] = n; } return value; } int main() { int *value = add(4, 10); int i; for (i = 0; i < 10; i++) { printf("%d: %d\n", i, value[i]); } free(value); return 0; } 注:最後にfree()関数で、解放することをお忘れなく。 まあ、int value[10]; という宣言はできませんけどね。 なお、上のサンプルコードは、ヒープメモリを使わないのであれば、以下のように書くのが、ふつうだということは、ご存知のとおりです。 #include <stdio.h> void add(int n, int *temp, int number) { int i; for (i = 0; i < number; i++) { temp[i] += n; } } int main() { int value[10]; int i; for (i = 0; i < 10; i++) { value[i] = 0; } add(4, value, 10); for (i = 0; i < 10; i++) { printf("%d: %d\n", i, value[i]); } return 0; } 配列も含めて、ポインタは関数の引数に渡します。

0

配列だと、実体の大きさが限定できないので、 出来ません。 アセンブラコードに落とせなくなります。

ID非公開

質問者

2020/9/22 0:44

hoge[8]とか書いて渡せれば問題無くないですか?

0

逆に構造体を値渡しにする方が後付けだと思います。 40年前までそんな使い方は無かったような気がします。 値渡しだろうがポインタ渡しだろうがメモリ上で渡すのは変わりが無くて値渡しだとスタック上にコピーして使っているだけです。 つまりあまり大量の引数には値渡しは向いてないと言う事です。そこで配列を値渡しにしてしまうと効率が悪いしメモリのreallocなどの対応が難しいかと思います。

0

できません。 渡されるのは配列の先頭アドレス、すなわちポインタになるので。

ID非公開

質問者

2020/9/21 14:36

なぜ構造体だとできるのですか? 構造体引数の場合、コンパイラはスタック域に大量コピーするマシンコードを吐いているわけですよね?配列でできない理由が無いと思いませんか?