Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม C

Scope Rules (กฎขอบเขตตัวแปร) ของฟังก์ชันในภาษา C

Scope (ขอบเขต)** กำหนดว่า ตัวแปรสามารถ "มองเห็น" และ "เข้าถึง" ได้จากที่ไหนในโปรแกรม

ประเภท Scope หลัก

1. Local Scope (Block Scope)

  • ตัวแปรที่ประกาศใน Block (อยู่ใน { })
  • มองเห็นได้เฉพาะใน Block นั้นเท่านั้น
  • หายไปเมื่อ Block จบ (Automatic Storage Duration)

2. Global Scope (File Scope)

  • ตัวแปรที่ประกาศนอกฟังก์ชันทุกตัว
  • มองเห็นได้ทุกที่ในไฟล์หลังจากจุดประกาศ
  • อยู่ตลอดการรันโปรแกรม (Static Storage Duration)

ตัวอย่าง: Global vs Local

#include <stdio.h>

int r = 50;  // Global Variable

void fun() {
    printf("In fun: r = %d\n", r);  // เข้าถึง Global ได้
}

int main() {
    int p = 30;  // Local to main
    printf("In main: p = %d, r = %d\n", p, r);
    fun();
    return 0;
}

ผลลัพธ์

In main: p = 30, r = 50
In fun: r = 50

Scope Rules เกี่ยวกับ Function

  • ตัวแปรในฟังก์ชัน = Local Variable (อยู่ได้แค่ในฟังก์ชันนั้น)
  • ฟังก์ชันอื่นเข้าถึงไม่ได้ (แม้ชื่อเหมือนกันก็เป็นตัวคนละตัว)
  • ตัวแปรหายไปเมื่อฟังก์ชัน Return

ตัวอย่าง: Swap ผิด (Pass by Value)

#include <stdio.h>

void swap(int a, int b) {  // รับ Copy
    int c = a;
    a = b;
    b = c;
    // a, b ในนี้เปลี่ยน แต่ main ไม่ได้รับผล
}

int main() {
    int a = 10, b = 20;
    printf("Before: a=%d, b=%d\n", a, b);
    swap(a, b);
    printf("After:  a=%d, b=%d\n", a, b);  // ไม่เปลี่ยน!
    return 0;
}

ผลลัพธ์

Before: a=10, b=20
After:  a=10, b=20  // ไม่สลับได้!

ตัวอย่าง: Swap ถูกต้อง (Pass by Reference + Global)

#include <stdio.h>

int a = 10, b = 20;  // Global

void swap() {  // ไม่ต้องรับ Parameter
    int c = a;
    a = b;
    b = c;
}

int main() {
    printf("Before: a=%d, b=%d\n", a, b);
    swap();
    printf("After:  a=%d, b=%d\n", a, b);  // สลับได้!
    return 0;
}

ผลลัพธ์

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

Variable Shadowing (การบังตัวแปร)

int x = 10;  // Global

void foo() {
    int x = 20;  // Local ซ่อน Global
    printf("In foo: x = %d\n", x);  // 20
}

int main() {
    printf("In main: x = %d\n", x);  // 10
    foo();
    return 0;
}

Best Practices

  • ลด Global Variables ให้น้อยที่สุด (ยาก Debug, Namespace Pollution)
  • ใช้ static สำหรับ File-Scoped Variables ที่ไม่ต้อง Export
  • ส่งผ่าน Parameter (Pass by Reference) แทน Global
  • ประกาศตัวแปรให้ใกล้จุดใช้งานที่สุด (C99+)