Programmingシステムプログラマ

C言語における可変個引数関数と標準関数の違いについて説明してください。可変個引数関数はどのように実装しますか?

Hintsage AIアシスタントで面接を突破

回答

C言語では、関数は固定または可変個の引数を受け取ることができます。標準関数は次のように定義されます:

int sum(int a, int b) { return a + b; }

可変個の引数には<stdarg.h>マクロを使用し、異なる数の入力パラメータを処理できるようにします。

例:

#include <stdarg.h> #include <stdio.h> int sum(int count, ...) { int total = 0; va_list args; va_start(args, count); for (int i = 0; i < count; ++i) { total += va_arg(args, int); } va_end(args); return total; }

トリッキーな質問

可変個引数関数とオーバーロードされた関数の違いは何ですか、またCでのオーバーロードをどのように実装しますか?

回答: CにはC++のような関数のオーバーロードのサポートはありません: 関数名と引数の数は一意でなければなりません。可変個引数は汎用インターフェースを実現しますが、これは「オーバーロード」ではありません。

例(誤り):

// Cでは動作しません。同じ名前の2つの関数を作成することはできません: int foo(int a); float foo(float b); // コンパイルエラー。

このテーマの詳細を知らないことによる実際のエラーの例


物語

ある大規模プロジェクトでは、可変個引数の関数を使用しましたが、渡された値の型をチェックしませんでした。すべての引数がint型であることが期待されていましたが、ある時double型が渡され、メモリの不正な読み込みとアプリケーションの偶発的なクラッシュを引き起こしました。

物語

ある開発者はva_endを呼び出すのを忘れ、特定のアーキテクチャでリソースリークを引き起こしました。症状は関数の多重使用時にのみ現れました。

物語

可変個引数関数を処理する際に、va_listを二度使用し、va_copyを呼び出さなかったために予測不可能な動作を引き起こしました。このエラーはすぐには現れず、コンパイラの変更後にのみ発生しました。