cのint mainは何を意味しますか? int main() と int main(void) の違いは? 仮パラメータと実パラメータ

機能メイン。

すべての C および C++ プログラムには main 関数が必要です。 そしてそれをどこに置くかはあなた次第です。 これをファイルの先頭に配置するプログラマもあれば、ファイルの最後に配置するプログラマもいます。 ただし、その位置に関係なく、次の点に注意する必要があります。 「main」関数の引数。 Borland C++ の開始プロシージャは、argc、argv、env という 3 つのパラメータ (引数) を main 関数に送信します。 - argc (整数) は、main 関数に送信されるコマンド ライン引数の数です。 - argv は、文字列 (char *) へのポインターの配列です。 DOS 3.x 以降では、argv は起動するプログラムのフルパスとして定義されます。 以前のバージョンの DOS で実行している場合、argv はヌル文字列 ("") を指します。 argv は、プログラム名の後の最初のコマンド ライン行を指します。 argv は、プログラム名の後の 2 番目のコマンド ライン行を指します。 argv は、main に送信される最後の引数を指します。 argv には NULL が含まれています。 - env も文字列へのポインタの配列です。 各 env 要素には、ENVVAR=value 形式の文字列が含まれます。 ENVVAR は、PATH や 87 などの環境変数の名前です。<значение>これは、特定の環境変数の値です。たとえば、C:\DOS;C:\TOOLS (PATH の場合) または YES (87 の場合) です。 ただし、これらの引数の一部を指定する場合は、argc、argv、env の順序で指定する必要があることに注意してください。 たとえば、次の引数宣言は有効です。 main() main(int argc) /* 有効ですが、あまり良くありません */ main(int argc, char *argv) main(int argc, char *argv, char *env) Main (int) 宣言 argc) は、パラメーターの数がわかっていても、自分でアクセスできないため、あまり便利ではありません。 env 引数には、environ グローバル変数を通じて常にアクセスできます。 environ 変数 (第 3 章) と putenv および getenv 関数 (第 2 章) を参照してください。 argc パラメーターと argv パラメーターは、_argc 変数と _argv 変数を通じても使用できます。 argc、argv、env を使用したプログラム例。 これはサンプル プログラム ARGS.EXE で、main 関数に渡される引数を使用する最も簡単な方法を示しています。 /* ARGS.C プログラム */ #include #含む void main(int argc, char *argv, char *env) ( int i; printf("argc の値は %d \n\n",argc); printf("コマンド ラインには %d パラメータが含まれています \n\ n" ,argc); for (i=0; i<=argc; i++) printf(" argv[%d]: %s\n",i,argv[i]); printf("Среда содержит следующие строки:\n"); for (i=0; env[i] != NULL; i++) printf(" env[%d]: %s\n",i,env[i]); return 0; } Предположим, что вы запускаете программу ARGS.EXE со следующей командной строкой: C:> args first_arg "空白を含む引数" 3 4 "最後から 1 つ" 停止! プログラム呼び出しの「空白を含む引数」と「最後から 1 つ」の例に示すように、二重引用符で囲むことにより、空白を含む引数を送信できることに注意してください。 プログラムを実行すると、次のような結果が得られます。 argc の値は 7 です。 コマンド ラインには 7 つのパラメータが含まれています。 argv: c:\turboc\testargs.exe argv: first_arg argv: arg withblank argv: 3 argv : 4 argv: 最後から 1 つ argv: やめてください! 環境には次の行が含まれています。 env: COMSPEC=C:\COMMAND.COM env: PROMPT=$p $g env: PATH=C:\SPRINT;C:\DOS;C:\BC コマンド ラインの最大合計長main 関数に送信されるメッセージ (スペースとプログラム自体の名前を含む) は 128 文字を超えることはできません。 これらは DOS の制限です。 コマンド ラインのエスケープ文字 コマンド ライン引数にはエスケープ文字を含めることができます。 ただし、DOS の copy コマンドなどと同じ方法で、引数に一致するすべてのファイル名を展開できます。 エスケープ記号を使用するには、リンカーを使用してプログラムをリンクするときに、Borland C++ に付属の WILDARGS.OBJ オブジェクト ファイルをインクルードする必要があります。 WILDARGS.OBJ ファイルがプログラムに添付されている場合は、コマンド ラインで「*.*」のような引数を使用できます。 この場合、このマスクに一致するすべてのファイルの名前が argv 配列に入力されます。 argv 配列の最大サイズは、動的メモリ領域のサイズのみに依存します。 指定されたマスクに適したファイルが見つからなかった場合、引数はコマンド ラインに入力された形式で渡されます。 (つまり、main 関数にはエスケープ文字を含む文字列が渡されます)。 二重引用符 ("...") で囲まれた引数は展開されません。 例。 次のコマンドは、ARGS.C ファイルをコンパイルして WILDARGS.OBJ モジュールにリンクし、結果の ARGS.EXE プログラムを実行します。 bcc args wildarg.obj args C:\BORLANDC\INCLUDE\*.H "*.C" ARGS.EXE を実行すると、最初の引数は、Borland C++ INCLUDE ディレクトリ内の拡張子 H を持つすべてのファイルの名前に展開されます。 すべての行に完全なルートが含まれていることに注意してください (たとえば、C:\TC\INCLUDE\ALLOC.H)。 *.C 引数は展開されません。 引用符で囲まれます。 統合環境 (BC.EXE) で作業している場合は、プロジェクト メニューでプロジェクト ファイルの名前を指定するだけです。このファイルには次の行が含まれている必要があります。 ARGS WILDARGS.OBJ 次に、「Run/Arguments」コマンドを使用して、 " コマンドを使用する場合は、コマンド ライン パラメータを設定する必要があります。 コメント。 エスケープ文字の処理を常に実行したい場合、つまり WILDARGS.OBJ がリンク エディターによって自動的にリンクされるようにするには、標準 C?.LIB ライブラリを変更してファイル WILDARGS.OBJ を含める必要があります。 これを行うには、SETARGV をライブラリから削除し、WILDARGS を追加します。 これは、次のコマンドで実行できます (標準ライブラリと WILDARGS.OBJ が現在のディレクトリに含まれていることを前提としています): TLIB については、『ユーザー ガイド』の第 7 章「ユーティリティ」で説明されています。 tlib cs -setargv +wildargs tlib cc - setargv +wildargs tlib cm -setargv +wildargs tlib cl -setargv +wildargs tlib ch -setargv +wildargs -p スイッチを使用したコンパイル (Pascal 呼び出し規約) Pascal 呼び出し規約 (第 9 章で詳しく説明) を使用してプログラムをコンパイルする場合「アセンブリ言語とのインターフェース」、「プログラマーズ ガイド」) では、main 関数は C 関数として明示的に宣言する必要があることを覚えておく必要があります。これは次のように実行できます。 キーワード cdecl は次のようなものです。 cdecl main(int argc, char *argv, char *env) main 関数によって返される値。 main 関数は、プログラムの終了コードである値 (整数) を返します。 ただし、プログラムが exit (または _exit) 関数を使用して終了する場合、戻り値はその関数の引数になります。 たとえば、プログラムに exit(1) という呼び出しが含まれている場合、終了コードは 1 になります。Borland C++ 統合環境 (BC.EXE) を使用してプログラムを実行すると、メイン関数の戻り値を確認できます。 「ファイル | 情報を見る」を選択して機能します。

53/85 ページ

1.5.3. main関数にパラメータを渡す

C プログラムの実行を開始する main 関数は、コマンド ラインなどの外部環境から渡されるパラメーターを使用して定義できます。 外部環境にはデータ表現に関する独自のルールがあり、すべてのデータは文字列の形式で表現されます。 これらの文字列を main 関数に渡すには、2 つのパラメータが使用されます。最初のパラメータは送信する文字列の数を送信するために使用され、2 番目のパラメータは文字列自体を送信するために使用されます。 これらのパラメータの一般的な (ただし必須ではない) 名前は argc と argv です。 argc パラメータは int 型で、その値はコマンド ラインの分析から形成され、呼び出されるプログラムの名前を含むコマンド ラインの単語数と等しくなります (単語とは、スペースを含まない任意のテキストです)キャラクター)。 argv パラメータは文字列へのポインタの配列であり、各文字列にはコマンド ラインからの 1 つの単語が含まれます。 単語にスペース文字を含める必要がある場合は、コマンド ラインに書き込むときに単語を引用符で囲む必要があります。

main 関数は、通常 argp と呼ばれる 3 番目のパラメータを持つこともでき、C プログラミング言語でプログラムが実行されるオペレーティング システム (環境) のパラメータを main 関数に転送するのに役立ちます。

メイン関数のヘッダーは次のようになります。

たとえば、C プログラミング言語のプログラムのコマンド ラインが次のようになっているとします。

A:\>cprog は「C プログラム」を実行しています 1

この場合、引数 argc、argv、argp は、図 1 の図に示すようにメモリ内に表現されます。

引数[4]
引数 --> -->
-->
-->
-->
argp --> -->
-->
-->
-->
図1。 コマンドラインオプションのレイアウト

オペレーティング システムは、パラメーター argc、argv、argp の値の受け渡しをサポートしています。実際の引数を main 関数に渡して使用するのはユーザーの責任です。

次の例は、オペレーティング システムから main 関数に渡される実際の引数とオペレーティング システム パラメータを出力するプログラムです。

例:
int main (int argc、char *argv、char *argp)
( int i=0;
printf("\nプログラム名 %s", argv);
for (i=1; i>=argc; i++)
printf("\n 引数 %d は %s", argv[i]);
printf("\nオペレーティング システムの設定:");
while (*argp)
( printf ("\n %s",*argp);
argp++;
}
リターン(0);
}

オペレーティング システムのパラメーターには、geteuv ライブラリ関数を使用してアクセスすることもできます。そのプロトタイプは次のようになります。

char *geteuv (const char *varname);

この関数の引数は環境パラメータの名前を指定します。このパラメータの値へのポインタが geteuv 関数によって返されます。 指定されたパラメータが環境内で現在定義されていない場合、戻り値は NULL です。

geteuv 関数で取得したポインターを使用すると、オペレーティング システム パラメーターの値を読み取ることのみができますが、変更することはできません。 puteuv 関数は、システム パラメーターの値を変更するために使用されます。

C プログラミング言語コンパイラーは、プログラムの先頭で何らかの初期化が実行されるような方法で C プログラムを構築します。これには、主な関数に渡される引数の処理や環境パラメーターの値の受け渡しなどが含まれます。 これらのアクションは、コンパイラによって常に main 関数の前に配置されるライブラリ関数 _setargv および _seteuv によって実行されます。

C プログラミング言語のプログラムが引数やオペレーティング システム パラメーターの値の受け渡しを使用しない場合は、プログラミング言語の C プログラムにライブラリ関数 _setargv および _seteuv を配置して、ライブラリ関数の使用を禁止することをお勧めします。 main 関数の前に、同じ名前を持つ、アクションを実行しない関数 (スタブ) があります。 この場合、プログラムの先頭は次のようになります。

setargv()
}
-seteuv()
( return ; /* 空の関数 */
}
int main()
( /* 引数なしの main 関数 */
...
...
レンルン(0);
}

上記のプログラムでは、ライブラリ関数 _setargv および _seteuv を呼び出すときに、ユーザーがプログラム内に配置した関数が使用され、何も実行されません。 これにより、生成される exe ファイルのサイズが大幅に削減されます。

Borland C++ は、main() に対する 3 つの引数をサポートしています。 最初の 2 つは従来の argc と argv です。 これらは、ANSI C 標準で定義されている main() の唯一の引数であり、コマンド ライン引数をプログラムに渡すことができます。 コマンド ライン引数は、オペレーティング システムのコマンド ライン上のプログラム名に続く情報です。 たとえば、プログラムが Borland ライン コンパイラを使用してコンパイルされる場合、通常は bcc と入力されます。 プログラム名

どこ プログラム名コンパイルが必要なプログラムです。 プログラム名は引数としてコンパイラに渡されます。

argc パラメータにはコマンド ライン引数の数が含まれており、整数です。 プログラム名が最初の引数として適格であるため、これは常に少なくとも 1 に等しくなります。 argv パラメータは、文字ポインタの配列へのポインタです。 この配列の各要素はコマンド ライン引数を指します。 すべてのコマンドライン引数は文字列です。 すべての数値はプログラムによって内部形式に変換されます。 次のプログラムは、プログラム名の直後にユーザー名を入力すると、「Hello」の後にユーザー名を出力します。

#含む

{
if(argc!=2)
{
printf("名前を入力するのを忘れました\n");
1 を返します。
}
printf("こんにちは %s", argv);
0を返します。
}

このプログラム名をユーザー名 Sergey とすると、プログラムを開始するには次のように入力する必要があります。
名前はセルゲイ。
プログラムの結果として、次のものが表示されます。
「こんにちは、セルゲイ。」

コマンドライン引数はスペースまたはタブで区切る必要があります。 カンマ、セミコロン、および類似の文字は区切り文字とみなされません。 例えば:

3行で構成されていますが、

ハーブ、リック、フレッド

これは 1 行です。カンマは区切り文字ではありません。

スペースまたはタブを含む文字列を単一の引数として渡す必要がある場合は、それを二重引用符で囲む必要があります。 たとえば、これは 1 つの引数です。

"これはテストです"

argv を正しく宣言することが重要です。 最も典型的な方法は次のとおりです。

空の括弧は、配列が固定長ではないことを示します。 アクセスできます 個々の要素 argv インデックスを使用します。 たとえば、argv は最初の行を指し、常にプログラム名が含まれます。 argv は次の行を指します。以下同様です。

以下はコマンドライン引数の使用例です。 コマンドラインで指定された値からカウントダウンし、ゼロに達すると信号を発します。 最初の引数には、標準の atoi() 関数を使用して整数に変換された数値が含まれることに注意してください。 文字列「display」が 2 番目の引数として存在する場合、カウンター自体が画面に表示されます。

/* カウントプログラム */

#含む
#含む
#含む
int main(int argc, char *argv)
{
int disp、カウント;
if(argc<2)
{
printf("カウントの長さを入力する必要があります\n");
printf("コマンド ライン上です。もう一度お試しください。\n");
1 を返します。
}
if (argc==3 && !strcmp(argv,"display")) disp = 1;
それ以外の場合は disp = 0;
for(count=atoi(argv); count; -count)
if (disp) printf("%d ", count);
printf("%c", "\a"); /* ほとんどのコンピュータではこれは呼び出しです */
0を返します。
}

引数を指定しない場合はエラーメッセージが表示されますのでご注意ください。 これは、正しい情報なしでプログラムを実行しようとした場合に、コマンド ライン引数を使用して命令を発行するプログラムで最も一般的です。

個々のコマンド ライン文字にアクセスするには、argv に 2 番目のインデックスを追加します。 たとえば、次のプログラムは、呼び出されたすべての引数を一度に 1 文字ずつ出力します。

#含む
int main(int argc, char *argv)
{
int t、i;
for(t=0; t {
i = 0;
while(argv[t][i])
{
printf("%c", argv[t][i]);
}
printf(" ");
}
0を返します。
}

最初のインデックスは文字列にアクセスするためのものであり、2 番目のインデックスは文字列内の文字にアクセスするためのものであることを覚えておく必要があります。

通常、argc と argv はソース コマンドを取得するために使用されます。 理論的には最大 32767 個の引数を指定できますが、ほとんどのオペレーティング システムではそれに近づくことさえできません。 通常、これらの引数はファイル名またはオプションを指定するために使用されます。 コマンド ライン引数を使用すると、プログラムにプロフェッショナルな外観が与えられ、プログラムをバッチ ファイルで使用できるようになります。

Borland C++ に付属の WILDARGS.OBJ ファイルを含めると、*.EXE 型の引数でテンプレートを使用できます。 (Borland C++ はワイルドカードを自動的に処理し、それに応じて argc をインクリメントします。) たとえば、次のプログラムに WILDARGS.OBJ をアタッチすると、コマンド ラインで指定したファイル名に一致するファイルの数が表示されます。

/* このプログラムを WILDARGS.OBJ にリンクします */

#含む
int main(int argc, char *argv)
{
int i を登録します。
printf("%d ファイルが指定された名前と一致します\n", argc-1);
printf("それらは次のとおりです: ");
for(i=1; i printf("%s ", argv[i]);
0を返します。
}

このプログラムを WA と呼び、次のように実行すると、EXE 拡張子を持つファイルの数とこれらのファイル名のリストが取得されます。

argc と argv に加えて、Borland C++ は 3 番目のコマンド ライン引数 -env も提供します。 env パラメータを使用すると、プログラムはオペレーティング システム環境に関する情報にアクセスできます。 env パラメータは argc および argv の後に続く必要があり、次のように宣言されます。

ご覧のとおり、env は argv と同じ方法で宣言されます。 argv と同様に、これは文字列の配列へのポインタです。 各行は、オペレーティング システムによって定義された環境文字列です。 env パラメータには、環境行の数を示す同等の argc パラメータがありません。 代わりに、環境の最後の行は null です。 次のプログラムは、オペレーティング システムで現在定義されているすべての環境文字列を出力します。

/* このプログラムはすべての環境行を表示します */

#含む
int main(int argc, char *argv, char *env)
{
int t;
for(t=0; env[t]/ t++)
printf("%s\n", env[t]);
0を返します。
}

argc と argv はプログラムでは使用されませんが、パラメーター リストに存在する必要があることに注意してください。 C はパラメータ名を知りません。 代わりに、それらの使用はパラメータが宣言された順序によって決まります。 実際、パラメータには好きな名前を付けることができます。 argc、argv、および env は従来の名前であるため、プログラムを読んだ人がこれらが main() 関数の引数であることをすぐに理解できるように、これらを引き続き使用することが最善です。

プログラムの一般的なタスクは、環境文字列で定義された値を検索することです。 たとえば、PATH 行の内容により、プログラムは検索パスを使用できるようになります。 次のプログラムは、標準の検索パスを宣言する文字列を検索する方法を示しています。 これは、次のプロトタイプを持つ標準ライブラリ関数 strstr() を使用します。

Char *strstr(const char *str1, const char *str2);

strstr() 関数は、str2 が指す文字列内で str1 が指す文字列を検索します。 そのような文字列が見つかった場合は、最初の位置へのポインタが返されます。 一致するものが見つからない場合、関数は NULL を返します。

/* プログラムは環境文字列の中から PATH を含む行を検索します */

#含む
#含む
int main (int argc、char *argv、char *env)
{
int t;
for(t=0; env[t]; t++)
{
if(strstr(env[t], "PATH"))
printf("%s\n", env[t]);
}
0を返します。
}

すべての C プログラムは、main() 関数の呼び出しから始まります。 この関数はすべてのプログラムにある必要があります。

他の関数と同様に、main() 関数にはパラメーターを含めることができます。 プログラムを開始するときに、プログラムに何らかの情報を渡すと便利な場合があります。 この情報は、コマンドライン引数を使用して main() に渡されます。 コマンドライン引数– これは、プログラム開発環境外でプログラムを起動して実行するときに、プログラム名に続いてコマンド ラインに入力される情報です。 たとえば、task.cpp ファイルのアーカイブを開始するには、コマンド ラインに次のように入力する必要があります。

ウィンラー アーチタスクtask.cpp // winrar.exe アーチタスクタスク.cpp

ここで、winrar はアーカイバ プログラムの名前であり、行「 ある», « アーチタスク" そして " タスク. CP» プログラムにアーカイブを作成するように指示するコマンド ライン引数を表します (" ある") 名前付き アーチタスク 1つのファイルから タスク. CP.

main() 関数にパラメータを渡すときは、次のように定義する必要があります。

int main(int argc, char *argv) ( ) // または void main(...)()

argc パラメータにはコマンド ラインの引数の数が含まれ、整数です。最初の引数は常にプログラム名 (プログラムへの絶対パスを含むプログラム名) であるため、常に 1 以上になります。

argv パラメータは、文字列へのポインタの配列へのポインタです。 この配列では、各要素が次のコマンド ライン引数を指します。 空の角括弧は、配列の長さが無限であることを示します。 argv 配列にインデックスを付けることで、個々の引数にアクセスできます。 たとえば、argv は最初の文字列を指します。これは常にプログラム名です。 argv は最初の引数を指します。以下同様です。 引数リストは NULL に制限されます。 argv == NULL。

コマンド ライン引数のいずれかの個々の文字にアクセスするには、argv の 2 番目のインデックスを使用する必要があります。 つまり、最初のインデックス argv は文字列へのアクセスを提供し、2 番目のインデックスはその個々の文字へのアクセスを提供します。

すべてのコマンド ライン引数は文字列であるため、プログラムの開発時に数値パラメータを目的の形式に変換する必要があります。

シンボリック形式の数値を整数と実数に変換するさまざまな方法を備えたプログラムの例:

#含む

#含む

// 起動時に、たとえば次の引数を設定します: 100 2.7

void main(int a, char *b) (

k = strtol(b, &ptr, 10); // ptr = 行内のエラーのアドレス

f = strtod(b, &ptr);

sscanf(b, "%d", &k);

sscanf(b, "%lf", &f);

argc および argv という名前は伝統的なものですが、必須ではありません。 main() 関数のこれら 2 つのパラメータは、好きな名前で呼び出すことができます。

コマンドライン引数を使用する簡単な例:

int main(int argc, char *argv) (

if (argc != 4) (

printf("プログラム起動パラメータが無効です!\n");

k = atoi(argv); // 数値パラメータの変換

printf("こんにちは、%d 年のグループ %s の %s",

プログラムの名前がタスクで、あなたの名前が「Vasya」、最初の年からグループが「PM-11」の場合、プログラムを開始するには、コマンド ラインに次のように入力する必要があります。

タスク ヴァシャ PM-11 1

プログラムを実行すると、画面に「こんにちは、1年PM-11グループのヴァシャです。」というメッセージが表示されます。

すべてのコマンド ライン引数が指定されていない場合は、エラー メッセージが表示されることに注意してください。 コマンド ライン引数を受け取るプログラムは、多くの場合、次のことを行います。 ユーザーが必要な情報を入力せずにこれらのプログラムを実行すると、引数を正しく指定する方法に関する指示が表示されます。

コマンドライン引数はスペースで区切る必要があります。 引数自体にスペースが含まれている場合は、複数の引数を作成できないように、この引数を二重引用符で囲む必要があります。 その結果、引用符で囲まれた文字列全体が 1 つの引数とみなされます。 たとえば、プログラムは次のように起動できます。 タスク「Vasya と Petya」 PM-21 2. プログラムを実行すると、次のメッセージが画面に表示されます。「こんにちは、PM 2 年の Vasya と Petya- 21グループです。」

char *argv とは何ですか? これ 要素がポインタである配列、 あれは ポインタの配列。 これは、パラメータを main() に渡すときに、次のように定義できることを意味します。

void main(int argc, char **argv) (

タスク。 すべてのコマンド ライン引数を表示します (プログラム名を表示する必要はありません)。

#含む

void main(int argc, char *argv)(

for (i = 1; i< argc; i++)

printf("%s\n", argv[i]);

2 番目のオプション ================

#含む

void main(int argc, char **argv)(

while((p=*argv) != NULL) (

printf("%s\n", p);

通常、コマンド ライン引数は、プログラムの起動時に必要となる初期データをプログラムに提供するために使用されます (たとえば、コマンド ライン引数は、ファイル名やプログラム起動パラメータなどのデータを渡すことがよくあります)。

プログラムがコマンド ライン パラメーターを必要としない場合、main() 関数はパラメーター リストで void キーワードを使用します (または単に何も指定しません)。

デバッグ方法 紀元前 コマンドライン引数を必要とするプログラム。 メニュー「実行」→「引数...」で、コマンドライン引数を入力する必要があります。 プログラム名を指定する必要はありません。 その後、通常どおり開発環境でプログラムを実行してデバッグできます。

このサイトの AdBlock を一時停止してください。

では、なぜカスタム関数が必要なのでしょうか? ユーザー定義関数は、プログラマーがプログラムを簡単に作成できるようにするために必要です。

思い出してください。プログラミング パラダイム、より正確には構造化プログラミングについて話しました。 そこでの主なアイデアは、フォロー、条件、ループという 3 つの基本構造のみを使用して、どのようなプログラムも作成できるということでした。 ここで、これらの構造にもう 1 つ「サブルーチン」を追加し、新しいパラダイムを取得します。 手続き型プログラミング」.

唯一の違いは、メインプログラムの個々の部分 (特に繰り返し部分) を別個の関数 (サブルーチン、プロシージャ) の形式で作成し、必要に応じて呼び出すことです。 基本的に、プログラムはさまざまな機能の相互作用を記述します。

したがって、このチュートリアルでは、関数が内部でどのように構築されるかについて詳しく説明します。 独自のカスタム関数を作成する方法も学習します。

機能の仕組み

最初のレッスンで得た情報を思い出してみましょう。 ユーザーが作成した関数を含むすべての関数は、同様の方法で配置されます。 これらには、関数ヘッダーと関数本体という 2 つの主要な部分があります。

リスト 1.

Int main(void)( // 関数ヘッダ // 関数本体は中括弧内に記述されます)

関数の本体を見ればすべてが明らかです。関数のアルゴリズムが記述されています。 タイトルを見てみましょう。 これは 3 つの必須部分で構成されます。

  • 戻り値の型;
  • 関数名;
  • 関数の引数。

まず、戻り値の型は main 関数と同様に、たとえば int のように記述されます。 関数がプログラムに値を返さない場合は、この場所にキーワード void が書き込まれます。 この関数は何も返さないので、何も書く必要がないように見えます。 ちなみに、以前はこれは C 言語で行われていましたが、統一性のために追加されました。 最近のコンパイラでは、戻り値の型を指定しないと警告やエラーが発行されます。
一部のプログラミング言語では、値を返さない関数はプロシージャと呼ばれます (Pascal など)。 さらに、関数とプロシージャを作成するためのさまざまな構文があります。 C言語ではそのような差別はありません。

関数名は戻り値の型の後に記述されます。 名前の後に、関数に渡される引数の型と数が示されます。

すでによく知っている関数の見出しを見てみましょう。

リスト 2.

// 整数を取る srand という名前の関数は何も返しません void srand(int) // 実数の浮動小数点を取る sqrt という名前の関数は浮動小数点を返します float sqrt(float) // 引数を取らない rand という名前の関数は整数を返しますint rand(void) //double 型の 2 つの引数を受け取り、double 型の実数を返す pow という名前の関数 double pow(double, double)

独自の関数を作成する方法

独自の関数を作成するには、それを完全に記述する必要があります。 ここでは一般的なルールが適用されます。つまり、使用する前に、それがどのように機能するかを宣言して説明します。 これを行うには、最初のレッスンで説明した C 言語のプログラム構造の図に戻りましょう。 関数を記述できる場所にマークを付けてみましょう。

図1 プログラム構造の明確化 関数の宣言。

ご覧のとおり、これを実行できる場所は 2 つあります。

2 つの数値の最大値を計算するカスタム関数を作成する例を見てみましょう。

リスト 3.

#含む // max_num という名前のカスタム関数を宣言します // 入力: a および b という名前の 2 つの整数パラメーター // 出力: 2 つの引数の最大値 int max_num(int a, int b)( int max = b; if (a > b) max = a; return max; ) //メインプログラム int main(void) ( int x = 0, y = 0; int m = 0; scanf("%d %d", &x, &y); m = max_num( x ,y); printf("max(%d,%d) = %d\n",x,y,m); return 0; )

このプログラムがどのように機能するかを詳しく説明しましょう。 main関数の本体が実行されます。 整数変数 x、y、m が作成されます。 変数 x と y はキーボードから読み取られます。 3 5 と入力し、x = 3、y = 5 と入力したとします。 これはすべて明らかなはずです。 次の行

リスト 4.

M = max_num(x,y);

変数 m は、= 記号の右側に代入する必要があります。 そこには、自分で作成した関数の名前があります。 コンピューターはこの関数の宣言と説明を探します。 上にあります。 この宣言によれば、この関数は 2 つの整数値を受け入れる必要があります。 私たちの場合、これらは変数 x と y に書き込まれる値です。 それらの。 3番と5番。 関数に渡されるのは変数 x と y そのものではなく、それらに格納されている値 (2 つの数値) だけであることに注意してください。 プログラム内で関数が呼び出されたときに実際に渡されるものを、関数の実パラメータと呼びます。

ここで、max_num 関数の実行が開始されます。 最初のステップは、関数ヘッダーに記述されているパラメーターごとに個別の一時変数を作成することです。 この例では、a と b という名前の 2 つの整数変数が作成されます。 これらの変数には実際のパラメータの値が割り当てられます。 関数ヘッダーに記述されるパラメータ自体は、仮パラメータと呼ばれます。 したがって、仮パラメータ a と b には、それぞれ実パラメータ 3 と 5 の値が割り当てられます。 ここで、a = 3、b = 5 となります。 さらに関数の内部では、これらの変数を通常の変数であるかのように操作できます。

max という名前の整変数が作成され、値 b が割り当てられます。 次に、条件 a > b がチェックされます。 true の場合、max 変数の値は に置き換えられる必要があります。

次に return ステートメントが続き、max 変数に書き込まれた値を呼び出し側プログラム (メイン関数) に返します。 5. その後、変数 a、b、および max がメモリから削除されます。 そして列に戻ります

リスト 5.

M = max_num(x,y);

max_num 関数は値 5 を返しました。これは、= 記号の右側に 5 が書き込まれていることを意味します。 この値は変数 m に書き込まれます。 その後、画面に行が表示され、プログラムが終了します。

最後の 4 つの段落をもう一度注意深く読んで、プログラムがどのように動作するかを完全に理解してください。

それまでの間、関数説明の下部ブロックが必要な理由を説明します。 プログラムに 20 個の小さな関数を作成したと想像してください。 そしてそれらはすべて main 関数の前に記述されます。 メインプログラムに長時間アクセスするのはあまり便利ではありません。 この問題を解決するには、下位ブロックに関数を記述することができます。

ただし、関数コード全体をそこに単純に転送することはできません。 その場合、ルールは破られます。何かを使用する前に、それを宣言する必要があります。 この問題を回避するには、関数プロトタイプを使用する必要があります。

関数プロトタイプは、関数ヘッダーとそれに続く ; を完全に繰り返します。 。 上のブロックでプロトタイプを指定したら、下のブロックですでに関数を完全に記述することができます。 上の例では、次のようになります。

リスト 6.

#含む int max_num(int, int); int main(void) ( int x =0, y = 0; int m = 0; scanf("%d %d", &x, &y); m = max_num(x,y); printf("max(%d) ,%d) = %d\n",x,y,m); return 0; ) int max_num(int a, int b)( int max = b; if (a > b) max = a; return max; )

すべてがとてもシンプルです。 関数プロトタイプでは仮パラメータの名前を指定する必要はなく、単にその型を示すだけで十分であることに注意してください。 上の例では、まさにそれを実行しました。