デフォルトパラメータ
変分関数
現代の言語(PythonやJavaScriptのような)は良い機能を持っています:関数は変数の数の引数を持つことができます.また、指定されていない引数のデフォルト値を定義することもできます.
これはプログラミングのより簡潔なスタイルを許容します.
Cは、変数の数(可変関数と呼ばれる)を持つ関数を
stdarg.h
ヘッダva_start()
, va_copy()
, va_arg()
and va_end()
これにより、引数のリストをスキャンできます.彼らは何もないし、何もない、私は彼らが本当に使用し、いくつかの欠点を持っているとしてそれを好きにしたことがない:
printf()
フォーマットする文字列をスキャンし、期待するパラメータ数を知るexecl()
渡す必要がありますNULL
を返します.stdarg.h
そして、我々の日を保存してください.私がここで例で使用する最もきれいなものをここに提示します、そして、以下で、これがどのように達成されるかについて示します.例:定義しましょう
greet()
つの引数(名前とメッセージ)を受け取り、あいさつメッセージを出力する関数ですが、2番目の引数を省略することができます.指定されない場合は、デフォルトのメッセージが使用されます.#include <stdio.h>
#include "vrg.h"
char * msg_default = "How are you?";
#define greet(...) vrg(greet, __VA_ARGS__)
#define greet1(n) greetX(n, msg_default)
#define greet2(n, m) greetX(n, m)
void greetX(char *name, char *msg) {
printf("Hello %s. %s\n", name, msg);
}
int main(int argc, char *argv[]) {
greet("Alice", "How's your day?");
greet("Bob"); // too lazy to think of a greeting for Bob
}
上のコードは出力を生成します.Hello Alice. How's your day?
Hello Bob. How are you?
私たちがしたことはgreetX()
) そして、我々が普通にするようにそれを書きます.greet()
Variadicマクロとして(関数ではなく)greet1()
マクロの場合、greet ()マクロは1つの引数だけで呼び出されます.greet2()
マクロの場合、greet ()マクロは2つの引数で呼び出されます.stdarg.h
. この特定のケースがカバーするのが不可能であると言及しない限りstdarg.h
の動作以来va_arg()
引数が存在しない場合は未定義です!あなたが少なくとも1つの引数を持たなければならないという制限があります、しかし、あなたが使うとき、これは真実です
stdarg.h
. GCCは0の引数を扱うことができる拡張子を持っていますが、C 99に滞在したいです.フードの下で
トリックは
vrg.h
上記のコードに含まれるファイルvrg
のためのニーモニックとして役立つvariadic arguments
.私はまだGithubにそれを置いていないので
vrg.h
こちら#define vrg_cnt(vrg1,vrg2,vrg3,vrg4,vrg5,vrg6,vrg7,vrg8,vrgN, ...) vrgN
#define vrg_argn(...) vrg_cnt(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define vrg_cat0(x,y) x ## y
#define vrg_cat(x,y) vrg_cat0(x,y)
#define vrg(vrg_f,...) vrg_cat(vrg_f, vrg_argn(__VA_ARGS__))(__VA_ARGS__)
最初の2つのマクロは引数の数を数えます.これは8つ以上の引数に制限されています.なぜなら、いくつかの引数(そして8つの引数がたくさんある)で関数を書いていたなら、私はその関数をどのように構成したかに大きな問題がありました.単純にあまりにも多くの引数を持つ関数を言う!他の2つのマクロは、区分的に識別子を作成する標準的な方法です.
最後のものはすべてをまとめ、引数の数によって異なる関数(またはマクロ)を呼び出します.
このマクロは各引数が一度だけ評価されるので安全です.
Reference
この問題について(デフォルトパラメータ), 我々は、より多くの情報をここで見つけました https://dev.to/rdentato/default-parameters-in-c-4kl1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol