可変パラメータ
時には、あなたがそのような状況が発生する可能性があり、あなたは、可変個の引数ではなく、パラメータの定義済みの数の関数にしたいです。C言語はこのような状況に対する解決策を提供し、それはあなたが特定のニーズに応じたパラメータの可変数を受け入れることができます関数を定義することができます。次の例では、そのような関数の定義を示しています。
int func(int, ... )
{
.
.
.
}
int main()
{
func(2, 2, 3);
func(3, 2, 3, 4);
}
機能のことに注意してくださいFUNC() 3つのドット(で最後の引数書か省略記号、...省略記号がある前に)、その引数int型渡される変数パラメータの合計数を表します。この機能を使用するには、使用する必要がSTDARG.H関数やマクロの可変パラメータ機能の実装を提供したヘッダファイルを、。次のように具体的な手順は次のとおりです。
- 関数の定義は、最後のパラメータが省略記号で、省略記号カスタムパラメータの前に設けられてもよいです。
- 関数定義を作成たva_list型の変数を、タイプは、ヘッダファイルSTDARG.Hに定義されています。
- 使用int型のパラメータとのva_startの初期化するマクロたva_listパラメータリストとして変数を。va_startマクロは、ヘッダファイルSTDARG.Hに定義されています。
- 使用のva_argマクロとva_listのパラメータリスト内の各項目にアクセスするための変数。
- マクロ使用にva_endを与えクリーンアップするva_listのメモリ変数を。
可変数の引数で関数を記述し、その平均値を返すために上記の私たちは、今の手順に従ってみましょう:
#include <stdio.h>
#include <stdarg.h>
double average(int num,...)
{
va_list valist;
double sum = 0.0;
int i;
/* 为 num 个参数初始化 valist */
va_start(valist, num);
/* 访问所有赋给 valist 的参数 */
for (i = 0; i < num; i++)
{
sum += va_arg(valist, int);
}
/* 清理为 valist 保留的内存 */
va_end(valist);
return sum/num;
}
int main()
{
printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5));
printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15));
}
上記のコードがコンパイルおよび実行されると、次の結果を生成します。関数ことに留意すべきである平均値()は最初のパラメータは可変パラメータの総数が表現を転送されるたびに、二回呼び出されます。省略記号は、可変個の引数を転送するために使用されています。
2、3、4、5 = 3.500000の平均
5の平均値、10、= 10.000000 15
メモリ管理
C言語では、メモリを割り当てて管理するためにいくつかの機能を提供します。これらの機能は、することができ、<stdlib.h>に含まれたヘッダファイルを見つけます。
いいえ。 | 機能と説明 |
---|---|
1 | void *型のcalloc(int型NUM、int型のサイズ); メモリを動的num個連続した長さのサイズの領域を割り当て、各バイトを0に初期化されます。その結果は、NUMが割り当てられているので*メモリのサイズは、長さがバイト、各バイトの値は0です。 |
2 | ボイドのない(void *型のアドレス);この関数は、メモリ・ブロック・アドレスが動的に割り当てられたメモリ空間のリリースによって指さリリース。 |
3 | ;ボイド*(INT NUM)mallocのヒープ領域にデータを格納するための指定されたメモリサイズを割り当てます。このメモリ空間は、関数の実行が完了した後、それらの値が不明で初期化されません。 |
4 | void *型のrealloc(void *型アドレス、 INT NewSizeパラメータ); この関数REALLOCATEメモリへの拡張メモリでNewSize。 |
注: void *型のタイプは、ポインタの未定種類を表しています。C、C ++所定の型がvoid *ポインタの型変換の他のタイプによってキャストすることができます。
動的なメモリ割り当て
プログラミングする場合、あなたが事前にわかっている場合は、配列を定義する場合、配列のサイズは、それは簡単です。たとえば、次のようにあなたは、配列を定義することができますので、100文字まで収容するの名前の配列:
char name[100];
事前に知っていない場合は、テキストの長さは、ストレージに関連するトピックのあなたの詳細な説明として、保存する必要があります。ここでは、未定義の文字を指し、以下に示すように、必要に応じてメモリを割り当てるメモリサイズ、及びその後のを必要とすることポインタを定義する必要があります。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char name[100];
char *description;
strcpy(name, "Zara Ali");
/* 动态分配内存 */
description = (char *)malloc( 200 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcpy( description, "Zara ali a DPS student in class 10th");
}
printf("Name = %s\n", name );
printf("Description: %s\n", description );
}
上記のコードがコンパイルおよび実行されると、次の結果を生成します:
名前=ザラアリの
説明:ザラアリクラス10位でDPSの学生
上記手順を使用することもできるのcalloc()の下に示すようにライトするだけで、malloc関数のcallocを交換する必要があります。
calloc(200, sizeof(char));
メモリの動的な割り当ては、あなたが任意の値の大きさを完全に制御を持っているときに渡すことができます。これらの定義済みのサイズのアレイのは、定義されたら、サイズを変更することはできません。
メモリサイズと空きメモリを再調整
プログラムが終了すると、自動的にメモリを必要としないことをお勧めします、しかし、すべてのプログラムに割り当てられたメモリを解放しますオペレーティングシステムが、あなたは、関数を呼び出す必要がある場合は無料()メモリを解放します。
それとも、あなたは、関数を呼び出すことができます)(のreallocを割り当てられたメモリブロックのサイズを増減します。私たちは、reallocの()及び()free関数を使用して、再び上記の例を見てみましょう:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char name[100];
char *description;
strcpy(name, "Zara Ali");
/* 动态分配内存 */
description = (char *)malloc( 30 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcpy( description, "Zara ali a DPS student.");
}
/* 假设您想要存储更大的描述信息 */
description = (char *) realloc( description, 100 * sizeof(char) );
if( description == NULL )
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcat( description, "She is in class 10th");
}
printf("Name = %s\n", name );
printf("Description: %s\n", description );
/* 使用 free() 函数释放内存 */
free(description);
}
上記のコードがコンパイルおよび実行されると、次の結果を生成します:
名前=ザラアリの
説明:ザラアリDPS student.Sheは、クラス10位です
あなたは説明を格納する際ために利用可能なメモリの不足のため、余分なメモリは、strcatは()関数は、エラーが発生し再割り当てしようとすることはできません。
コマンドラインパラメータ
プログラムを実行するとき、コマンドラインは、Cプログラムに値を渡すことができます。これらの値が呼び出され、コマンドライン引数、彼らはあなたではなく、コード内のハードコードされた値よりも、外部プログラムから制御したい場合には特に、それが特に重要であり、プログラムにとって重要です。
パラメータを処理するために、main()関数を使用するコマンドライン引数、前記ARGCは、渡されたパラメータの数であり、ARGVは[]のポインタの配列であり、各パラメータは、アプリケーションポイントに渡されます。以下は、コマンドラインパラメータと対応するアクションは、パラメータに基づいて行われたか否か、チェックが設けられている単純な例です。
#include <stdio.h>
int main( int argc, char *argv[] )
{
if( argc == 2 )
{
printf("The argument supplied is %s\n", argv[1]);
}
else if( argc > 2 )
{
printf("Too many arguments supplied.\n");
}
else
{
printf("One argument expected.\n");
}
}
パラメータを使用して、上記のコードをコンパイルし、実行し、それは以下の結果を生成します。
$。/テストa.outの
供給引数がテストしています
、2つのパラメータを使用してコンパイルし、上記のコードを実行し、それは以下の結果を生成します。
$。/ a.outのtesting1 testing2
供給引数が多すぎます。
それは次のような結果が生成されます、上記のコードを、任意のパラメータを渡すコンパイルして実行しないでください。
$。/ a.outの
期待一つの引数
これは、ことに留意されたいのargv [0]は、プログラムの名前、格納[1]のargvの最初のコマンドライン引数を指すポインタであり、* ARGV [n]は最後のパラメータです。あなたが任意の引数を指定しない場合、argcが1になり、あなたはパラメータを渡すとそうでない場合は、argcが 2に設定されます。
スペースで区切られたコマンドライン引数、複数の間が、パラメータの伝送パラメータは、二重引用符「」またはアポストロフィ「」内部に配置されなければならない場合、スペースでパラメータ自体場合。スペースは、その後、あなたが「」二重引用符または一重引用符に入れて、ビューを渡すことができますがあります「」レッツは、二重引用符の内側に配置されたプログラムに引数-lineコマンド渡して、上の例を書き直します:
#include <stdio.h>
int main( int argc, char *argv[] )
{
printf("Program name %s\n", argv[0]);
if( argc == 2 )
{
printf("The argument supplied is %s\n", argv[1]);
}
else if( argc > 2 )
{
printf("Too many arguments supplied.\n");
}
else
{
printf("One argument expected.\n");
}
}
単純なパラメータは、二重引用符で囲まれたパラメータは、コンパイルし、上記のコードを実行する空間によって分離された、それは以下の結果を生成します。
$。/ a.outの "testing1のtesting2"
./a.out Progranm名前
与えられた引数はtesting1 testing2です
リファレンスから:https://www.runoob.com/cprogramming/c-tutorial.html