static
සී කේතයේ විවිධ ස්ථානවල භාවිතා වන වචනය මම දැක ඇත්තෙමි ; මෙය C # හි ස්ථිතික ශ්රිතයක් / පන්තියක් හා සමානද?
static
සී කේතයේ විවිධ ස්ථානවල භාවිතා වන වචනය මම දැක ඇත්තෙමි ; මෙය C # හි ස්ථිතික ශ්රිතයක් / පන්තියක් හා සමානද?
Answers:
(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
එමඟින් පරිශීලකයාට ඒවාට ප්රවේශ විය නොහැක. මෙය සංවෘත කිරීම, හොඳ පුරුද්දකි.
විකිපීඩියාව උපුටා දැක්වීම :
සී ක්රමලේඛන භාෂාවෙන්, ස්ථිතිකය ගෝලීය විචල්යයන් සහ කාර්යයන් සමඟ ඒවායේ විෂය පථය අඩංගු ගොනුවට සැකසීමට භාවිතා කරයි. දේශීය විචල්යයන්හි, ස්වයංක්රීයව වෙන් කරන ලද මතකය වෙනුවට සංඛ්යාත්මකව වෙන් කරන ලද මතකයේ විචල්යය ගබඩා කිරීමට ස්ථිතික භාවිතා වේ. එක් ආකාරයක මතකයක් ක්රියාත්මක කිරීම භාෂාව විසින් නියම නොකරන අතර, සංඛ්යාත්මකව වෙන් කරන ලද මතකය සාමාන්යයෙන් සංයුක්ත වේලාවේදී වැඩසටහනේ දත්ත කාණ්ඩයේ වෙන් කර ඇති අතර ස්වයංක්රීයව වෙන් කරන ලද මතකය සාමාන්යයෙන් ක්රියාත්මක වන්නේ අස්ථිර ඇමතුම් තොගයක් ලෙස ය.
ඔබේ දෙවන ප්රශ්නයට පිළිතුරු දීමට, එය 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 (විචල්ය-දිග අරාව) වේ. ඔබ අදහස් කළේ එයද?
කෙටි පිළිතුර ... එය රඳා පවතී.
ස්ථිතික අර්ථ දක්වා ඇති දේශීය විචල්යයන් ක්රියාකාරී ඇමතුම් අතර ඒවායේ වටිනාකම නැති නොකරයි. වෙනත් වචන වලින් කිවහොත් ඒවා ගෝලීය විචල්යයන් වන නමුත් ඒවා අර්ථ දක්වා ඇති දේශීය ශ්රිතයට අනුරූප වේ.
ස්ථිතික ගෝලීය විචල්යයන් ඒවා අර්ථ දක්වා ඇති සී ගොනුවෙන් පිටත නොපෙනේ.
ඒවා අර්ථ දක්වා ඇති සී ගොනුවෙන් පිටත ස්ථිතික ශ්රිත නොපෙනේ.
private
C හි නොමැති වුවද , ඔබේ ප්රතිසමය හොඳයි: ස්ථිතික විසින් ලබා දී ඇති ගොනුවකට දේවල් "පුද්ගලික" කරයි. C හි ගොනු බොහෝ විට C ++ හි පන්ති වලට සිතියම් ගත කරයි.
බහු ගොනු විචල්ය විෂය පථ උදාහරණය
බහුවිධ ලිපිගොනු හරහා ක්රියාකාරී අර්ථ දැක්වීම්වල විෂය පථයට ස්ථිතික බලපාන්නේ කෙසේද යන්න මෙහිදී මම පැහැදිලි කරමි.
ac
#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;
}
සම්පාදනය කර ධාවනය කරන්න:
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
ඔබට හැකි නම් සෑම විටම විචල්යයන් ප්රකාශ කරන්න.
සී ක්රමලේඛනයේදී, ලිපිගොනු බොහෝ විට "පන්ති" නියෝජනය කිරීමට භාවිතා කරන අතර static
විචල්යයන් පන්තියේ පුද්ගලික ස්ථිතික සාමාජිකයන් නියෝජනය කරයි.
ඒ ගැන කුමන ප්රමිතීන් පවසයිද?
C99 N1256 කෙටුම්පත 6.7.1 “ආචයන පංති පිරිවිතරයන්” පවසන්නේ static
එය “ගබඩා පන්තියේ පිරිවිතරයක්” බවයි.
6.2.2 / 3 “හඳුනාගැනීම් සම්බන්ධක” static
යන්නෙන් ගම්ය වන්නේ internal linkage
:
වස්තුවක් හෝ ශ්රිතයක් සඳහා ගොනු විෂය පථය හඳුනාගැනීමේ ප්රකාශනයේ ගබඩා පංති පිරිවිතර ස්ථිතික අඩංගු නම්, හඳුනාගැනීමට අභ්යන්තර සම්බන්ධතාවයක් ඇත.
සහ 6.2.2 / 2 පවසන්නේ internal linkage
අපගේ උදාහරණයේ දී මෙන් හැසිරෙන බවයි :
සම්පූර්ණ වැඩසටහනක් සමන්විත පරිවර්තන ඒකක සහ පුස්තකාල සමූහය තුළ, බාහිර සම්බන්ධතා සහිත විශේෂිත හඳුනාගැනීමේ සෑම ප්රකාශයක්ම එකම වස්තුවක් හෝ ශ්රිතයක් දක්වයි. එක් පරිවර්තන ඒකකයක් තුළ, අභ්යන්තර සම්බන්ධතා ඇති අනන්යතාවයේ සෑම ප්රකාශයකින්ම දැක්වෙන්නේ එකම වස්තුවක් හෝ ශ්රිතයකි.
"පරිවර්තන ඒකකය යනු පෙර සැකසුම් කිරීමෙන් පසු ප්රභව ගොනුවකි.
ජීසීසී එය ඊඑල්එෆ් (ලිනක්ස්) සඳහා ක්රියාත්මක කරන්නේ කෙසේද?
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 හි ELF පිරිවිතරයේ ලේඛනගත කර ඇත :
STB_LOCAL දේශීය සංකේත ඒවායේ අර්ථ දැක්වීම අඩංගු වස්තු ගොනුවෙන් පිටත නොපෙනේ. එකම නමකින් යුත් දේශීය සංකේත එකිනෙකට මැදිහත් නොවී බහුවිධ ගොනු වල පැවතිය හැකිය
එමඟින් එය නිරූපණය කිරීමට පරිපූර්ණ තේරීමක් කරයි static
.
ස්ථිතික නොමැතිව විචල්යයන් වන STB_GLOBAL
අතර පිරිවිතර මෙසේ පවසයි:
සම්බන්ධක සංස්කාරකය නැවත ස්ථානගත කළ හැකි වස්තු ලිපිගොනු කිහිපයක් ඒකාබද්ධ කරන විට, එය එකම නමක් සහිත STB_GLOBAL සංකේත පිළිබඳ බහු අර්ථ දැක්වීම් වලට ඉඩ නොදේ.
බහු ස්ථිතික නොවන අර්ථ දැක්වීම් වල සම්බන්ධක දෝෂ සමඟ සමපාත වේ.
අප සමඟ ප්රශස්තිකරණය ඉහළ නංවන්නේ නම් -O3
, si
සංකේතය සම්පූර්ණයෙන්ම සංකේත වගුවෙන් ඉවත් කරනු ලැබේ: එය කෙසේ හෝ පිටතින් භාවිතා කළ නොහැක. TODO ප්රශස්තිකරණයක් නොමැති විට සංකේත වගුවේ ස්ථිතික විචල්යයන් තබා ගන්නේ ඇයි? ඒවා ඕනෑම දෙයකට භාවිතා කළ හැකිද? සමහර විට නිදොස්කරණය සඳහා.
මෙයද බලන්න
static
කාර්යයන් සඳහා සමාන වේ: https://stackoverflow.com/a/30319812/895245static
සමග extern
"විරුද්ධ" උරුම වන්නේ,: මම කොහොමද source ගොනු අතර කොටස් විචල්යයන්ට 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
වෙනත් ස්ථානයකින් හෝ වෙනත් ස්ථානයකට පිවිසිය නොහැක .
බොහෝ සී පුස්තකාලවල සියලුම "පුද්ගලික" කාර්යයන් ස්ථිතික වන අතර බොහෝ "පොදු" ඒවා නොවේ.
සී හි 'ස්ථිතික' යන්නට අර්ථ දෙකක් ඇති බව ජනතාව දිගටම පවසති. මම එය නැරඹීමේ විකල්ප ක්රමයක් ඉදිරිපත් කරමි, එය තනි අර්ථයක් ලබා දෙයි:
එය අර්ථ දෙකක් ඇති බව පෙනී හේතුව 'ස්ථිතික' යෙදිය හැකි සෑම අයිතමය, සී, එනම් මේ වන විටත් මෙම ගුණ දෙක එක් කර එය එසේ, පෙනේ එම සුවිශේෂී භාවිතය පමණක් අනෙක් ඇතුළත් නම්.
උදාහරණයක් ලෙස, විචල්යයන් සලකා බලන්න. ශ්රිතයෙන් පිටත ප්රකාශිත විචල්යයන් දැනටමත් (දත්ත කාණ්ඩයේ) නොනැසී පවතී, එබැවින් 'ස්ථිතික' යෙදීමෙන් ඒවා වර්තමාන විෂය පථයෙන් (සම්පාදන ඒකකයෙන්) නොපෙනේ. ඊට හාත්පසින්ම වෙනස්ව, ශ්රිත ඇතුළත ප්රකාශිත විචල්යයන්ට දැනටමත් පවතින විෂය පථයට (ශ්රිතයට) පිටින් දෘශ්යතාවයක් නොමැති බැවින් 'ස්ථිතික' යෙදීමෙන් ඒවා නොනැසී පැවතිය හැකිය.
කාර්යයන් සඳහා 'ස්ථිතික' යෙදීම හරියට ගෝලීය විචල්යයන්ට අදාළ කිරීම හා සමානයි - කේතය අනිවාර්යයෙන්ම නොනැසී පවතී (අවම වශයෙන් භාෂාව තුළම), එබැවින් දෘශ්යතාව පමණක් වෙනස් කළ හැකිය.
සටහන: මෙම අදහස් සී සඳහා පමණක් අදාළ වේ. සී ++ හි, පන්ති ක්රමවලට 'ස්ථිතික' යෙදීම සැබවින්ම මූල පදයට වෙනත් අර්ථයක් ලබා දෙයි. ඒ හා සමානව C99 අරාව-තර්ක දිගුව සඳහා.
static
ලබා දෙයි .
විකිපීඩියාවෙන්:
සී ක්රමලේඛන භාෂාවෙන්, ස්ථිතිකය ගෝලීය විචල්යයන් සහ කාර්යයන් සමඟ ඒවායේ විෂය පථය අඩංගු ගොනුවට සැකසීමට භාවිතා කරයි. දේශීය විචල්යයන්හි, ස්වයංක්රීයව වෙන් කරන ලද මතකය වෙනුවට සංඛ්යාත්මකව වෙන් කරන ලද මතකයේ විචල්යය ගබඩා කිරීමට ස්ථිතික භාවිතා වේ. එක් ආකාරයක මතකයක් ක්රියාත්මක කිරීම භාෂාව විසින් නියම නොකරන අතර, සංඛ්යාත්මකව වෙන් කරන ලද මතකය සාමාන්යයෙන් සංයුක්ත වේලාවේදී වැඩසටහනේ දත්ත කාණ්ඩයේ වෙන් කර ඇති අතර ස්වයංක්රීයව වෙන් කරන ලද මතකය සාමාන්යයෙන් ක්රියාත්මක වන්නේ අස්ථිර ඇමතුම් තොගයක් ලෙස ය.
static
විවිධ සන්දර්භයන්හි විවිධ දේ අදහස් කරයි.
සී ශ්රිතයක ස්ථිතික විචල්යයක් ඔබට ප්රකාශ කළ හැකිය. මෙම විචල්යය දෘශ්යමාන වන්නේ ශ්රිතය තුළ පමණි, කෙසේ වෙතත් එය ගෝලීය ලෙස හැසිරෙන්නේ එය එක් වරක් පමණක් ආරම්භ කර එහි වටිනාකම රඳවා තබා ගනිමිනි. මෙම උදාහරණයේ දී, ඔබ foo()
එය අමතන සෑම අවස්ථාවකම වැඩි වන සංඛ්යාවක් මුද්රණය කරනු ඇත. ස්ථිතික විචල්යය ආරම්භ කරනු ලබන්නේ එක් වරක් පමණි.
void foo ()
{
static int i = 0;
printf("%d", i); i++
}
ස්ථිතිකයේ තවත් භාවිතයක් වන්නේ ඔබ .c ගොනුවක ශ්රිතයක් හෝ ගෝලීය විචල්යයක් ක්රියාත්මක කරන නමුත් එහි සංකේතය .obj
ගොනුව මඟින් ජනනය කළ පිටතින් දෘශ්යමාන වීමට අවශ්ය නොවන විටය . උදා
static void foo() { ... }
මම පැරණි ප්රශ්නයකට පිළිතුරු දීමට අකමැතියි, නමුත් කේ ඇන්ඩ් ආර් එය “සී ක්රමලේඛන භාෂාව” හි A4.1 කොටසේ පැහැදිලි කරන්නේ කෙසේදැයි කිසිවෙකු සඳහන් කර ඇතැයි මම නොසිතමි.
කෙටියෙන් කිවහොත්, ස්ථිතික යන වචනය අර්ථ දෙකක් සමඟ භාවිතා වේ :
static
මූල පදය (අ ඉඟි පද ලෙස කේතය භාවිතා කරමින් එය මත විශාල අවධාරණය) ප්රකාශ සමග භාවිතා වන අතර, එය වස්තුවක් අභ්යන්තර සම්බන්ධතාවය නිසාම එය පරිවර්තනය ඒකකයක් තුළ පමණක් භාවිතා කළ හැකි නිසා ලබා දෙයි. නමුත් ශ්රිතයක් තුළ මූල පදය භාවිතා කරන්නේ නම්, එය වස්තුවෙහි ගබඩා පන්තිය වෙනස් කරයි (වස්තුව කෙසේ හෝ එම ශ්රිතය තුළ පමණක් දැකිය හැකිය). ස්ථිතිකයේ ප්රතිවිරුද්ධ දෙය නම් extern
, එය වස්තුවකට බාහිර සම්බන්ධතාවයක් ලබා දෙයි.පීටර් වැන් ඩර් ලින්ඩන් "විශේෂ C සී ක්රමලේඛනය" තුළ මෙම අර්ථ දෙක ලබා දෙයි:
register
වූ ගබඩා-පන්ති විශේෂණයක් (C99 ප්රමිතියේ දී 6.7.1 ගබඞා-පංති නිශ්චයකක්). එය හුදෙක් ඉඟියකට වඩා වැඩි ය, නිදසුනක් ලෙස , සම්පාදකයා ලේඛනයක් වෙන් කරන්නේ ද නැද්ද යන්න නොසලකා, &
ගබඩා පන්තියක් ඇති වස්තුවක් මත ක්රියාකරුගේ ලිපිනය යෙදිය register
නොහැක.
ඔබ ශ්රිත ස්ථිතිකයක විචල්යයක් ප්රකාශ කරන්නේ නම්, එහි අගය ශ්රිත ඇමතුම් තොගයේ ගබඩා නොවන අතර ඔබ නැවත ශ්රිතය ඇමතූ විට එය තවමත් පවතී.
ඔබ ගෝලීය විචල්ය ස්ථිතිකයක් ප්රකාශ කරන්නේ නම්, එහි විෂය පථය ඔබ ප්රකාශ කළ ගොනුව තුළට පමණක් සීමා වේ. මෙය ඔබේ මුළු වැඩසටහන පුරාම කියවිය හැකි හා වෙනස් කළ හැකි සාමාන්ය ගෝලීයයකට වඩා තරමක් ආරක්ෂිතයි.
C හි, ස්ථිතිකයට එහි භාවිතයේ විෂය පථය අනුව අර්ථ දෙකක් ඇත. ගෝලීය විෂය පථය තුළ, වස්තුවක් ගොනු මට්ටමින් ප්රකාශයට පත් කළ විට, එයින් අදහස් වන්නේ එම වස්තුව දෘශ්ය වන්නේ එම ගොනුව තුළ පමණක් බවයි.
වෙනත් ඕනෑම විෂය පථයක දී එය නිශ්චිත විෂය පථයට ඇතුළු වූ විවිධ කාලයන් අතර එහි වටිනාකම රඳවා ගන්නා වස්තුවක් ප්රකාශ කරයි. නිදසුනක් ලෙස, ක්රියා පටිපාටියක් තුළ int එකක් තෝරාගෙන තිබේ නම්:
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
තුළ, දත්ත කාණ්ඩයේ ගබඩා කර ඇත. එහි ආයු කාලය මුළු සී වැඩසටහනයි.
ශ්රිත ඇමතුම 1 ට var
පසුව, 2 var
බවට පත්වේ. ශ්රිත ඇමතුම 2 න් පසුව 3 බවට පත්වේ.
var
ශ්රිත ඇමතුම් අතර වටිනාකම විනාශ නොවේ.
නම් var
නොවන ස්ථිතික හා දේශීය විචල්ය අතර ඇති, එය සී වැඩසටහන අඩුක්කුව කොටස තුළ ගබඩා කර ඇත. ශ්රිතය නැවත පැමිණීමෙන් පසු ශ්රිතයේ සිරස් රාමුව විනාශ වන බැවින්, අගයvar
ද විනාශ වේ.
ආරම්භක ස්ථිතික විචල්යයන් සී වැඩසටහනේ දත්ත කාණ්ඩයේ ගබඩා කර ඇති අතර ආරම්භ නොකළ ඒවා බීඑස්එස් කාණ්ඩයේ ගබඩා කර ඇත.
ස්ථිතික පිළිබඳ තවත් තොරතුරු: විචල්යයක් ගෝලීය හා ස්ථිතික නම්, එයට සී වැඩසටහනේ ආයු කාලය ඇත, නමුත් එයට ගොනු විෂය පථය ඇත. එය දෘශ්ය වන්නේ එම ගොනුවේ පමණි.
මෙය උත්සාහ කිරීමට:
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
X ට file1.c හි ගොනු විෂය පථය ඇති බැවින් එය සම්බන්ධක දෝෂයක් ලබා දෙන අතර file2.c හි භාවිතා වන විචල්ය x වෙත යොමු කිරීම සම්බන්ධ කිරීමට සම්බන්ධකයට නොහැකි වනු ඇත.
යොමුව:
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).
ස්ථිතික විචල්යයන්ට ඒවායේ විෂය පථයෙන් බැහැර වූ පසුවත් ඒවායේ වටිනාකම ආරක්ෂා කිරීමේ දේපලක් ඇත ! එබැවින් ස්ථිතික විචල්යයන් ඒවායේ පෙර පරාසය ඔවුන්ගේ පෙර විෂය පථය තුළ ආරක්ෂා කර ගන්නා අතර නව විෂය පථය තුළ නැවත ආරම්භ නොකෙරේ.
උදාහරණයක් ලෙස මෙය දෙස බලන්න - වැඩසටහන ක්රියාත්මක වන විට ස්ථිතික 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]
නවකයකු සඳහා ඉහත විස්තර කර නොමැති මා සොයාගත් ප්රධාන ඒවා මේවායි!
සී ක්රමලේඛනයේදී, 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
එය ක්රියාත්මක කරන විට එය ගණන් විචල්යය විනාශ කරයි.