重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

C言語の関数、変数の宣言について分からないことがあるので質問させてください。

int main(void){
int a;
int b;
return 0;
}

これと

int main(int a, int b){
return 0;
}

この関数は全く同じ内容になりますか?関数の()内に記述する意味がよく分かりません

A 回答 (7件)

>この関数は全く同じ内容になりますか?関数の()内に記述する意味がよく分かりません



「質問文に書いてある通りのこれらの関数」という意味であれば、実行結果は全く同じになります。また、最近のコンパイラは賢いので、恐らく実行コードそのものもどちらのソースコードからでもアキュムレータに0を代入(XOR EAX)するだけのシンプルなものになり、aやbなど完全に無視すると思います。

そうではなく、関数内でaやbを利用する場合であれば、これは意味が大きく違います。

まず、メモリの使い方で言えば、どちらの書き方でもローカル変数であるaとbとしてスタック領域にそれ用の領域が用意されます。なので、関数内ではどちらもただのローカル変数(ファンクションスコープの変数)として利用できます。ただ、関数の引数として宣言した場合、呼び出し元で関数を起動するときにそのスタック領域に値を書き込むことができます。

仮に関数を「func(int a, int b)」として、int aとint bを引数として取ることができるとすると、

func(1, 2);
func(3, 4);
func(5, 6);
と、func()関数を3回呼び出したとき、それぞれ違う処理が内部的に行われることになります。すなわち1つ目の場合はa=1, b=2と初期化された状態で、2つ目はa=2, b=4、3つ目はa=5, b=6という感じになります。これが、引数としてではなく関数の中でaとbを宣言する場合は、呼び出し元からaとbの値を制御することができません。もちろん、別の方法で制御可能ではありますが、このレベルの質問をしているあなたにはちょっと難しい話になります。
    • good
    • 0

関数名をmainにすると、話がややこしくなるので、


sample1,sample2とします。

int sample1(void){
int a;
int b;
return 0;
}
int sample2(int a,int b){
return 0;
}

上記の場合、どちらも、0を返すので、機能的には同じになります。
但し、呼び出し方が違います。
sample1は、引数を指定しません。
sample2は、引数を2つ指定します。

従って、正しい呼び出し方は以下のようになります。
sample1();
sample2(10,20);

以下は、誤った呼び出し方です。
sample1(10); ・・・・・引数を1つ指定している。
sample1(10,20); ・・・・引数を2つ指定している。
smaple2(); ・・・・・・引数を指定していない。
smaple2(10); ・・・・・・引数を1つ指定している。

では、以下のような場合、機能が同じになるかということですが、同じになりません。

int sample1(void){
int a;
int b;
return a+b;
}
int sample2(int a,int b){
return a+b;
}

smaple2の場合は、
sample2(10,20);
を実行すると、int aの値が10になり、int bの値が20になって、
sample2が呼び出されます。したがって、呼び出し元に30の値が返ります。

sample1の場合は、
sample1();
を実行すると、int a;の値、及びint b;の値は不定の状態です。
不定とは、値がいくつかわからないということです。
従って、int aの値は、0かも知れないし、3899かも知れないし、100000かも知れません。
int bの値も同様です。
従って、値のわからない同士を加算した結果の値は、いくつかわからない結果になります。
従って、呼び出し元に返る値は、わかりません。

従って、sample1とsample2の機能は同じではありません。
    • good
    • 1

関数を呼び出す側から見ると、両者に違いが出ます。



中括弧{}内は関数本体ブロックなので、
ブロック内でだけ使われるローカル変数を定義できます。
関数を呼ぶ出す側は、この変数を使えません。

## 例
int f() { int a = 1; int b = 2; return a+b; }
f(); ← OK
f(3,4); ← error: 関数を呼ぶ出す側から a,b を渡せない

小括弧()内は引数定義なので、
関数を呼ぶ出す側との I/F となる引数を定義できます。

## 例
int g(int a, int b) { return a+b; }
g(); ← error: 引数を要求されているのに渡していない
g(3,4); ← OK

引数は関数呼出規約やC++多重定義に影響する重要情報なので、
ローカル変数ですむ場合は引数として定義しないようにしましょう。
https://ja.wikipedia.org/wiki/%E5%91%BC%E5%87%BA …
https://ja.wikipedia.org/wiki/%E5%A4%9A%E9%87%8D …

余談ではありますが、

プログラム開始処理である特別な関数 main の仕様は、
以下の二通りの書き方のみと制限されていますので、
勝手に引数定義を変更しない様に注意してください。
int main(void)
int main(int argc, char *argv[])
    • good
    • 0

プログラム言語以前の数学の話だけど, 関数の「引数」(ひきすう, not いんすう) という言葉を聞いたことはありますか?



なお C の場合「main」という名前の関数は
・定義の形式が (数種類に) 固定されている
・ユーザーが記述したプログラム中最初に実行される
・最初の main の呼び出しから return するとユーザーの書いたプログラム全体が終了に向かう
・「int を返す」といっているにもかかわらず return 文がなくても許される
という特殊な点はあるけど, それでもまだ「ふつうの関数」ではある.

C++ だと「ふつう」じゃなくなる.
    • good
    • 0

私がよく使ってた時代の C では、


int main(int a, int b) と int main(int a, char **b) で同じことができたんだけど...
最近は、コンパイラでハネられるんじゃないかな。

int main(void) と int main(int a, int b) は、main からスタートアップルーチンへ
return したときのスタックの扱いが違うけれど、それで実害は特に起こらない。
    • good
    • 1

同じではありません。


前者はaとbの値は不定ですが、後者は呼び出し元の設定に従います。

ただ、C言語のmain関数は引数の型が決まっているので、思った通りの値は渡せていない事になるか、コンパイルが失敗します。
    • good
    • 0

> この関数は全く同じ内容になりますか?



なりません。
と言うか、後者はC言語だと「間違い」になる。

C言語のmain関数は特殊な関数で、アセンブリ言語なんかの用語では「エントリポイント」と呼ばれる部分を設定する為だけ、にあって、任意のint a、int bなんかの引数は自在には取れない。
    • good
    • 2

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

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A