Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

グローバル変数の再宣言は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言語でもローカル変数の再宣言はできない点に注意しましょう。

  1. C言語でプラス完全数(Armstrong数)を判定するプログラム

    n桁の整数xが与えられたとき、その数が「プラス完全数(Plus Perfect Number)」であるかどうかを判定するのが本記事のテーマです。プラス完全数とは、各桁の数字dを桁数nでべき乗した値(dn)をすべて合計し、その合計が元の数と一致する場合を指します。この考え方は、いわゆる「Armstrong数(ナルシシスト数)」の判定とまったく同じものです。 具体例 入力:163 出力:完全数ではない 説明:1³ + 6³ + 3³ = 244 となり、163と一致しないため 入力:371 出力:完全数である 説明:3³ + 7³ + 1³ = 371 となり、元の数と一致するため 上記の例のよ

  2. C言語でアームストロング数を判定するプログラムの作成方法

    アームストロング数とは? 本記事では、入力された整数 n がアームストロング数(Armstrong number)であるかどうかを判定するCプログラムについて解説します。 アームストロング数とは、各桁の数字をそれぞれ「桁数(位数)」でべき乗し、その総和が元の数値と等しくなる数のことです。例えば、4桁の数 1634 は 14 + 64 + 34 + 44 = 1 + 1296 + 81 + 256 = 1634 となるため、アームストロング数です。 アームストロング数を求める基本的な考え方は、次の式のように表せます。 計算式: wxyz…. = pow(w, n) + pow(x, n) + p