คีย์เวิร์ด static ใน C มีความหมายหลากหลายขึ้นอยู่กับบริบท แต่สำหรับตัวแปร (Variables) จะทำให้ตัวแปรมี Lifetime ตลอดการทำงานของโปรแกรม และ Scope จำกัด ตามที่ประกาศ
คุณสมบัติของ Static Variables
- Initialized Once: เริ่มต้นค่าเพียงครั้งเดียว (ครั้งแรกที่ผ่านบรรทัดนั้น)
- Persist Value: รักษาค่าไว้ระหว่างการเรียกฟังก์ชัน
- Default Zero: หากไม่กำหนดค่า จะเป็น 0 อัตโนมัติ
- Scope: Local Static - เห็นได้เฉพาะใน Block/Function ที่ประกาศ | Global Static - เห็นได้เฉพาะใน File (Internal Linkage)
ไวยากรณ์
static datatype variable_name = value;
ตัวอย่าง: Local Static Variable ในฟังก์ชัน
#include <stdio.h>
void counter() {
static int count = 0; // เริ่มต้นครั้งเดียว
count++;
printf("Count: %d\n", count);
}
int main() {
counter(); // Count: 1
counter(); // Count: 2
counter(); // Count: 3
return 0;
}
ผลลัพธ์
Count: 1
Count: 2
Count: 3
ตัวอย่าง: Static vs Non-Static Local Variables
#include <stdio.h>
void func() {
static int staticVar = 0; // Static local
int autoVar = 0; // Automatic local
staticVar++;
autoVar++;
printf("Static: %d, Auto: %d\n", staticVar, autoVar);
}
int main() {
func(); // Static: 1, Auto: 1
func(); // Static: 2, Auto: 1
func(); // Static: 3, Auto: 1
return 0;
}
ผลลัพธ์
Static: 1, Auto: 1
Static: 2, Auto: 1
Static: 3, Auto: 1
Global Static Variables (File Scope)
// file1.c
static int fileGlobal = 10; // Internal Linkage - เห็นได้แค่ file1.c
void printFileGlobal() {
printf("fileGlobal = %d\n", fileGlobal);
}
// file2.c
// extern int fileGlobal; // Error: fileGlobal มี Internal Linkage
// ไม่สามารถเข้าถึง fileGlobal จาก file2.c ได้
ตารางสรุป Static ในบริบทต่างๆ
| บริบท | Lifetime | Scope/Visibility | Linkage |
|---|---|---|---|
| Local Static (ในฟังก์ชัน) | Program Duration | Block Scope (ในฟังก์ชัน) | No Linkage |
| Global Static (นอกฟังก์ชัน) | Program Duration | File Scope (ทั้งไฟล์) | Internal Linkage |
| Static Member (C++ Class) | Program Duration | Class Scope | External Linkage |
Best Practices
- ใช้ Local Static สำหรับ Stateful Functions (เช่น Counter, Cache, Singleton)
- ใช้ Global Static (
staticที่ File Scope) เพื่อ Encapsulation - ซ่อน Implementation Details - หลีกเลี่ยง Static Variables ใน Multithreaded Code (Race Conditions) - ใช้ Thread-local Storage หรือ Mutex
- ใน C++ ควรใช้
staticClass Members แทน Global Static Variables
ข้อควรระวัง
- Static Variables ใช้ Memory ตลอดโปรแกรม - อย่าใช้เกินไป
- Initialization ของ Local Static เป็น Thread-safe ใน C++11+ แต่ ไม่ Thread-safe ใน C
- Destruction Order ของ Static Variables ข้ามไฟล์ ไม่ได้รับการกำหนด (Static Initialization Order Fiasco)