グローバル変数の再宣言はOK?CとC++の挙動の違いをサンプルコードで徹底解説
C言語とC++では、同じコードを書いても変数の再宣言に対する扱いが異なります。この記事では、以下の4つのパターンに分けて、実際のサンプルコードと実行結果をもとに両言語の挙動を詳しく解説します。
- グローバル変数を初期化なしで再宣言する
- ローカル変数を初期化なしで再宣言する
- グローバル変数を初期化ありで再宣言する
- ローカル変数を初期化ありで再宣言する
1. グローバル変数を初期化なしで再宣言する場合
A) C言語の場合
#include <stdio.h>
int var;
int var;
int main(void)
{
printf("Var = %d", var);
return 0;
}
実行結果
Var = 0
B) C++の場合
#include <iostream>
using namespace std;
int var;
int var;
int main()
{
cout << "Var = " << var;
return 0;
}
コンパイル結果
error: redefinition of 'int var' note: 'int var' previously declared here
結果: C言語では、初期化なしのグローバル変数の再宣言(仮定義)が許され、値はデフォルトの0のままです。一方、C++では同じ名前の変数を二度宣言するとコンパイルエラーになります。
2. ローカル変数を初期化なしで再宣言する場合
A) C言語の場合
#include <stdio.h>
int main(void)
{
int var;
int var;
printf("Var = %d", var);
return 0;
}
コンパイル結果
error: redeclaration of 'var' with no linkage
B) C++の場合
#include <iostream>
using namespace std;
int main()
{
int var;
int var;
cout << "Var = " << var;
return 0;
}
コンパイル結果
error: redeclaration of 'int var'
結果: ローカル変数の再宣言は、C言語・C++のどちらでも許されず、両方ともコンパイルエラーとなります。
3. グローバル変数を初期化ありで再宣言する場合
A) C言語の場合
#include <stdio.h>
int var;
int var = 10;
int main(void)
{
printf("Var = %d", var);
return 0;
}
実行結果
Var = 10
B) C++の場合
#include <iostream>
using namespace std;
int var;
int var = 10;
int main()
{
cout << "Var = " << var;
return 0;
}
コンパイル結果
error: redeclaration of 'int var'
結果: C言語では、「未初期化の宣言」と「初期化付きの定義」を組み合わせた再宣言が可能で、最終的な値は10になります。C++ではコンパイルエラーとなります。
4. ローカル変数を初期化ありで再宣言する場合
A) C言語の場合
#include <stdio.h>
int main(void)
{
int var;
int var = 10;
printf("Var = %d", var);
return 0;
}
コンパイル結果
error: redeclaration of 'var' with no linkage
B) C++の場合
#include <iostream>
using namespace std;
int main()
{
int var;
int var = 10;
cout << "Var = " << var;
return 0;
}
コンパイル結果
error: redeclaration of 'int var'
結果: ローカル変数は、初期化の有無にかかわらず再宣言できません。C言語・C++ともにコンパイルエラーとなります。
まとめ:CとC++の再宣言ルール比較表
| ケース | C言語 | C++ |
|---|---|---|
| グローバル変数の再宣言(初期化なし) | ○ 許可される(値は0) | × コンパイルエラー |
| ローカル変数の再宣言(初期化なし) | × コンパイルエラー | × コンパイルエラー |
| グローバル変数の再宣言(初期化あり) | ○ 許可される(値は10) | × コンパイルエラー |
| ローカル変数の再宣言(初期化あり) | × コンパイルエラー | × コンパイルエラー |
なぜC言語だけ再宣言が許されるのか?
その鍵となるのが、C言語特有の「仮定義(tentative definition)」という仕組みです。ファイルスコープで int var; のように初期化式を伴わない定義を書くと、それは仮定義として扱われ、同じ翻訳単位内に複数存在しても1つの定義にまとめられます。明示的な初期化がない場合は0で初期化されます。
一方、C++には仮定義という概念がなく、同一スコープでの同名変数の再宣言はすべてエラーになるため、より厳格なルールとなっています。また、仮定義が適用されるのはファイルスコープ(グローバル変数)のみであり、ブロックスコープのローカル変数には当てはまらないため、C言語でもローカル変数の再宣言はできない点に注意しましょう。
-
C言語でプラス完全数(Armstrong数)を判定するプログラム
n桁の整数xが与えられたとき、その数が「プラス完全数(Plus Perfect Number)」であるかどうかを判定するのが本記事のテーマです。プラス完全数とは、各桁の数字dを桁数nでべき乗した値(dn)をすべて合計し、その合計が元の数と一致する場合を指します。この考え方は、いわゆる「Armstrong数(ナルシシスト数)」の判定とまったく同じものです。 具体例 入力:163 出力:完全数ではない 説明:1³ + 6³ + 3³ = 244 となり、163と一致しないため 入力:371 出力:完全数である 説明:3³ + 7³ + 1³ = 371 となり、元の数と一致するため 上記の例のよ
-
C言語でアームストロング数を判定するプログラムの作成方法
アームストロング数とは? 本記事では、入力された整数 n がアームストロング数(Armstrong number)であるかどうかを判定するCプログラムについて解説します。 アームストロング数とは、各桁の数字をそれぞれ「桁数(位数)」でべき乗し、その総和が元の数値と等しくなる数のことです。例えば、4桁の数 1634 は 14 + 64 + 34 + 44 = 1 + 1296 + 81 + 256 = 1634 となるため、アームストロング数です。 アームストロング数を求める基本的な考え方は、次の式のように表せます。 計算式: wxyz…. = pow(w, n) + pow(x, n) + p