3

I am learning C, and after starting out learning C++ as my first compiled language, I decided to "go back to basics" and learn C.

There are two questions that I have concerning the ways each language deals with functions.

Firstly, why does C "not care" about the scope that functions are defined in, whereas C++ does?

For example,

int main()
{
    donothing();
    return 0;
}

void donothing() { }

the above will not compile in a C++ compiler, whereas it will compile in a C compiler. Why is this? Isn't C++ mostly just an extension on C, and should be mostly "backward compatible"?

Secondly, the book that I found (Link to pdf) does not seem to state a return type for the main function. I check around and found other books and websites and these also commonly do not specify return types for the main function. If I try to compile a program that does not specify a return type for main, it compiles fine (although with some warnings) in a C compiler, but it doesn't compile in a C++ compiler. Again, why is that? Is it better style to always specify the return type as an integer rather than leaving it out?

Thanks for any help, and just as a side note, if anyone can suggest a better book that I should buy that would be great!

4

6 に答える 6

6

まず、なぜ C は関数が定義されているスコープを「気にしない」のに対し、C++ は気にしないのでしょうか?

実際、C は気にします。C89が暗黙的に宣言された関数を許可し、その戻り値の型intとそのパラメーターを使用法から推測するだけです。C99 では、これが許可されなくなりました。

したがって、あなたの例では、プロトタイプを次のように宣言したかのようです

int dosomething();

同じことが暗黙の戻り値の型にも当てはまります。戻り値の型が欠落している場合はint、C89 と同様に推測されますが、C99 では推測されません。でコードをコンパイルするgcc -std=c99 -pedantic-errorsと、次のような結果が得られます。

main.c: In function 'main':
main.c:2:5: error: implicit declaration of function 'donothing' [-Wimplicit-function-declaration]
main.c: At top level:
main.c:5:6: error: conflicting types for 'donothing'
main.c:2:5: note: previous implicit declaration of 'donothing' was her

記録のために、これが私が使用したコードです:

int main() {
    donothing();
    return 0;
}
void donothing() { }
于 2012-10-05T09:36:13.517 に答える
3

これは、C++ がオプションのパラメーターをサポートしているためです。C++ が見たとき、donothing();それは次のように判断できませんdonothing:

void donothing(void);

また

void donothing(int j = 0);

これら 2 つのケースでは、異なるパラメーターを渡す必要があります。また、C++ は C よりも厳密に型付けされているためです。

于 2012-10-05T09:35:05.757 に答える
2
int main() {
    donothing();
    return 0;
}
void donothing() { } 

素敵な最小限の実例。

void donothing()gcc 4.2.1 では、上記のコードは、既定のコンパイラ設定と競合する型に関する警告を受け取ります。これが、C89 標準がこの種の問題に対処するように言っていることです。clang を使用すると、上記のコードは で失敗しvoid donothing()ます。C99 標準は少し厳格です。

警告を有効にし、しきい値を高く設定して C++ コードをコンパイルすることをお勧めします。これは、C ではさらに重要になります。警告を有効にしてコンパイルし、暗黙的な関数宣言をエラーとして扱います。

C と C++ のもう 1 つの違い: C++ では、宣言void donothing(void);と宣言の間に違いはありません。C ではvoid donothing();、これら 2 つの間に大きな違いがあります。1 つ目は、パラメーターを取らない関数です。後者は、呼び出しシーケンスが指定されていない関数です。

donothing()引数を取らない関数を指定するために使用しないでください。donothing(1,2,3)コンパイラは、この形式で受け入れるしかありません。donothing(1,2,3)関数が として宣言されている場合、拒否することを知っていvoid donothing(void)ます。

于 2012-10-05T10:37:40.397 に答える
2

上記は C++ コンパイラではコンパイルされませんが、C コンパイラではコンパイルされます。どうしてこれなの?

C++ では、呼び出しの時点で関数の宣言 (または定義) がスコープ内にある必要があるためです。

C++ はほとんどが C の単なる拡張機能ではありませんか

ではない正確に。もともとは一連の C 拡張に基づいており、C の標準ヘッダーの内容の定義については C 標準 (いくつかの変更を加えたもの) を参照しています。C++ の「言語自体」は C に似ていますが、言語そのものではありません。それの延長。

そして、ほとんど「下位互換性」があるべきですか?

「ほとんど」を強調。ほとんどの C 機能は C++ で使用できます。削除された機能の多くは、C++ を C より厳密に型指定された言語にするためのものでした。しかし、C コードが C++ としてコンパイルされるという特別な期待はありません。たとえそうであっても、常に同じ意味を持っているとは限りません。

私は他の本やウェブサイトを調べて見つけましたが、これらも通常、メイン関数の戻り値の型を指定していません

mainC および C++ 標準では、 が を返すと常に言われてきintました。

C89 では、関数の戻り値の型を省略すると、 と見なされますint。C++ と C99 にはどちらも、この暗黙の int 戻り値の型がありませんが、多くの C チュートリアルの本とチュートリアル (およびコンパイラとコード) は、依然として C89 標準を使用しています。

Cには、実装が他の戻り値の型を受け入れるための許容範囲がありますが、移植可能なプログラムがそれらを要求するための許容範囲はありません. どちらの言語にも「独立した実装」の概念があり、プログラムの開始と終了を好きなように定義できます。繰り返しますが、これは実装に固有のものであるため、C の一般的な教育には適していません。

IMO、C89コンパイラを使用する場合でも、有効なC99になるようにコードを書く価値があります(特に、C99コンパイラを使用してチェックできる場合)。C99 で削除された機能は、何らかの形で有害であると見なされていました。言語間の相互運用を目的としたヘッダー ファイルを除いて、C と C++ の両方でコードを記述しようとしても意味がありません。

「基本に立ち返って」C を学ぶことにしました。

C を C++ の前提条件または「基本形式」と考えるべきではありません。そうではないからです。ただし、これはより単純な言語であり、高レベルのプログラミング用の機能が少なくなっています。これは、C のユーザーによる C の利点としてよく引用されます。また、C++ のユーザーによる C++ の利点としても挙げられます。場合によっては、それらのユーザーが同じ言語を異なる目的で使用している場合もあります。

C での典型的なコーディング スタイルは、C++ での典型的なコーディング スタイルとは異なるため、特定の基本は C++ よりも C の方が容易に習得できる可能性があります。C++ を使用して低レベルのプログラミングを学習することは可能であり、そのときに作成するコードは、最終的に C コードのように見える場合とそうでない場合があります。

したがって、C の学習中に学んだことは、C++ の書き方に影響する場合もあれば、そうでない場合もあります。もしそうなら、それは良いことかもしれませんし、そうでないかもしれません。

于 2012-10-05T09:55:22.570 に答える
1

C++ は、C++ をよりタイプセーフな言語にするために、意図的にこれらのルールを変更しました。

C.1.4 節 5: 式[diff.expr]
5.2.2
変更:関数の暗黙的な宣言は許可されない理由
: C++ のタイプ セーフな性質。
元の機能への影響:意味的に明確に定義された機能の削除。注: 元の機能は、ISO C では「時代遅れ」とラベル付けされていました。
変換の難しさ:構文変換。明示的な関数宣言を生成する機能は、商業的にかなり普及しています。
広く使用されている方法:一般的です。

このドラフト C++ 標準の付録 C には、他の同様の変更があります。

于 2012-10-05T09:43:47.887 に答える
0

C++ はほとんどが C の単なる拡張機能ではありませんか

いいえ、C++ を「C with Classes」と考えるなら、それは非常に間違っています。厳密には、最も有効なC は有効なC++ ですが、優れたC++ である優れたC は事実上ありません。現実には、優れた C++ コードは、優れた C コードと見なされるものとは大きく異なります。

まず、なぜ C は関数が定義されているスコープを「気にしない」のに対し、C++ は気にしないのでしょうか?

本質的に、C++ と同じルールを強制しないと、C でこれを行うと恐ろしく危険になり、実際、正気な人は決してそれを行うべきではないからです。C99 では、C 言語の暗黙的な int やその他の欠陥とともに、これが強化されました。

于 2012-10-05T12:40:34.510 に答える