C プログラミングの関数と例: 再帰的およびインライン

⚡ スマートサマリー

C言語における関数は、大規模なプログラムをより小さなサブルーチンに分割する再利用可能なコードブロックであり、理解、テスト、および変更を容易にします。各関数は、宣言、定義、および呼び出し部分から構成されます。

  • 🧩 機能の内容: 関数は再利用可能な命令をグループ化するため、大規模なプログラムをより小さく管理しやすいサブルーチンに分割でき、デバッグが容易になります。
  • 📚 2つのタイプ: printfやscanfといったライブラリ関数は既製の関数である一方、ユーザー定義関数はプログラマーが作成する関数である。
  • 📝 3つの部分: 関数を使用するには、その宣言(プロトタイプ)、定義(本体)、そしてそれを実行する呼び出しが必要です。
  • 🎯 引数: 値は位置によって渡され、デフォルトでは値によって渡されるため、呼び出された関数内では元の変数は変更されません。
  • 🌐 範囲: ローカル変数は関数内でのみ有効ですが、グローバル変数と静的変数はプログラム全体または関数呼び出し間で値を保持します。
  • 🤖 AI支援: GitHub CopilotとAIアシスタントは、C言語の関数を生成し、戻り値の型を提案し、戻り値の欠落や引数の不一致を指摘します。

Cプログラミングの機能

Cの関数とは何ですか?

Cプログラミングにおける関数 関数は、プログラムを理解しやすく、テストしやすく、呼び出し元のプログラムを変更することなく簡単に修正できる、再利用可能なコードブロックです。関数はコードを分割し、プログラムをモジュール化することで、より良い、より効果的な結果をもたらします。つまり、大きなプログラムは、関数と呼ばれるさまざまなサブルーチンに分割されます。

Cの関数とは何ですか

大規模なプログラムをさまざまな関数に分割すると、各関数を個別に管理することが容易になります。 プログラムでエラーが発生した場合は、問題のある機能を簡単に調査し、それらのエラーのみを修正できます。 必要なときにいつでも簡単に機能を呼び出して使用できるため、時間とスペースの節約につながります。

図書館 vs. ユーザー定義関数

すべての「C」プログラムにはメイン関数である関数が少なくとも XNUMX つありますが、プログラムには任意の数の関数を含めることができます。 C の main () 関数はプログラムの開始点です。

「C」プログラミングでは、関数は XNUMX つのタイプに分類されます。

  1. ライブラリ関数
  2. ユーザー定義関数

C のライブラリ関数とユーザー定義関数の違いは、ライブラリ関数のコードを記述する必要がないことです。 これは、プログラムの先頭に常に含めるヘッダー ファイル内にすでに存在します。 関数の名前を入力し、適切な構文とともに使用するだけです。 ライブラリ関数の例としては、printf、scanf があります。

一方、ユーザー定義関数は、関数の本体を記述し、プログラム内で何らかの操作を実行するために関数が必要なときにその関数を呼び出す必要があるタイプの関数です。

C のユーザー定義関数は常にユーザーによって作成されますが、後で 'C' ライブラリの一部にすることができます。これは 'C' プログラミングの大きな利点です。

C プログラミング関数は、次の XNUMX つのアクティビティに分かれています。

  1. 関数宣言
  2. 関数定義
  3. 関数呼び出し

関数宣言

関数宣言とは、プログラムに関数名を記述することです。これは、コード内で関数を使用するために必須の要素です。関数宣言では、変数宣言と同様に、プログラム内で使用する関数名を指定します。プログラム内で宣言されていない関数は使用できません。関数宣言は「関数プロトタイプ」とも呼ばれます。

関数宣言 (プロトタイプと呼ばれる) は通常、main () 関数の上で行われ、一般的な形式を取ります。

return_data_type function_name (data_type arguments);
  • return_data_type: は、値関数が呼び出し元のステートメントに返すデータ型です。
  • function_name: の後には括弧が続きます
  • 引数名とそのデータ型宣言は、任意で括弧内に記述できます。

整数変数の立方値を計算する立方関数を宣言する方法を示す次のプログラムを検討します。

#include <stdio.h>
/*Function declaration*/
int add(int a,b);
/*End of Function declaration*/
int main() {

関数は必ずしも値を返すわけではないことに注意してください。 この場合、キーワード void が使用されます。

たとえば、output_message 関数宣言は、関数が値を返さないことを示します。

関数定義

関数定義とは、関数の本体を記述するだけです。 関数の本体は、特定のタスクを実行するステートメントで構成されます。 関数本体は、単一またはステートメントのブロックで構成されます。 これは関数の必須の部分でもあります。

int add(int a,int b)	//function body	
{
	int c;
	c=a+b;
	return c;
}

関数呼び出し

関数呼び出しとは、プログラムで必要なときにいつでも関数を呼び出すことを意味します。関数を呼び出すたびに、関数は設計された操作を実行します。関数呼び出しは、プログラムのオプション部分です。

  result = add(4,5);

以下に完全なコードを示します。

#include <stdio.h>
int add(int a, int b);	//function declaration
int main()
{
	int a=10,b=20;
	int c=add(10,20); 	//function call
	printf("Addition:%d\n",c);
	getch();
}
int add(int a,int b)	//function body
{
	int c;
	c=a+b;
	return c;
}

出力:

Addition:30

関数の引数

関数の引数は、関数呼び出しによって必要な値を受け取るために使用されます。 これらは位置によって照合されます。 最初の引数は最初のパラメータに渡され、XNUMX 番目の引数は XNUMX 番目のパラメータに渡されます。

デフォルトでは、引数は値渡しされ、呼び出された関数にデータのコピーが渡されます。実際に渡される変数は変更されません。

値渡しされるパラメータを示す次のプログラムを検討します。

int add (int x, int y); 
int main() {
  int a, b, result;
  a = 5;
  b = 10;
  result = add(a, b);
  printf("%d + %d\ = %d\n", a, b, result);
return 0;}
int add (int x, int y) { 
x += y;
  return(x);}

プログラムの出力は次のとおりです。

5 + 10 = 15

add 関数に渡された a と b の値は、その値のみがパラメータ x に渡されたため、変更されないことに注意してください。

可変スコープ

変数スコープとは、プログラムのコード内の変数の可視性を意味します。

C言語では、関数内で宣言された変数はそのコードブロック内でのみ有効であり、関数外からは参照できません。一方、すべての関数の外で宣言された変数はグローバル変数であり、プログラム全体からアクセス可能です。プログラムの先頭で#defineを使って宣言された定数も、プログラム全体からアクセスできます。ここでは、main関数とユーザー定義関数の両方からグローバル変数の値を出力する以下のプログラムを考えてみましょう。

#include <stdio.h>
int global = 1348;
void test();
int main() {
  printf("from the main function : global =%d \n", global);
  test () ;
return 0;}

void test (){
printf("from user defined function : global =%d \n", global);}

結果:

from the main function : global =1348
from user defined function : global =1348

プログラムの詳細について話し合います。

可変スコープ

  1. 初期値として 1348 を使用して整数グローバル変数を宣言します。
  2. 引数も取らず、値も返さない test() 関数を宣言して定義します。 この関数は、プログラム内のどこからでもグローバル変数にアクセスできることを示すために、グローバル変数の値のみを出力します。
  3. main 関数内でグローバル変数を出力します。
  4. グローバル変数の値を出力するために、テスト関数を呼び出します。

C では、引数が関数のパラメータに渡されると、パラメータはローカル変数として機能し、関数の終了時に破棄されます。

この方法でエスプレッソの抽出を計量する場合、エスプレッソがスパウトから落ちるタイミングとスケールが反応するタイミングに時間差が生じます。エスプレッソがスパウトからエスプレッソカップに落ち、スケールが計量するまで若干の時間差が生じるため、抽出ボタンを止めた後、液量が約2~4g増加することを念頭に置いて抽出を止めてください。 グローバル変数エラーが発生する可能性があり、プログラム内の任意の場所で変更される可能性があるため、注意して使用してください。 使用する前に初期化する必要があります。

静的変数

静的変数はローカル スコープを持ちます。ただし、関数を終了しても破棄されません。したがって、静的変数は値を永久に保持し、関数に再度入ったときにアクセスできます。静的変数は宣言時に初期化され、プレフィックス static が必要です。

次のプログラムは静的変数を使用します。

#include <stdio.h>
void say_hi();
int main() {    
  int i;
  for (i = 0; i < 5; i++) { say_hi();}
   return 0;}
void say_hi() {
  static int calls_number = 1;
  printf("Hi number %d\n", calls_number);
  calls_number ++; }

プログラムは次のように表示します。

Hi number 1
Hi number 2
Hi number 3
Hi number 4
Hi number 5

再帰関数

数の階乗は次のように計算されます。6! = 6 * 5 * 4 * 3 * 2 * 1。

この計算は、fact が 1 になるまで、fact * (fact -1) を繰り返し計算して実行されます。

再帰関数は、それ自体を呼び出す関数であり、再帰呼び出しを終了するための終了条件が含まれています。 階乗数計算の場合、終了条件は事実が 1 に等しいです。再帰は、終了条件が true になるまで呼び出しを「積み重ねる」ことによって機能します。

具体的な例を挙げますと、以下の通りです。

#include <stdio.h>
int factorial(int number);
int main() {    
  int x = 6;
  printf("The factorial of %d is %d\n", x, factorial(x)); 
  return 0;}
int factorial(int number) {
 if (number == 1)    return (1); /* exiting condition */
  else
    return (number * factorial(number - 1));
}

プログラムは次のように表示します。

 The factorial of 6 is 720

ここでは、プログラムの詳細について説明します。

再帰関数

  1. 整数パラメータを受け取り、このパラメータの階乗を返す再帰階乗関数を宣言します。 この関数はそれ自体を呼び出し、終了するか基本条件に達するまで数値を減らします。 条件が true の場合、以前に生成された値が互いに乗算され、最終的な階乗値が返されます。
  2. 整数変数を値「6」で宣言して初期化し、factorial 関数を呼び出してその階乗値を出力します。

再帰メカニズムをより深く理解するために、次の図を参照してください。再帰メカニズムは、基本ケースまたは停止条件が満たされるまで、関数自身を呼び出すことで構成されています。ping 条件が満たされた後、以前の値を収集します。

再帰関数

インライン関数

C プログラミングの関数は、最も頻繁に使用される命令を保存するために使用されます。 プログラムをモジュール化するために使用されます。

関数が呼び出されるたびに、命令ポインタは関数定義にジャンプします。 関数の実行後、命令ポインタは関数定義にジャンプした場所からステートメントに戻ります。

関数を使用するときは常に、追加の関数が必要です ポインタ head をクリックして関数定義にジャンプし、ステートメントに戻ります。 このようなポインターヘッドの必要性を排除するために、インライン関数を使用します。

インライン関数では、関数呼び出しが実際のプログラム コードに直接置き換えられます。すべての操作はインライン関数内で実行されるため、ブロックにジャンプすることはありません。

インライン関数は主に小規模な計算に使用されます。 大規模なコンピューティングが関与する場合には適していません。

インライン関数は、キーワード inline が関数名の前に配置される点を除いて、通常の関数と似ています。インライン関数は次の構文で作成されます。

inline function_name ()
{
    //function definition
}

インライン関数を実装するプログラムを書いてみましょう。

inline int add(int a, int b)		//inline function declaration
{
	return(a+b);
}
int main()
{
	int c=add(10,20);
	printf("Addition:%d\n",c);
	getch();
}

出力:

Addition: 30

上記のプログラムは、2 つの数値を加算するためのインライン関数の使用を示しています。ご覧のとおり、余分な行を記述せずに、インライン関数内でのみ 2 つの数値の加算を返しています。関数呼び出し中に、加算を実行する必要がある値を渡しただけです。

よくあるご質問

値渡しでは引数が関数にコピーされるため、変更はローカルに留まり、元の変数は変更されません。参照渡しでは変数アドレスがポインタを介して渡されるため、関数は呼び出し元の元のデータを直接変更できます。

実引数とは、関数呼び出し時に呼び出し元が渡す実際の値または変数です。仮引数とは、関数定義内でその値を受け取るプレースホルダーです。これらは位置によって対応付けられ、最初の引数は最初の引数、2番目の引数は2番目の引数として扱われます。

AC関数は、戻り値として1つの値のみを直接返します。複数の結果を返すには、構造体でラップするか、配列に格納するか、またはポインタを引数として渡して、関数が各結果を呼び出し元の変数に書き込むようにします。

関数は再利用性をもたらし、1つのコードブロックを何度も実行できるようにします。また、モジュール性も高め、大きなプログラムをより小さな部分に分割します。さらに、可読性を向上させ、テストとデバッグを簡素化し、複雑な詳細を単一の名前で隠蔽することで、開発時間を節約します。

main() 関数は、すべての C プログラムの実行開始点です。オペレーティングシステムが最初に呼び出し、その戻り値(通常は 0)は成功を示します。コマンドライン引数を受け取るために、argc と argv を受け取る場合があります。

再帰は、ツリー走査や階乗など、自然に繰り返し構造を持つ問題に適しており、より短く分かりやすいコードを作成できます。一方、反復処理は繰り返し呼び出しを避けるため、通常は高速でメモリ使用量も少なくて済みます。分かりやすさを重視するなら再帰を、大きな入力に対するパフォーマンスを重視するなら反復処理を選択してください。

はい。AIコーディングアシスタントは、平易な言語のプロンプトからC言語の関数を作成し、パラメータや戻り値の型を提案し、戻り値の欠落や引数の不一致などのバグを指摘できます。生成された関数を使用する前に、必ずコンパイルとテストを行ってください。

GitHubコパイロット C言語の関数を自動生成し、関数名または短いコメントから本体を補完し、宣言、ループ、再帰呼び出しを提案します。多くの場合、main() 関数の上に一致するプロトタイプを追加しますが、ロジックは必ず確認してください。