ฉันเห็นคำที่static
ใช้ในที่ต่างๆในรหัส C มันเป็นเหมือนฟังก์ชั่นแบบคงที่ / คลาสใน C # (ที่มีการใช้งานร่วมกันทั่ววัตถุ)?
ฉันเห็นคำที่static
ใช้ในที่ต่างๆในรหัส C มันเป็นเหมือนฟังก์ชั่นแบบคงที่ / คลาสใน C # (ที่มีการใช้งานร่วมกันทั่ววัตถุ)?
คำตอบ:
(1) เป็นหัวข้อต่างประเทศมากขึ้นถ้าคุณเป็นมือใหม่ดังนั้นนี่คือตัวอย่าง:
#include <stdio.h>
void foo()
{
int a = 10;
static int sa = 10;
a += 5;
sa += 5;
printf("a = %d, sa = %d\n", a, sa);
}
int main()
{
int i;
for (i = 0; i < 10; ++i)
foo();
}
ภาพพิมพ์นี้:
a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60
สิ่งนี้มีประโยชน์สำหรับกรณีที่ฟังก์ชันต้องการรักษาสถานะระหว่างการเรียกใช้และคุณไม่ต้องการใช้ตัวแปรโกลบอล อย่างไรก็ตามควรใช้คุณลักษณะนี้อย่างประหยัดมาก - ทำให้โค้ดของคุณไม่ปลอดภัยและยากต่อการเข้าใจ
(2) มีการใช้งานอย่างกว้างขวางว่าเป็นคุณสมบัติ "การควบคุมการเข้าถึง" หากคุณมีไฟล์. c ที่ใช้ฟังก์ชั่นการใช้งานบางอย่างมันมักจะแสดงฟังก์ชั่น "สาธารณะ" เพียงเล็กน้อยให้กับผู้ใช้ ควรทำฟังก์ชั่นที่เหลือstatic
เพื่อให้ผู้ใช้ไม่สามารถเข้าถึงได้ นี่คือการห่อหุ้มการปฏิบัติที่ดี
การอ้างถึงWikipedia :
ในภาษาการเขียนโปรแกรม C สแตติกจะใช้กับตัวแปรและฟังก์ชั่นทั่วโลกเพื่อกำหนดขอบเขตของไฟล์ที่มี ในตัวแปรโลคัลสแตติกถูกใช้เพื่อเก็บตัวแปรในหน่วยความจำที่จัดสรรแบบสแตติกแทนที่จะเป็นหน่วยความจำที่จัดสรรโดยอัตโนมัติ ในขณะที่ภาษาไม่ได้กำหนดการใช้งานของหน่วยความจำทั้งสองประเภทหน่วยความจำที่จัดสรรแบบสแตติกจะถูกสงวนไว้ในส่วนของข้อมูลของโปรแกรม ณ เวลาที่คอมไพล์ในขณะที่หน่วยความจำที่จัดสรรโดยอัตโนมัติ
และเพื่อตอบคำถามที่สองของคุณมันไม่เหมือนกับใน C #
อย่างไรก็ตามใน C ++ static
ยังใช้เพื่อกำหนดแอตทริบิวต์คลาส (ใช้ร่วมกันระหว่างวัตถุทั้งหมดของคลาสเดียวกัน) และวิธีการ ใน C ไม่มีคลาสดังนั้นคุณลักษณะนี้จึงไม่เกี่ยวข้อง
.c
ไฟล์ส่วนหัวหนึ่งไฟล์ แต่ปีศาจมักจะอยู่ในสิ่งที่ไม่ธรรมดา
มีอีกหนึ่งการใช้ที่ไม่ครอบคลุมในที่นี้และนั่นเป็นส่วนหนึ่งของการประกาศประเภทอาเรย์ว่าเป็นอาร์กิวเมนต์ของฟังก์ชัน:
int someFunction(char arg[static 10])
{
...
}
ในบริบทนี้สิ่งนี้ระบุว่าอาร์กิวเมนต์ที่ส่งผ่านไปยังฟังก์ชันนี้ต้องเป็นอาร์เรย์ที่char
มีองค์ประกอบอย่างน้อย 10 องค์ประกอบ สำหรับข้อมูลเพิ่มเติมโปรดดูที่คำถามของฉันที่นี่
arg[0]
ผ่านไปarg[9]
จะมีค่า (ซึ่งหมายความว่าฟังก์ชั่นไม่ยอมรับตัวชี้โมฆะ) คอมไพเลอร์สามารถใช้ข้อมูลนี้เพื่อการปรับให้เหมาะสมและตัววิเคราะห์แบบสแตติกสามารถใช้ข้อมูลนี้เพื่อให้แน่ใจว่าฟังก์ชั่นไม่เคยได้รับตัวชี้โมฆะ (หรือถ้ามันสามารถบอกได้อาร์เรย์ที่มีองค์ประกอบน้อยกว่าที่ระบุ)
static
ใน C99 เป็นเวลากว่าทศวรรษครึ่งแล้วที่นักเขียนคอมไพเลอร์ทุกคนไม่ได้ใช้คุณสมบัติ C99 ทั้งหมดดังนั้น C99 จึงยังไม่เป็นที่ทราบแน่ชัด
int arr[n];
นั่นคือVLA (อาเรย์ที่มีความยาวผันแปร)ซึ่งถูกเพิ่มใน C99 นั่นคือสิ่งที่คุณหมายถึงอะไร
คำตอบสั้น ๆ ... มันขึ้นอยู่กับ
ตัวแปรโลคัลที่นิยามไว้แบบคงที่จะไม่สูญเสียค่าระหว่างการเรียกใช้ฟังก์ชัน กล่าวอีกนัยหนึ่งคือตัวแปรทั่วโลก แต่กำหนดขอบเขตให้กับฟังก์ชันโลคัลที่กำหนดไว้
ตัวแปรโกลบอลแบบสแตติกไม่สามารถมองเห็นได้นอกไฟล์ C ที่ถูกกำหนดไว้
ฟังก์ชั่นคงที่ไม่สามารถมองเห็นได้นอกไฟล์ C ที่มีการกำหนดไว้
private
ใน C การเปรียบเทียบของคุณดี: สแตติกทำให้ทุกสิ่ง "ส่วนตัว" เป็นไฟล์ที่กำหนด และไฟล์ใน C มักจะจับคู่กับคลาสใน C ++
ตัวอย่างขอบเขตตัวแปรหลายไฟล์
ที่นี่ฉันแสดงให้เห็นว่าสแตติกส่งผลกระทบต่อขอบเขตของนิยามฟังก์ชันในหลายไฟล์
ไฟฟ้ากระแสสลับ
#include <stdio.h>
/*
Undefined behavior: already defined in main.
Binutils 2.24 gives an error and refuses to link.
/programming/27667277/why-does-borland-compile-with-multiple-definitions-of-same-object-in-different-c
*/
/*int i = 0;*/
/* Works in GCC as an extension: https://stackoverflow.com/a/3692486/895245 */
/*int i;*/
/* OK: extern. Will use the one in main. */
extern int i;
/* OK: only visible to this file. */
static int si = 0;
void a() {
i++;
si++;
puts("a()");
printf("i = %d\n", i);
printf("si = %d\n", si);
puts("");
}
main.c
#include <stdio.h>
int i = 0;
static int si = 0;
void a();
void m() {
i++;
si++;
puts("m()");
printf("i = %d\n", i);
printf("si = %d\n", si);
puts("");
}
int main() {
m();
m();
a();
a();
return 0;
}
GitHub ต้นน้ำ
รวบรวมและเรียกใช้:
gcc -c a.c -o a.o
gcc -c main.c -o main.o
gcc -o main main.o a.o
เอาท์พุท:
m()
i = 1
si = 1
m()
i = 2
si = 2
a()
i = 3
si = 1
a()
i = 4
si = 2
การตีความ
si
หนึ่งสำหรับแต่ละไฟล์i
ตามปกติขอบเขตที่เล็กลงจะดีกว่าดังนั้นควรประกาศตัวแปรทุกครั้งstatic
ถ้าทำได้
ในการเขียนโปรแกรม C ไฟล์มักจะใช้เพื่อแสดง "คลาส" และstatic
ตัวแปรแสดงถึงสมาชิกสแตติกส่วนตัวของคลาส
มาตรฐานพูดถึงอะไร
C99 N1256 ฉบับร่าง 6.7.1 "ตัวระบุคลาสหน่วยเก็บข้อมูล" ระบุว่าstatic
เป็น "ตัวระบุระดับชั้นเก็บข้อมูล"
6.2.2 / 3 "การเชื่อมโยงของตัวระบุ" กล่าวstatic
ถึงนัยinternal linkage
:
หากการประกาศของตัวระบุขอบเขตไฟล์สำหรับวัตถุหรือฟังก์ชั่นนั้นมีตัวระบุคลาสเก็บข้อมูลแบบคงที่ตัวระบุจะมีการเชื่อมโยงภายใน
และ 6.2.2 / 2 บอกว่ามันinternal linkage
ทำงานเหมือนในตัวอย่างของเรา:
ในชุดของหน่วยการแปลและไลบรารีที่ประกอบเป็นโปรแกรมทั้งหมดการประกาศของตัวระบุเฉพาะที่มีการเชื่อมโยงภายนอกแสดงถึงวัตถุหรือฟังก์ชันเดียวกัน ภายในหนึ่งหน่วยการแปลการประกาศของตัวระบุแต่ละตัวที่มีการเชื่อมโยงภายในหมายถึงวัตถุหรือฟังก์ชันเดียวกัน
โดยที่ "หน่วยการแปลเป็นไฟล์ต้นฉบับหลังจากประมวลผลล่วงหน้า
GCC ใช้สำหรับ ELF (Linux) ได้อย่างไร
ด้วยการSTB_LOCAL
ผูกมัด
ถ้าเรารวบรวม:
int i = 0;
static int si = 0;
และแยกตารางสัญลักษณ์ด้วย:
readelf -s main.o
ผลลัพธ์ประกอบด้วย:
Num: Value Size Type Bind Vis Ndx Name
5: 0000000000000004 4 OBJECT LOCAL DEFAULT 4 si
10: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 i
ดังนั้นการผูกเป็นความแตกต่างที่สำคัญระหว่างพวกเขาเท่านั้น Value
เป็นเพียงส่วนชดเชยของพวกเขาใน.bss
ส่วนดังนั้นเราจึงคาดหวังว่ามันจะแตกต่างกัน
STB_LOCAL
เป็นเอกสารเกี่ยวกับข้อมูลจำเพาะของเอลฟ์ที่http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html :
STB_LOCAL สัญลักษณ์ท้องถิ่นจะมองไม่เห็นนอกไฟล์วัตถุที่มีคำจำกัดความของพวกเขา สัญลักษณ์ท้องถิ่นที่มีชื่อเดียวกันอาจมีอยู่ในหลายไฟล์โดยไม่รบกวนซึ่งกันและกัน
static
ซึ่งจะทำให้มันเป็นทางเลือกที่สมบูรณ์แบบที่จะเป็นตัวแทน
ตัวแปรที่ไม่มีค่าคงที่คืออะไรSTB_GLOBAL
และสเป็คพูดว่า:
เมื่อตัวแก้ไขลิงก์รวมหลายอ็อบเจ็กต์ไฟล์ที่เปลี่ยนตำแหน่งได้มันไม่อนุญาตให้นิยามหลาย ๆ สัญลักษณ์ STB_GLOBAL ด้วยชื่อเดียวกัน
ซึ่งเชื่อมโยงกับข้อผิดพลาดการเชื่อมโยงในหลาย ๆ คำจำกัดความคงที่
ถ้าเราเหวี่ยงขึ้นการเพิ่มประสิทธิภาพด้วย-O3
การsi
สัญลักษณ์จะถูกลบออกทั้งหมดจากตารางสัญลักษณ์: มันไม่สามารถนำมาใช้จากนอกนะ ทำไมต้องเก็บตัวแปรสแตติกไว้ในตารางสัญลักษณ์เลยเมื่อไม่มีการปรับให้เหมาะสม พวกเขาสามารถใช้เพื่ออะไร อาจแก้จุดบกพร่อง
ดูสิ่งนี้ด้วย
static
ฟังก์ชั่น: https://stackoverflow.com/a/30319812/895245static
กับextern
"ตรงกันข้าม" ใด: ฉันจะใช้ extern เพื่อแชร์ตัวแปรระหว่างไฟล์ต้นฉบับได้อย่างไรเนมสเปซที่ไม่ระบุชื่อ C ++
ใน C ++ คุณอาจต้องการใช้เนมสเปซที่ไม่ระบุชื่อแทนที่จะเป็นสแตติกซึ่งให้เอฟเฟกต์ที่คล้ายกัน แต่ซ่อนนิยามของประเภทเพิ่มเติม: เนมสเปซที่ไม่มีชื่อ / ไม่ระบุชื่อกับฟังก์ชั่นแบบคงที่
มันขึ้นอยู่กับ:
int foo()
{
static int x;
return ++x;
}
ฟังก์ชันจะคืนค่า 1, 2, 3 และอื่น ๆ --- ตัวแปรไม่ได้อยู่ในสแต็ก
static int foo()
{
}
หมายความว่าฟังก์ชันนี้มีขอบเขตในไฟล์นี้เท่านั้น ดังนั้น ac และ bc อาจมีfoo()
s ที่แตกต่างกันและ foo จะไม่ถูกเปิดเผยกับวัตถุที่ใช้ร่วมกัน ดังนั้นหากคุณกำหนด foo ใน ac คุณจะไม่สามารถเข้าถึงได้จากb.c
หรือจากที่อื่น ๆ
ในไลบรารี C ส่วนใหญ่ฟังก์ชัน "ส่วนตัว" ทั้งหมดเป็นแบบสแตติกและ "สาธารณะ" ส่วนใหญ่ไม่ใช่
ผู้คนต่างบอกว่า 'คงที่' ใน C มีความหมายสองประการ ฉันเสนอวิธีการอื่นในการดูซึ่งให้ความหมายเดียว:
เหตุผลที่ดูเหมือนจะมีความหมายสองประการคือใน C ทุกรายการที่ 'คงที่' อาจถูกนำไปใช้มีคุณสมบัติหนึ่งในสองคุณสมบัตินี้ดังนั้นจึงดูเหมือนว่าการใช้งานเฉพาะนั้นเกี่ยวข้องกับอีกอย่างหนึ่งเท่านั้น
ตัวอย่างเช่นพิจารณาตัวแปร ตัวแปรที่ประกาศภายนอกฟังก์ชั่นมีการคงอยู่ (ในส่วนของข้อมูล) ดังนั้นการใช้ 'คงที่' จะทำให้ไม่สามารถมองเห็นได้นอกขอบเขตปัจจุบัน (หน่วยการรวบรวม) ในทางตรงกันข้ามตัวแปรที่ประกาศไว้ภายในฟังก์ชั่นมีการมองเห็นไม่ได้อยู่นอกขอบเขตปัจจุบัน (ฟังก์ชั่น) ดังนั้นการใช้ 'คงที่' สามารถทำให้มันคงอยู่ได้เท่านั้น
การใช้ 'คงที่' กับฟังก์ชั่นก็เหมือนกับการนำไปใช้กับตัวแปรทั่วโลก - รหัสจำเป็นต้องคงอยู่ (อย่างน้อยภายในภาษา) ดังนั้นการมองเห็นเท่านั้นที่สามารถเปลี่ยนแปลงได้
หมายเหตุ: ความคิดเห็นเหล่านี้ใช้เฉพาะกับ C ใน C ++ การใช้ 'คงที่' กับวิธีการเรียนเป็นการให้ความหมายที่แตกต่างกันอย่างแท้จริง ในทำนองเดียวกันสำหรับการขยายอาเรย์อาร์กิวเมนต์ C99
static
ให้การเชื่อมโยงภายในกับตัวระบุ
จาก Wikipedia:
ในภาษาการเขียนโปรแกรม C สแตติกจะใช้กับตัวแปรและฟังก์ชั่นทั่วโลกเพื่อกำหนดขอบเขตของไฟล์ที่มี ในตัวแปรโลคัลสแตติกถูกใช้เพื่อเก็บตัวแปรในหน่วยความจำที่จัดสรรแบบสแตติกแทนที่จะเป็นหน่วยความจำที่จัดสรรโดยอัตโนมัติ ในขณะที่ภาษาไม่ได้กำหนดการใช้งานของหน่วยความจำทั้งสองประเภทหน่วยความจำที่จัดสรรแบบสแตติกจะถูกสงวนไว้ในส่วนของข้อมูลของโปรแกรม ณ เวลาที่คอมไพล์ในขณะที่หน่วยความจำที่จัดสรรโดยอัตโนมัติ
static
หมายถึงสิ่งที่แตกต่างในบริบทที่แตกต่างกัน
คุณสามารถประกาศตัวแปรแบบคงที่ในฟังก์ชั่น C ตัวแปรนี้สามารถมองเห็นได้เฉพาะในฟังก์ชั่น แต่มันทำงานเหมือนทั่วโลกในการที่จะเริ่มต้นเพียงครั้งเดียวและมันยังคงรักษามูลค่าของมัน ในตัวอย่างนี้ทุกครั้งที่คุณโทรfoo()
จะพิมพ์จำนวนที่เพิ่มขึ้น ตัวแปรคงที่จะเริ่มต้นได้เพียงครั้งเดียว
void foo ()
{
static int i = 0;
printf("%d", i); i++
}
การใช้งานสแตติกอีกอย่างหนึ่งคือเมื่อคุณใช้ฟังก์ชั่นหรือตัวแปรโกลบอลในไฟล์. c แต่ไม่ต้องการให้สัญลักษณ์ของมันปรากฏอยู่ด้านนอกของไฟล์ที่.obj
สร้างขึ้น เช่น
static void foo() { ... }
หากคุณประกาศตัวแปรในฟังก์ชั่นคงที่ค่าของมันจะไม่ถูกเก็บไว้ในฟังก์ชั่นการโทรสแต็คและจะยังคงสามารถใช้ได้เมื่อคุณเรียกใช้ฟังก์ชั่นอีกครั้ง
หากคุณประกาศตัวแปรโกลบอลสแตติกขอบเขตของมันจะถูก จำกัด ภายในไฟล์ที่คุณประกาศไว้ สิ่งนี้ปลอดภัยกว่า global เล็กน้อยเล็กน้อยซึ่งสามารถอ่านและแก้ไขได้ตลอดทั้งโปรแกรมของคุณ
ฉันเกลียดที่จะตอบคำถามเก่า แต่ฉันไม่คิดว่ามีใครพูดถึงวิธีที่ K&R อธิบายในหัวข้อ A4.1 ของ "ภาษาการเขียนโปรแกรม C"
กล่าวโดยย่อคำว่า static ใช้กับความหมายสองประการ:
static
คำหลัก (เน้นที่การใช้รหัสเป็นคำหลัก) ด้วยการประกาศจะให้การเชื่อมโยงภายในวัตถุนั้นเพื่อให้สามารถใช้ภายในหน่วยการแปลนั้นเท่านั้น แต่ถ้าใช้คีย์เวิร์ดในฟังก์ชั่นมันจะเปลี่ยนคลาสหน่วยเก็บข้อมูลของวัตถุ ตรงกันข้ามของคงที่คือextern
คำหลักซึ่งจะให้การเชื่อมโยงวัตถุภายนอกPeter Van Der Linden ให้ความหมายทั้งสองนี้ใน "การเขียนโปรแกรมผู้เชี่ยวชาญ C":
register
ตัวระบุระดับการจัดเก็บ (C99 6.7.1 ตัวระบุระดับการจัดเก็บ) ชัดเจน และมันเป็นมากกว่าคำใบ้ตัวอย่างเช่นคุณไม่สามารถใช้ที่อยู่ของผู้ประกอบการ&
บนวัตถุที่มีคลาสหน่วยเก็บข้อมูลregister
ไม่ว่าคอมไพเลอร์จะจัดสรรการลงทะเบียนหรือไม่
ใน C คงที่มีสองความหมายขึ้นอยู่กับขอบเขตของการใช้งาน ในขอบเขตส่วนกลางเมื่อมีการประกาศวัตถุในระดับไฟล์หมายความว่าวัตถุนั้นสามารถมองเห็นได้ภายในไฟล์นั้นเท่านั้น
ในขอบเขตอื่นใดมันจะประกาศวัตถุที่จะเก็บค่าไว้ระหว่างเวลาต่าง ๆ ที่มีการป้อนขอบเขตเฉพาะ ตัวอย่างเช่นถ้า int ถูก delcared ภายในขั้นตอน:
void procedure(void)
{
static int i = 0;
i++;
}
ค่าของ 'i' ถูกเตรียมใช้งานเป็นศูนย์ในการเรียกไปยังโพรซีเดอร์แรกและค่าจะถูกเก็บไว้ในแต่ละครั้งที่โพรซีเดอร์ถูกเรียกใช้ ถ้าพิมพ์ 'i' มันจะส่งออกลำดับ 0, 1, 2, 3, ...
เป็นสิ่งสำคัญที่จะต้องทราบว่าตัวแปรสแตติกในฟังก์ชั่นจะเริ่มต้นได้ที่รายการแรกในฟังก์ชั่นนั้นและคงอยู่แม้หลังจากการโทรของพวกเขาเสร็จสิ้นแล้ว ในกรณีของฟังก์ชันแบบเรียกซ้ำตัวแปรแบบคงที่จะได้รับการเตรียมใช้งานเพียงครั้งเดียวและยังคงอยู่เช่นเดียวกันกับการโทรแบบเรียกซ้ำทั้งหมดและแม้กระทั่งหลังจากการเรียกใช้ฟังก์ชันเสร็จสิ้นแล้ว
หากตัวแปรถูกสร้างขึ้นนอกฟังก์ชั่นก็หมายความว่าโปรแกรมเมอร์สามารถใช้ตัวแปรในไฟล์ต้นฉบับที่ตัวแปรถูกประกาศเท่านั้น
หากคุณประกาศสิ่งนี้ในmytest.c
ไฟล์:
static int my_variable;
ดังนั้นตัวแปรนี้สามารถเห็นได้จากไฟล์นี้เท่านั้น ตัวแปรไม่สามารถส่งออกได้ทุกที่
หากคุณประกาศภายในฟังก์ชันค่าของตัวแปรจะเก็บค่าไว้ทุกครั้งที่เรียกใช้ฟังก์ชัน
ฟังก์ชั่นคงที่ไม่สามารถส่งออกจากนอกไฟล์ ดังนั้นใน*.c
ไฟล์คุณกำลังซ่อนฟังก์ชั่นและตัวแปรหากคุณประกาศพวกเขาแบบคงที่
ตัวแปรสแตติกใน C มีอายุการใช้งานของโปรแกรม
หากกำหนดไว้ในฟังก์ชั่นจะมีขอบเขตในตัวเครื่องกล่าวคือสามารถเข้าถึงได้เฉพาะภายในฟังก์ชั่นเหล่านั้นเท่านั้น ค่าของตัวแปรสแตติกถูกเก็บรักษาไว้ระหว่างการเรียกใช้ฟังก์ชัน
ตัวอย่างเช่น:
void function()
{
static int var = 1;
var++;
printf("%d", var);
}
int main()
{
function(); // Call 1
function(); // Call 2
}
ในโปรแกรมข้างต้นvar
จะถูกเก็บไว้ในส่วนข้อมูล อายุการใช้งานคือโปรแกรม C ทั้งหมด
หลังจากการเรียกใช้ฟังก์ชัน 1 var
กลายเป็น 2 หลังจากการเรียกใช้ฟังก์ชัน 2 var
กลายเป็น 3
ค่าของvar
ไม่ถูกทำลายระหว่างการเรียกฟังก์ชัน
หากvar
มีระหว่างตัวแปรไม่คงที่และท้องถิ่นมันจะถูกเก็บไว้ในกองส่วนในโปรแกรม C เนื่องจากสแต็กเฟรมของฟังก์ชันถูกทำลายหลังจากฟังก์ชันส่งคืนค่าของvar
จึงถูกทำลายเช่นกัน
ตัวแปรสแตติกเริ่มต้นถูกเก็บไว้ในส่วนข้อมูลของโปรแกรม C ในขณะที่ตัวแปรเริ่มต้นจะถูกเก็บไว้ในเซ็กเมนต์ BSS
ข้อมูลอื่นเกี่ยวกับสแตติก: หากตัวแปรเป็นโกลบอลและสแตติกมันมีช่วงเวลาชีวิตของโปรแกรม C แต่มีขอบเขตไฟล์ มันสามารถมองเห็นได้เฉพาะในไฟล์นั้น
ลองทำสิ่งนี้:
static int x;
int main()
{
printf("Accessing in same file%d", x):
}
extern int x;
func()
{
printf("accessing in different file %d",x); // Not allowed, x has the file scope of file1.c
}
run gcc -c file1.c
gcc -c file2.c
ตอนนี้ลองเชื่อมโยงพวกเขาโดยใช้:
gcc -o output file1.o file2.o
มันจะให้ข้อผิดพลาด linker เป็น x มีขอบเขตไฟล์ของ file1.c และ linker จะไม่สามารถแก้ไขการอ้างอิงถึงตัวแปร x ที่ใช้ใน file2.c
อ้างอิง:
static int var = 1;
เปลี่ยนกลับค่าเป็นหนึ่งในแต่ละครั้ง
ตัวแปรคงที่เป็นตัวแปรพิเศษที่คุณสามารถใช้ในฟังก์ชั่นและมันจะบันทึกข้อมูลระหว่างการโทรและจะไม่ลบมันระหว่างการโทร ตัวอย่างเช่น:
void func(){
static int count; // If you don't declare its value, the value automatically initializes to zero
printf("%d, ", count);
++count;
}
void main(){
while(true){
func();
}
}
ผลลัพธ์:
0, 1, 2, 3, 4, 5, ...
printf("%d, ", count); count++;
ด้วย `printf ("% d, ", นับ ++) (ไม่ใช่ว่าสำคัญ: P)
ค่าตัวแปรสแตติกยังคงอยู่ระหว่างการเรียกใช้ฟังก์ชันที่แตกต่างกันและขอบเขตถูก จำกัด ไว้ที่บล็อกโลคัล var แบบคงที่จะเริ่มต้นด้วยค่า 0 เสมอ
มี 2 กรณี:
(1) ตัวแปรโลคัลที่ประกาศstatic
: จัดสรรในเซ็กเมนต์ข้อมูลแทนสแต็ก ค่าจะยังคงอยู่เมื่อคุณเรียกใช้ฟังก์ชันอีกครั้ง
(2) ตัวแปรหรือฟังก์ชั่นทั่วโลกประกาศstatic
: หน่วยการรวบรวมภายนอกที่มองไม่เห็น (เช่นสัญลักษณ์ท้องถิ่นในตารางสัญลักษณ์ระหว่างการเชื่อมโยง)
ตัวแปรสแตติกมีคุณสมบัติในการรักษาค่าของพวกเขาแม้ว่าจะอยู่นอกขอบเขตดังนั้นตัวแปรสแตติกจะรักษาค่าก่อนหน้าในขอบเขตก่อนหน้านี้และจะไม่เริ่มต้นอีกครั้งในขอบเขตใหม่
ดูตัวอย่างนี้ - ตัวแปร int แบบสแตติกยังคงอยู่ในหน่วยความจำในขณะที่โปรแกรมกำลังทำงาน ตัวแปรปกติหรืออัตโนมัติถูกทำลายเมื่อการเรียกใช้ฟังก์ชันที่มีการประกาศตัวแปรสิ้นสุด
#include<stdio.h>
int fun()
{
static int count = 0;
count++;
return count;
}
int main()
{
printf("%d ", fun());
printf("%d ", fun());
return 0;
}
สิ่งนี้จะออก: 1 2
ในฐานะที่ 1 ยังคงอยู่ในหน่วยความจำตามที่ประกาศคงที่
ตัวแปรสแตติก (เช่นตัวแปรโกลบอล) ถูกเตรียมใช้งานเป็น 0 หากไม่ได้กำหนดค่าเริ่มต้นอย่างชัดเจน ตัวอย่างเช่นในโปรแกรมด้านล่างค่าของ x ถูกพิมพ์เป็น 0 ในขณะที่ค่าของ y เป็นสิ่งที่ขยะ ดูสิ่งนี้สำหรับรายละเอียดเพิ่มเติม
#include <stdio.h>
int main()
{
static int x;
int y;
printf("%d \n %d", x, y);
}
สิ่งนี้จะออก: 0 [some_garbage_value]
นี่คือสิ่งสำคัญที่ฉันพบว่าไม่ได้อธิบายไว้ข้างต้นสำหรับมือใหม่!
ในการเขียนโปรแกรม C static
เป็นคำหลักที่สงวนไว้ซึ่งควบคุมทั้งอายุการใช้งานและการมองเห็น ถ้าเราประกาศว่าตัวแปรเป็นแบบคงที่ภายในฟังก์ชั่นมันจะมองเห็นได้ตลอดทั้งฟังก์ชั่นนั้น ในการใช้งานนี้อายุการใช้งานของตัวแปรคงที่จะเริ่มต้นเมื่อการเรียกใช้ฟังก์ชันและจะทำลายหลังจากการใช้งานฟังก์ชันนั้น คุณสามารถดูตัวอย่างต่อไปนี้:
#include<stdio.h>
int counterFunction()
{
static int count = 0;
count++;
return count;
}
int main()
{
printf("First Counter Output = %d\n", counterFunction());
printf("Second Counter Output = %d ", counterFunction());
return 0;
}
โปรแกรมด้านบนจะให้ผลลัพธ์นี้กับเรา:
First Counter Output = 1
Second Counter Output = 1
count = 0
เพราะทันทีที่เราเรียกฟังก์ชั่นมันจะเริ่มต้น และในขณะที่เราดำเนินการcounterFunction
มันจะทำลายตัวแปรนับ