C++でコンパイルできないCプログラムの作成方法
C++はC言語の後継言語とされ、Cの機能をすべて備え、Cコードとの互換性があると考えられています。しかし実際には、C++コンパイラでコンパイルするとエラーが発生する、つまりコンパイルできないCプログラムが存在します。
本記事では、C++ではコンパイルできないCプログラムの代表例を、具体的なコードとともに紹介します。
1. 宣言前の関数呼び出し
C++では、関数を宣言する前に呼び出すとコンパイルエラーになります。一方、C言語では暗黙的な関数宣言が行われるため、このコードは問題なく動作します。
サンプルコード
#include <stdio.h>
int main(){
printHello();
return 0;
}
void printHello(){
printf("TutorialsPoint");
}実行結果(C言語の場合)
TutorialsPoint
このコードをC++コンパイラでコンパイルすると、「printHello がこのスコープで宣言されていない」というエラーが発生します。C++では関数を使用する前に必ずプロトタイプ宣言が必要です。
2. voidポインタの暗黙的な変換
C言語では、void型ポインタを他のデータ型のポインタに暗黙的に代入できます。しかしC++では、voidポインタを他の型のポインタに代入する際に明示的な型キャストが必要です。
サンプルコード
#include <stdio.h>
int main(){
void *ptr;
int *ptr2 = ptr; /* CではOK、C++ではエラー */
return 0;
}C++で同じ動作をさせたい場合は、int *ptr2 = static_cast<int*>(ptr); のように明示的なキャストを記述する必要があります。
3. 初期化なしのconst変数宣言
C言語では、const変数を初期値なしで宣言することが可能です。しかしC++では、const変数は宣言時に必ず初期化しなければならず、初期化しないとコンパイルエラーになります。
サンプルコード
#include <stdio.h>
int main(){
const int x;
printf("%d", x);
return 0;
}実行結果(C言語の場合)
0
C言語では未初期化のconst変数の値は不定(多くの場合0)ですが、C++では「const変数が初期化されていない」というコンパイルエラーとなります。
4. const変数への通常ポインタの代入
C言語では、const修飾された変数のアドレスを通常のポインタに代入することが許容されています。しかしC++では、const変数のアドレスを通常のポインタに代入することは禁止されており、コンパイルエラーになります。
サンプルコード
#include <stdio.h>
int main(void){
int const x = 3424;
int *cptr = &x; /* CではOK、C++ではエラー */
printf("ポインタの値 : %d\n", *cptr);
return 0;
}実行結果(C言語の場合)
ポインタの値 : 3424
C++でconst変数を指す場合は、const int *cptr = &x; のようにconst修飾されたポインタを使用する必要があります。
5. C++のキーワードを変数名として使用
C言語では、C++で予約語となっているキーワードを変数名として使用できます。つまり、Cではコンパイルできますが、C++ではコンパイルできません。
サンプルコード
#include <stdio.h>
int main(void){
int class = 5;
printf("%d", class);
return 0;
}実行結果(C言語の場合)
5
「class」はC++ではクラスを定義するための重要なキーワードです。このほかにも、「new」「delete」「explicit」「template」「namespace」など、C++で追加されたキーワードはC言語では変数名として使用できますが、C++では使用できません。
まとめ
C++はC言語と高い互換性を持っていますが、言語仕様の違いにより、Cでは正常にコンパイル・実行できるプログラムがC++ではエラーになるケースが存在します。主な違いは以下の通りです。
- 関数は使用前に必ず宣言する必要がある
- voidポインタの代入には明示的な型キャストが必要
- const変数は宣言時に初期化が必須
- const変数への通常ポインタの代入は禁止
- C++のキーワード(class、new、deleteなど)は変数名に使用不可
C言語からC++への移行や、両言語の互換性を考慮したコードを書く際には、これらの違いを理解しておくことが重要です。
-
C++の再帰を使って木(ツリー)のサイズを計算するプログラムの作成方法
この問題では、二分木が与えられ、「再帰」を使って木のサイズを計算するプログラムを作成することが課題となります。 ここでいう木のサイズとは、その木に含まれるノードの総数のことです。 具体例を見ながら問題を理解していきましょう。 上の木の場合、サイズは 5 となります。 解法の考え方:再帰によるサイズ計算 木のサイズを求めるには、左部分木のサイズ + 右部分木のサイズ + 1(現在のノード) を計算します。再帰関数は、木の左右それぞれの部分木に対して呼び出され、部分木が存在しない(NULL の)場合は 0 を返します。 上記の例をこの手法で解いてみる ルート(値3)のサイズを求める場合: si
-
C++で作る「ハッピー・ウィメンズデイ」出力プログラム
世界中でお祝いされる「女性の日」。この記事では、その祝福メッセージをC++のコンソールプログラムとして出力する方法をご紹介します。記号「#」で描かれた円の中央に「7 Oct」と「Happy Womens Day」の文字列を表示し、さらにその下にはアスタリスク(*)でリボンのような模様を描く構成になっています。 サンプルコード #include <iostream> using namespace std; int main(){ // デザインのサイズを初期化 int n = 5; // 円(デザインの上半分)を描画するループ // 外側のループで高