今まで2年ほどJavaを使っていましたが、最近になってCを使う必要が出てきました。Cは大学の頃に授業で学んだ程度のレベルです。
それはさておき。
JavaやC++ではメソッド内のどの場所ででも、新たな変数を宣言して使用できますが、Cでは関数内の最初の方でしか宣言できないですよね?
先日、その事を意識せずに、Javaと同じように変数を関数の任意の場所で宣言しているようなCのソースを書き、gccでコンパイルしたところ、コンパイルが通ってしまいました。
その時のファイルは「.c」ファイルです。
このソースはC++のソースとして、コンパイラが認識してしまったのでしょうか?拡張子が「.cpp」ではなく「.c」のままでしたが、コンパイラは拡張子ではなく、ソースを読み込んでから、そのプログラムがCなのかC++なのか判断しているのでしょうか?
いまいちピンと来ないので、どなたか解説お願いします。
No.5ベストアンサー
- 回答日時:
最近のGCCでは、C89のGNU拡張がデフォルトになっています。
C99はGNU拡張を大幅に標準に取り込んだ経緯があることから、完全にC99に対応しているわけではないのに、C99でなければできないことができてしまうわけです。ブロックの途中における宣言のほか、複合リテラル、複素数型、可変長配列なども使えたと思います。これらは、標準Cでは使えますが、標準C++では使えない機能です(C++はCのスーパーセットではありません)。
なお、CかC++か(あるいはObjective-Cか)の判断は、基本的にはサフィックス(要は拡張子)を元に行いますが、コンパイルオプションで-x cとか-x c++とかすれば、強引に解釈を変えることも可能です。
ちなみに、「定義」というのは「宣言」の特殊なものです(「JIS X3010:2003 6.7 宣言」の意味規則のところ参照 p71)。古いC言語の場合、純粋な宣言(たとえば外部宣言や関数原型)もブロックの途中では行えないので、「宣言」の方が正しいと思います。
No.4
- 回答日時:
nepiatissueさん、今晩は。
C++とCとの区別は私の知っている範囲では、ご提示の通り拡張子のみで判断されます。従って、途中での宣言でコンパイルが通る理由としては、次の二つが考えられます。
1 既に回答にありますが、新しいコンパイラーのため、途中での定義が可能になった。
ちなみに、宣言じゃなくて正しくは定義だと思いますが、違いは認識されているでしょうか。
2 コンパイラーは新しくないがブロックの先頭に記述したため。
即ち、
>関数内の最初の方でしか宣言できない
この場合も、定義のつもりだと解釈しますが、この認識は誤りでブロック( 大括弧{と}で囲まれた範囲)の先頭には、変数の定義は昔から可能です。
蛇足ですが、
>最近になってCを使う必要が出てきました。
たとえ中身がCプログラムでも、拡張子を変えてC++としてコンパイルするとCより文法チェックが厳密ですので、私はいつもそうしています。もちろん、Cプログラムの内容によりますので、誰にでも勧められるわけではないですが。
No.3
- 回答日時:
数日前の質問にこんなやりとりがありました。
http://oshiete1.goo.ne.jp/kotaeru.php3?q=1889034
C99でANSIが規格統一を行った際、変数の宣言はどこで宣言されてもいいように規格化されました。
それ以降のANSI準拠のコンパイラは、gccでもこの規格に沿ってコンパイラを実装したので、C言語のソースでも途中から変数がでてもコンパイルできるようになったわけです。
なので、C++としてコンパイラが認識したわけではありません。新しいコンパイラだったからです。
が、古いコンパイラは古い規格のままなので、そのあたりは十分注意する必要がありますね。
No.2
- 回答日時:
1999年に決められたC99規格 (ISO/IEC 9899:1999 - Programming Language C) ではそのようなC++風な変数宣言が許されています。
gcc はバージョン 3.0 からC99に対応しているようです。エラーなくコンパイルできたのはそのためだと思います。参考URL:http://seclan.dll.jp/c99d/
No.1
- 回答日時:
C++は、どの場所で変数定義をしてもいいようになっています。
C言語なのかC++なのかという判断ですが、今となっては、C++がコンパイル出来るコンパイラは、C言語ももちろんコンパイル出来ます。C言語を拡張したものが、C++ということになるからです。なので、C言語で認識してとか、C++で認識してとかそういう話ではないと思います。
ただ、C++であっても、変数定義は、先頭部分に書くことをお勧めします。関数化・クラス化する際も、その方がわかりやすいと思います。(個人的かな^^;;)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- IT・エンジニアリング c言語とjavaの需要について 3 2022/06/23 22:59
- その他(プログラミング・Web制作) プログラミングについて(Python) 添付した画像はC言語で簡単に作ったソースで、1つの配列に5つ 3 2022/09/10 19:15
- C言語・C++・C# 競技プログラミングに関する質問です。 3 2022/04/03 19:51
- Excel(エクセル) Excel マクロで For 文のインデックスを先に宣言する理由 7 2022/08/27 00:26
- その他(プログラミング・Web制作) Pythonのライブラリ、randomについて 3 2022/09/20 14:30
- C言語・C++・C# 至急お願いします。C言語で.imgのファイルを読み込んで1バイトづつ出力するプログラムを作りたいので 3 2023/01/16 22:49
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- その他(プログラミング・Web制作) 変数宣言および代入について 4 2022/11/02 13:03
- C言語・C++・C# c言語 コマンドライン引数 4 2023/02/09 18:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C++ で、「)」が必要 というエ...
-
0除算して、落ちるプログラムと...
-
ABAQUS ユーザーサブルーチン...
-
io.hをincludeしたプログラムで...
-
関数の返す値で直接Bitをセット...
-
Linux/Unix系C言語...
-
PL/SQLで、区切りのスペースは...
-
変数(関数)名の頭に_
-
fortranでのNaNについて
-
IntelのMKLをC++で使用したいの...
-
コンパイルできない
-
Vba 実数および実数タイプの変...
-
VBAで仕様書は書きますか?
-
正しい五十音順について
-
VBAにてメール作成した際、一部...
-
あるプログラムのコマンドライ...
-
C言語(gcc), Linux, FTPプログ...
-
パックマンプログラム
-
Notepad++の関数リスト表示でC...
-
VBAが止まります。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
0除算して、落ちるプログラムと...
-
C++ で、「)」が必要 というエ...
-
コンパイルできない
-
C++でアボート(Abort)で処理が...
-
変数(関数)名の頭に_
-
Visual C++とVisual C++.NETの違い
-
Eclipseの環境設定について
-
volatile修飾について
-
コンパイラについて
-
linuxのセキュリティ対策と致し...
-
__extension__
-
io.hをincludeするとそのような...
-
コンパイラフラグ(compiler fla...
-
PICマイコンによる乱数の表示に...
-
conio.h? curses.h?
-
【エラー】Cpadで初めてコンパイル
-
ABAQUS ユーザーサブルーチン...
-
関数の戻り値による変数の初期化
-
Delphiの逆コンパイル
-
プリコンパイラとは?
おすすめ情報