CからC++への変更点
関数のプロトタイプ
C++では、一部C言語とは違う、または拡張された部分がいくつかあります
コンパイラの実装レベルや、低レベルな部分での違いは省略します
C++プログラムを読み書きするのに、Cプログラマが最低限知るべきことを紹介します
まずは、関数のプロトタイプについてです
C言語でのプロトタイプ宣言で、引数に何も値を受け取らない場合はvoidを明示する必要があります
しかし、C++では任意です。voidを省略すると値を受け取らない関数を意味します
#include <stdio.h>
/*C言語ではvoidを明示しなければならない*/
void func(void);
void func() {
puts("kitty on your lap");
}
int main() {
func();
return 0;
}
上はC言語プログラムです
C言語では、引数に何も受け取らない関数の場合は void を明示する必要があります
これは、ANSI C 標準が定まる前の、古いC言語の 前方宣言 との互換性のためです
#include <iostream>
using namespace std;
/*C++では、voidを省略できる*/
void func();
void func() {
cout << "Kitty on your lap";
}
int main() {
func();
return 0;
}
こちらはC++プログラムです
C++では void を省略できるため、何の問題もなくコンパイルすることができます
戻り値
関数の戻り値に対する仕様も少し変化しています
C言語の場合、関数の戻り値の方がプロトタイプで指定されている状態で
何も値を返さなかった場合でも、コンパイルできました(通常、警告が出る)
この場合は、内容が保証されない値が返されます
しかし、C++ではコンパイルできません
戻り値がある場合は、必ず何らかの値を返さなくてはなりません
/*test.c*/
#include <stdio.h>
int func() {
puts("Kitty on your lap");
return; /*警告が出る可能性があるが、コンパイル可能*/
}
int main() {
func();
return 0;
}
/*test.cpp*/
#include <iostream>
using namespace std;
int func() {
cout << "Kitty on your lap";
return; /*コンパイルエラーが出る*/
}
int main() {
func();
return 0;
}
変数の宣言位置
ANSI C 標準に準拠している C 言語でのローカル変数の宣言は
かならず、関数などのブロックの先頭で宣言しなければいけません
しかし、C++ではあらゆる場所で宣言可能です
そのため、関数内の中部などで宣言することも可能なのです
#include <stdio.h>
int main() {
puts("Kitty on your lap");
char str[128] = "CardCaptorSakura";
puts(str);
return 0;
}
このプログラムをC言語としてコンパイルするとエラーが発生します
しかし、ファイル拡張子をcppに変更してC++としてコンパイルするとコンパイルできます
for文 と if文
C++のfor文で、C言語と大きく異なる特徴が初期化部分です
上記したように、C++ではローカル変数を自由な位置で宣言可能です
そのため、forループで用いるカウンタ変数はfor文の初期化部分で宣言し
ループが終了すると共に、カウンタ変数が消滅することを利用します
for文の初期化部分で宣言されたカウンタ変数は、forループのローカルな範囲のみで生きます
#include <stdio.h>
int main() {
for(int i = 0 ; i < 10 ; i++)
puts("Kitty on your lap");
return 0;
}
C++のソースとしてコンパイルするとコンパイルできます
この宣言方法は、多くの場面で用いることができるので非常に便利です
これをC言語としてコンパイルすると、やはりエラーが発生します
同様に if 文の条件式で変数を宣言することもできます
これも、if ブロックで使う一時的な変数として宣言するものですが
if で変数を宣言するケースは稀です
#include <iostream>
int main() {
if (char *str = "Kitty on your lap") {
std::cout << str;
}
return 0;
}
ただし、綺麗で保守的なプログラムを書きたいのであれば
適当な位置で変数を宣言するのではなく、ブロックの先頭でまとめて宣言するべきです
型の省略
CとC++の違いで、代表的な例の一つに型の省略があります
Cでは、構造体、共用体、及び列挙型の変数の宣言時には
必ずその型を明示しなければいけませんでした
struct TAG value;
例えば、上はC言語で構造体 TAG 型の変数の宣言です
structは省略できそうな気がしますが、C言語でこれを省略することはできません
共用体なら union 列挙型なら enum であることを明示しなければいけないのです
C言語でこれを省略し、作業をブラックボックス化するには typedef などを使用しましたね
しかし、C++では型名のみを指定し、struct などを省略することができます
(もちろん、無理に省略しなくてもかまいませんが冗長です)
struct S_TAG {
int i;
};
union U_TAG {
int i;
double d;
};
enum E_TAG { A , B , C };
int main() {
S_TAG s_obj;
U_TAG u_obj;
E_TAG e_obj;
return 0;
}
これをC言語のソースとしてコンパイルするとエラーが発生しますが
C++としてならば問題なくコンパイルすることができます
コメント
C++のコメントは、C言語でお馴染みの /* ... */ を用いることができますが
これに付け加え // というコメントがサポートされています
// は一行コメントで、 // 以降その行をコメントとします
最近ではC言語でも // コメントがサポートされているのでご存知の方も多いでしょう
#include <iostream>
using namespace std;
int main() {
/* C言語お馴染みのコメント */
// C++のコメントです
// 一行コメントには閉じる記号はありません
cout << "Kitty"; //命令の後でも可能です
return 0;
}