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

C言語における関数のスコープルールとは?ローカル変数とグローバル変数の違いを解説

はじめに

C言語における「スコープ(有効範囲)」とは、変数がプログラム内のどこから参照できるかを決める重要な概念です。変数のスコープを正しく理解することは、バグの少ない、保守性の高いプログラムを書くための基本となります。本記事では、ローカルスコープとグローバルスコープの違い、そして関数に関するスコープルールを具体例とともに解説します。

ローカルスコープ(局所スコープ)

ローカルスコープでは、ブロック({ } の中)内で定義された変数は、そのブロック内でのみ有効となり、ブロックの外部からは参照できません。これにより、変数の影響範囲が限定され、意図しない副作用を防ぐことができます。

グローバルスコープ(大域スコープ)

グローバルスコープでは、すべてのブロックの外側で定義された変数が、プログラムの終了まで有効になります。つまり、プログラム内のどの関数からでもアクセス可能です。

スコープの基本例

#include <stdio.h>
int r = 50; /* グローバル領域 */
main() {
int p = 30;
printf("p=%d, r=%d", p, r);
fun();
}
fun() {
printf("r=%d", r);
}

実行結果

p = 30, r = 50
r = 50

この例では、変数 p は main 関数内で宣言されたローカル変数であるため main 関数内でのみ有効ですが、変数 r はグローバル変数であるため、別の関数 fun() からも参照できています。

関数に関するスコープルール

  • 関数とは、特定のタスクを実行するための文の集まり(ブロック)です。

  • 関数の本体(ブロック内)で宣言された変数は「ローカル変数」と呼ばれます。

  • ローカル変数は、それを宣言した関数の内部でのみ存在し、他の関数や main 関数からは参照できません。

  • ローカル変数は、関数が処理を完了して呼び出し元に戻ると同時に消滅します。

ローカル変数の例(値の交換に失敗するケース)

#include <stdio.h>
main() {
int a = 10, b = 20;
printf("before swapping a=%d, b=%d", a, b);
swap(a, b);
printf("after swapping a=%d, b=%d", a, b);
}
swap(int a, int b) {
int c;
c = a;
a = b;
b = c;
}

実行結果

Before swapping a=10, b=20
After swapping a=10, b=20

この例では、swap 関数の引数 a と b はローカル変数(仮引数)です。関数内で値を入れ替えても、それは関数内のコピーにすぎないため、main 関数側の a と b の値は変化しません。これがローカルスコープの典型的な挙動です。

グローバル変数の例(値の交換に成功するケース)

一方、関数の外側で宣言された変数は「グローバル変数」と呼ばれ、どの関数からでもアクセスできます。

#include <stdio.h>
int a = 10, b = 20;
main() {
printf("before swapping a=%d, b=%d", a, b);
swap();
printf("after swapping a=%d, b=%d", a, b);
}
swap() {
int c;
c = a;
a = b;
b = c;
}

実行結果

Before swapping a=10, b=20
After swapping a=20, b=10

この例では、a と b がグローバル変数であるため、swap 関数内での値の入れ替えが main 関数側にも反映され、交換後の値が正しく出力されます。

まとめ

C言語のスコープルールを理解することは、変数の有効範囲を適切に管理し、予期しない動作を防ぐために不可欠です。ローカル変数は関数内でのみ有効で、関数の終了とともに消滅します。一方、グローバル変数はプログラム全体からアクセス可能ですが、乱用すると可読性や保守性が低下するため、使用は必要最小限にとどめるのが良い設計とされています。

  1. C言語の関数の分類とは?引数と戻り値による4つのカテゴリを解説

    C言語における関数は、引数(ひきすう)の有無と戻り値(返り値)の有無という2つの観点から、以下の4つのカテゴリに分類できます。引数なし・戻り値なしの関数引数なし・戻り値ありの関数引数あり・戻り値なしの関数引数あり・戻り値ありの関数それぞれのカテゴリについて、サンプルコードと実行結果を交えながら詳しく見ていきましょう。1. 引数なし・戻り値なしの関数このタイプの関数は、呼び出し元からデータを受け取らず、計算結果も返しません。関数内で入力・処理・表示をすべて完結させるため、単純な処理に向いています。サンプルコード#include<stdio.h>main() {  

  2. Pythonの変数スコープ基本ルールとは?LEGBルールをわかりやすく解説

    Pythonにおける変数の参照順序(スコープの解決方法)を理解するうえで、最も有名なのが「LEGBルール」です。これは、Mark Lutz氏の名著『Learning Python』の中で紹介されている記憶術で、Pythonが変数を探す順序を4つの頭文字で表したものです。LEGBルールとは?Pythonは変数を参照する際、最も狭いスコープから最も広いスコープへと、以下の順序で名前を探します。L:Local(ローカル)現在実行中の関数内で定義された変数を指します。関数の内部で代入された変数は、その関数のローカルスコープに属します。E:Enclosing(エンクロージング)別の関数を囲む外側の関数(