6

重複の可能性:
C、C ++、Java、C#のmain()

私はプログラミング全般、特にCに不慣れです。私が見たすべての例には「メイン」関数があります-これは何らかの方法で事前定義されているため、名前はコンパイラーまたはランタイムにとって特別な意味を持ちます...またはそれは単にCプログラマーの間で一般的なイディオムです(任意の変数名に「foo」と「bar」を使用するようなものです)。

4

4 に答える 4

12

いいえ、プログラムで定義する必要がありmainます。ただし、実行時に呼び出されるため、main提供する必要のあるインターフェイスは事前定義されています(を返すint必要があり、ゼロの引数または2つ、最初の引数、int2番目の引数またはchar **同等の引数を取る必要がありますchar *[])。CおよびC++標準では、という名前の外部リンケージを持つ関数がプログラム1mainのエントリポイントとして機能するように指定されています。

少なくともこの用語が通常使用されているように、事前定義された関数は、sinまたはprintf標準ライブラリにある関数であるため、自分で作成しなくても使用できます。

1技術を習得したい場合、それは「ホストされた」実装にのみ当てはまります。つまり、ほとんどの場合、オペレーティングシステムで実行されるプログラムを生成するために使用する種類です。「自立型」の実装(オペレーティングシステムがない「ベアメタル」上で直接実行されるプログラムを作成するもの)は、適切と思われるエントリポイントを自由に定義できます。独立した実装では、通常のランタイムライブラリのほとんどを除外することもでき、ほんの一握りのヘッダー(たとえば<stddef.h>)のみを提供し、実質的に標準ライブラリ関数は提供しません。

于 2010-08-23T17:05:59.700 に答える
8

はい、main「定義済み」という言葉の一般的な意味で定義済みの関数です。つまり、C 言語標準では、プログラムの起動時に呼び出される関数の名前はmain. fooこれは、またはのようにプログラマーが使用する単なる規則ではありませんbar

細字: C プログラミングのコンテキストにおける「定義済み」という言葉の技術的な意味の観点から、main関数は「事前定義済み」ではありません。コンパイラまたは C ライブラリは、 という名前の定義済み関数を提供しませんmain。関数の独自の実装を定義する必要がありmainます (そして、明らかに、名前を付ける必要がありますmain)。

于 2010-08-23T17:16:27.877 に答える
2

通常、通常のCプログラムがリンクされているコードがあります。

extern int main(int argc, char * argv[], char * envp[]);
FILE * stdin;
FILE * stdout;
FILE * stderr;


    /* ** setup argv  ** */
    ...

    /* ** setup envp  ** */
    ...

    /* ** setup stdio ** */
    stdin = fdopen(0, "r");
    stdout = fdopen(1, "w");
    stderr = fdopen(2, "w");

    int rc;
    rc = main(argc, argv, envp); // envp may not be present here with some systems
    exit(rc);

このコードはC++ではなくCであるため、mainがC関数であると想定していることに注意してください。また、私のコードはエラーチェックを行わず、おそらく発生する可能性のある他の多くのシステム依存のものを除外していることにも注意してください。また、C ++、Objective C、およびそれにリンクされている可能性のある他のさまざまな言語で発生するいくつかのことを無視します(特に、コンストラクターとデストラクタの呼び出し、および場合によってはメインがC++のtry/ catchブロック内にある)。

とにかく、このコードはmainが関数であることを認識しており、引数を取ります。メインが次のようになっている場合:

int main(void) {

その後、引数は渡されますが、無視されます。

このコードは、プログラムの起動時に呼び出されるように特別にリンクされています。

多くのアーキテクチャでこのコードの独自のバージョンを自由に作成できますが、オペレーティングシステムが新しいプログラムを開始する方法と、C(およびC ++、場合によってはObjective C)の実行時間に関する深い知識に依存しています。適切にビルドするには、アセンブリプログラミングやコンパイラ拡張機能の使用が必要になる可能性があります。

Cコンパイラドライバ(コンパイラを呼び出すときに通常呼び出すコマンド)は、これらすべてを含むオブジェクトファイル(Cランタイムの場合はcrt0.0と呼ばれることが多い...)を、プログラムの残りの部分とともにリンカに渡します。言われない限り。

オペレーティングシステムカーネルまたは組み込みプログラムを構築する場合、標準のcrt*.oファイルを使用したくないことがよくあります。また、別のプログラミング言語で通常のアプリケーションを構築している場合や、その他の非標準的な要件がある場合は、これを使用したくない場合があります。

于 2010-08-23T20:57:03.557 に答える
0

いいえ、または定義できませんでした。

事前定義されていませんが、エントリポイントが存在する場合は、その意味が定義されています。

于 2010-08-23T17:05:54.813 に答える