C හි “ස්ථිතික” යන්නෙන් අදහස් කරන්නේ කුමක්ද?


1151

staticසී කේතයේ විවිධ ස්ථානවල භාවිතා වන වචනය මම දැක ඇත්තෙමි ; මෙය C # හි ස්ථිතික ශ්‍රිතයක් / පන්තියක් හා සමානද?



17
Und ලුන්ඩින් යන මාතෘකාවේ අවසානයේ සිට “සී වැඩසටහනක” ඉවත් කිරීමට හේතුව කුමක්ද? C ටැගය ඉදිරියේ එය තරමක් අතිරික්ත වේ , නමුත් ටැග් පරීක්ෂා නොකර වර්ගීකරණය වඩාත් ඉක්මණින් බැලීමට එය මට ඉඩ දෙයි. වෙනත් භාෂාවන් පිළිබඳ ප්‍රශ්න අඩංගු විය හැකි දිශාවකින් මා ප්‍රශ්නයට ලඟා වන විට මෙම අතිරික්තය ඉතා පහසු වේ, උදා: ස්ථිතික හෝ ගූගල් සෙවීම.
පලෙක්

5
AlePalec ටැග් ලැයිස්තුවේ ඇති අයිතම මාතෘකාව තුළ අතිරික්තයක් ඇති බවට SO ප්‍රතිපත්තියක් ඇත. වෙබ් අඩවිය ස්වයංක්‍රීයව සත්‍ය වෙබ් අඩවියට C එකතු කරයි. "සී ස්ථිතික" සඳහා ගූගල් එකක් මෙම පිළිතුර ඉහළම පහරක් ලෙස ලබා දෙයි. මෙය වෙනස් කිරීමට හේතුව මෙම ප්‍රශ්නය දැන් SO C භාෂා නිති අසන ප්‍රශ්නවල කොටසක් වන අතර එකතු කරන ලද සියලුම තනතුරු මඳක් ඔප දමා ඇත.
ලුන්ඩින්

1
Und ලුන්ඩින් මම "සී" මාතෘකාව තුළ තබා ගැනීමට කැමැත්තෙමි, මන්ද SO මාතෘකාවට එක් ටැගයක් පමණක් එකතු කරයි (වඩාත් සුලභ ද?). සමහර දිනවල "වාක්‍ය ඛණ්ඩය" C ට වඩා වැඩි ප්‍රශ්න කරා ළඟා වන්නේ නම් (එය හරස් භාෂා දෙයක් බැවින්) මම පැහැදිලි හැසිරීම භාවිතා කිරීමට කැමැත්තෙමි :-) සංස්කරණය කරන්න: අහ් නමුත් මෙටා ප්‍රශ්නයක් වෙනත් ආකාරයකින් කියනු ලැබේ: meta.stackexchange.com/questions/19190/…
සීරෝ සැන්ටිලි 郝海东 冠状 病 六四 法轮功 事件

Answers:


1532
  1. ශ්‍රිතයක් තුළ ස්ථිතික විචල්‍යයක් එහි අගය ආයාචනා අතර තබා ගනී.
  2. ස්ථිතික ගෝලීය විචල්‍යයක් හෝ ශ්‍රිතයක් "දැකිය හැක්කේ" එය ප්‍රකාශිත ගොනුවේ පමණි

(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 හි පන්ති නොමැත, එබැවින් මෙම අංගය අදාල නොවේ.


181
පැක්ස්, OP ස්ථිතික ගැන නොදන්නා බැවින් සම්පාදක ඒකක සහ ලිපිගොනු අතර වෙනසකට ඔහුව ඇද දැමීමට ඔබ යෝජනා කරනවාද? :-)
එලී බෙන්ඩර්ස්කි

139
සම්පාදක ඒකකය යනු සම්පාදකයා දකින තනි ගොනුවකි. ඔබේ .c ගොනුවට වෙනත් .c ගොනු ඇතුළත් විය හැකි නමුත්, පෙර සැකසුම් මඟින් ඇතුළත් කිරීම් වර්ග කිරීමෙන් පසුව, සම්පාදකයා අවසානයේ දකින්නේ තනි “සම්පාදන ඒකකයක්” පමණි.
එලී බෙන්ඩර්ස්කි

82
@robUK: සම්පාදකයා .h ගොනු ගැන පවා නොදනී - මේවා පෙර සකසනයේ .c ගොනු සමඟ සංයුක්ත වේ. ඉතින් ඔව් ඔබට කියන්න පුළුවන් .c ගොනුව, එහි සියලුම ශීර්ෂයන් ඇතුළත් කර ඇත්තේ තනි සම්පාදන ඒකකයක් ලෙසයි.
එලී බෙන්ඩර්ස්කි

6
OnyTonyD සමහර විට එය ව්‍යාකූල විය හැකි නමුත් සම්පාදනය ක්‍රියාත්මක වන්නේ එයයි. එය සාමාන්‍යයෙන් එක් .cහා ශීර්ෂ ලිපිගොනු පොකුරක් විය හැකි නමුත් යක්ෂයා සෑම විටම සාමාන්‍ය නොවන දෙයක සිටී.
පීටර්ෆ්

7
OnyTonyD සම්පාදකයා සම්පාදනය කරයි. පෙර සැකසුම්කරු පෙර සැකසුම් කරයි. මෙවලම් කට්ටලය 'සම්පාදකයා' ලෙස හැඳින්වීමෙන් එය හෝ එය කරන දේ වෙනස් නොවේ.
සැතපුම් මාර්ගය

234

මෙහි ආවරණය නොවන තවත් එක් භාවිතයක් ඇත, එය ශ්‍රිතයකට තර්කයක් ලෙස අරාව වර්ග ප්‍රකාශනයේ කොටසකි:

int someFunction(char arg[static 10])
{
    ...
}

මෙම සන්දර්භය තුළ, මෙම ශ්‍රිතය වෙත සම්මත කරන ලද තර්කවල charඅවම වශයෙන් මූලද්‍රව්‍ය 10 ක්වත් තිබිය යුතු බව මෙයින් නියම කෙරේ . වැඩි විස්තර සඳහා මගේ ප්‍රශ්නය මෙතැනින් බලන්න .


3
මම හිතුවේ නැහැ සීට අරාව තර්ක තියෙනවා කියලා? ලිනස් ටොවල්ඩ්ස් මෙය කරන පුද්ගලයින් ගැන කෝපයෙන් කෝප වේ.
suprjami

13
am ජමීබ්: සී හි අරාව තර්ක නොමැත, නමුත් මෙම නිශ්චිත වාක්‍ය ඛණ්ඩයෙන් අදහස් වන්නේ ශ්‍රිතය මඟින් අගයන් arg[0]ලබා arg[9]ගැනීමට අපේක්ෂා කරන බවයි (එයින් ගම්‍ය වන්නේ ශ්‍රිතය ශුන්‍ය දර්ශකයක් භාර නොගන්නා බවයි). සම්පාදකයින්ට මෙම තොරතුරු කෙසේ හෝ ප්‍රශස්තිකරණය සඳහා යොදා ගත හැකි අතර, ස්ථිතික විශ්ලේෂකයන්ට මෙම තොරතුරු කිසි විටෙකත් ශුන්‍ය දර්ශකයක් ලබා නොදෙන බවට සහතික කර ගත හැකිය (හෝ එය පැවසිය හැකි නම්, නියම කර ඇති ප්‍රමාණයට වඩා අඩු මූලද්‍රව්‍යයන් සහිත අරාවක්).
ඩ්‍රීම්ලැක්ස්

19
Ix ක්වික්ස් - මෙය staticC99 හි දී ලබා දී ඇති නව බර පැටවූ අර්ථයකි . එය දශක එකහමාරකට වඩා පැරණි නමුත් සියලු සම්පාදක ලේඛකයින් සියළුම C99 අංගයන් වැලඳගෙන නැත - එබැවින් සමස්තයක් ලෙස C99 බොහෝ දුරට නොදන්නා කරුණකි.
සුබ හරිත කිඩ් නැප්

upsuprjami "අරාව තර්ක" යන්නෙන් ඔබ අදහස් කරන්නේ කුමක්දැයි මට 100% ක් විශ්වාස නැත , නමුත් ඔබ අදහස් කරන්නේ නම් , එය C99 හි එකතු කරන int arr[n];ලද VLA (විචල්‍ය-දිග අරාව) වේ. ඔබ අදහස් කළේ එයද?
රස්තජාඩි

171

කෙටි පිළිතුර ... එය රඳා පවතී.

  1. ස්ථිතික අර්ථ දක්වා ඇති දේශීය විචල්‍යයන් ක්‍රියාකාරී ඇමතුම් අතර ඒවායේ වටිනාකම නැති නොකරයි. වෙනත් වචන වලින් කිවහොත් ඒවා ගෝලීය විචල්‍යයන් වන නමුත් ඒවා අර්ථ දක්වා ඇති දේශීය ශ්‍රිතයට අනුරූප වේ.

  2. ස්ථිතික ගෝලීය විචල්‍යයන් ඒවා අර්ථ දක්වා ඇති සී ගොනුවෙන් පිටත නොපෙනේ.

  3. ඒවා අර්ථ දක්වා ඇති සී ගොනුවෙන් පිටත ස්ථිතික ශ්‍රිත නොපෙනේ.


8
"ස්ථිතික ශ්‍රිතය" සහ "පුද්ගලික ශ්‍රිතය" යන්නෙන් අදහස් කරන්නේ එකම දෙයද? “ස්ථිතික ගෝලීය විචල්‍යයන්” සහ “පුද්ගලික ගෝලීය විචල්‍යයන්” එකම දේද?
user1599964

41
මෙය සී ගැන ය. සී හි පුද්ගලික / පොදු කිසිවක් නොමැත
chris

20
15 user1599964 privateC හි නොමැති වුවද , ඔබේ ප්‍රතිසමය හොඳයි: ස්ථිතික විසින් ලබා දී ඇති ගොනුවකට දේවල් "පුද්ගලික" කරයි. C හි ගොනු බොහෝ විට C ++ හි පන්ති වලට සිතියම් ගත කරයි.
සිරෝ සැන්ටිලි 郝海东 冠状 病 六四 事件 事件

69

බහු ගොනු විචල්‍ය විෂය පථ උදාහරණය

බහුවිධ ලිපිගොනු හරහා ක්‍රියාකාරී අර්ථ දැක්වීම්වල විෂය පථයට ස්ථිතික බලපාන්නේ කෙසේද යන්න මෙහිදී මම පැහැදිලි කරමි.

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;
}

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ඔබට හැකි නම් සෑම විටම විචල්‍යයන් ප්‍රකාශ කරන්න.

සී ක්‍රමලේඛනයේදී, ලිපිගොනු බොහෝ විට "පන්ති" නියෝජනය කිරීමට භාවිතා කරන අතර 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_LOCALhttp://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html හි ELF පිරිවිතරයේ ලේඛනගත කර ඇත :

STB_LOCAL දේශීය සංකේත ඒවායේ අර්ථ දැක්වීම අඩංගු වස්තු ගොනුවෙන් පිටත නොපෙනේ. එකම නමකින් යුත් දේශීය සංකේත එකිනෙකට මැදිහත් නොවී බහුවිධ ගොනු වල පැවතිය හැකිය

එමඟින් එය නිරූපණය කිරීමට පරිපූර්ණ තේරීමක් කරයි static.

ස්ථිතික නොමැතිව විචල්යයන් වන STB_GLOBALඅතර පිරිවිතර මෙසේ පවසයි:

සම්බන්ධක සංස්කාරකය නැවත ස්ථානගත කළ හැකි වස්තු ලිපිගොනු කිහිපයක් ඒකාබද්ධ කරන විට, එය එකම නමක් සහිත STB_GLOBAL සංකේත පිළිබඳ බහු අර්ථ දැක්වීම් වලට ඉඩ නොදේ.

බහු ස්ථිතික නොවන අර්ථ දැක්වීම් වල සම්බන්ධක දෝෂ සමඟ සමපාත වේ.

අප සමඟ ප්‍රශස්තිකරණය ඉහළ නංවන්නේ නම් -O3, siසංකේතය සම්පූර්ණයෙන්ම සංකේත වගුවෙන් ඉවත් කරනු ලැබේ: එය කෙසේ හෝ පිටතින් භාවිතා කළ නොහැක. TODO ප්‍රශස්තිකරණයක් නොමැති විට සංකේත වගුවේ ස්ථිතික විචල්‍යයන් තබා ගන්නේ ඇයි? ඒවා ඕනෑම දෙයකට භාවිතා කළ හැකිද? සමහර විට නිදොස්කරණය සඳහා.

මෙයද බලන්න

C ++ නිර්නාමික නාම අවකාශයන්

C ++ හි, ඔබට ස්ථිතික වෙනුවට නිර්නාමික නාම අවකාශයක් භාවිතා කිරීමට අවශ්‍ය විය හැකිය, එය සමාන බලපෑමක් ලබා ගනී, නමුත් වර්ග අර්ථ දැක්වීම් තවදුරටත් සඟවයි: නම් නොකළ / නිර්නාමික නාම අවකාශ එදිරිව ස්ථිතික කාර්යයන්


39

එය රඳා පවතියි:

int foo()
{
   static int x;
   return ++x;
}

ශ්‍රිතය 1, 2, 3 යනාදිය නැවත ලබා දෙනු ඇත. --- විචල්‍යය තොගයේ නොමැත.

ac:

static int foo()
{
}

එයින් අදහස් වන්නේ මෙම ශ්‍රිතයට විෂය පථය ඇත්තේ මෙම ගොනුවේ පමණක් බවයි. එබැවින් ac සහ bc එකිනෙකට වෙනස් foo()s තිබිය හැකි අතර foo හවුල් වස්තු වලට නිරාවරණය නොවේ. එබැවින් ඔබ foo ac ලෙස අර්ථ දැක්වුවහොත් ඔබට b.cවෙනත් ස්ථානයකින් හෝ වෙනත් ස්ථානයකට පිවිසිය නොහැක .

බොහෝ සී පුස්තකාලවල සියලුම "පුද්ගලික" කාර්යයන් ස්ථිතික වන අතර බොහෝ "පොදු" ඒවා නොවේ.


19
X ගැන සඳහන් කිරීම සඳහා +1 තොගයක් හෝ ගොඩවල් මත නොවේ. එය ස්ථිතික මතක අවකාශයේ ය.
Gob00st

1
@ Gob00st ස්ථිතික මතක අවකාශය? ඔබ අදහස් කළේ "දත්ත කොටස" ...?
යූෂා අලෙයූබ්

26

සී හි 'ස්ථිතික' යන්නට අර්ථ දෙකක් ඇති බව ජනතාව දිගටම පවසති. මම එය නැරඹීමේ විකල්ප ක්‍රමයක් ඉදිරිපත් කරමි, එය තනි අර්ථයක් ලබා දෙයි:

  • අයිතමයකට 'ස්ථිතික' යෙදීමෙන් එම අයිතමයට ගුණාංග දෙකක් තිබිය යුතුය: (අ) එය වත්මන් විෂය පථයෙන් පිටත නොපෙනේ; (ආ) එය නොනැසී පවතී.

එය අර්ථ දෙකක් ඇති බව පෙනී හේතුව 'ස්ථිතික' යෙදිය හැකි සෑම අයිතමය, සී, එනම් මේ වන විටත් මෙම ගුණ දෙක එක් කර එය එසේ, පෙනේ එම සුවිශේෂී භාවිතය පමණක් අනෙක් ඇතුළත් නම්.

උදාහරණයක් ලෙස, විචල්යයන් සලකා බලන්න. ශ්‍රිතයෙන් පිටත ප්‍රකාශිත විචල්‍යයන් දැනටමත් (දත්ත කාණ්ඩයේ) ​​නොනැසී පවතී, එබැවින් 'ස්ථිතික' යෙදීමෙන් ඒවා වර්තමාන විෂය පථයෙන් (සම්පාදන ඒකකයෙන්) නොපෙනේ. ඊට හාත්පසින්ම වෙනස්ව, ශ්‍රිත ඇතුළත ප්‍රකාශිත විචල්‍යයන්ට දැනටමත් පවතින විෂය පථයට (ශ්‍රිතයට) පිටින් දෘශ්‍යතාවයක් නොමැති බැවින් 'ස්ථිතික' යෙදීමෙන් ඒවා නොනැසී පැවතිය හැකිය.

කාර්යයන් සඳහා 'ස්ථිතික' යෙදීම හරියට ගෝලීය විචල්‍යයන්ට අදාළ කිරීම හා සමානයි - කේතය අනිවාර්යයෙන්ම නොනැසී පවතී (අවම වශයෙන් භාෂාව තුළම), එබැවින් දෘශ්‍යතාව පමණක් වෙනස් කළ හැකිය.

සටහන: මෙම අදහස් සී සඳහා පමණක් අදාළ වේ. සී ++ හි, පන්ති ක්‍රමවලට 'ස්ථිතික' යෙදීම සැබවින්ම මූල පදයට වෙනත් අර්ථයක් ලබා දෙයි. ඒ හා සමානව C99 අරාව-තර්ක දිගුව සඳහා.


ඔබේ (අ) අතිරික්තය. එහි විෂය පථයෙන් පිටත කිසිදු විචල්‍යයක් නොපෙනේ. එය හුදෙක් විෂය පථයේ අර්ථ දැක්වීමයි. ඔබ අදහස් කරන දෙය සී ප්‍රමිතියේ සම්බන්ධතාවය ලෙස හැඳින්වේ . හඳුනාගැනුමකට අභ්‍යන්තර සම්බන්ධතාවයstatic ලබා දෙයි .
ජෙන්ස්

16

විකිපීඩියාවෙන්:

සී ක්‍රමලේඛන භාෂාවෙන්, ස්ථිතිකය ගෝලීය විචල්‍යයන් සහ කාර්යයන් සමඟ ඒවායේ විෂය පථය අඩංගු ගොනුවට සැකසීමට භාවිතා කරයි. දේශීය විචල්‍යයන්හි, ස්වයංක්‍රීයව වෙන් කරන ලද මතකය වෙනුවට සංඛ්‍යාත්මකව වෙන් කරන ලද මතකයේ විචල්‍යය ගබඩා කිරීමට ස්ථිතික භාවිතා වේ. එක් ආකාරයක මතකයක් ක්‍රියාත්මක කිරීම භාෂාව විසින් නියම නොකරන අතර, සංඛ්‍යාත්මකව වෙන් කරන ලද මතකය සාමාන්‍යයෙන් සංයුක්ත වේලාවේදී වැඩසටහනේ දත්ත කාණ්ඩයේ වෙන් කර ඇති අතර ස්වයංක්‍රීයව වෙන් කරන ලද මතකය සාමාන්‍යයෙන් ක්‍රියාත්මක වන්නේ අස්ථිර ඇමතුම් තොගයක් ලෙස ය.


16

static විවිධ සන්දර්භයන්හි විවිධ දේ අදහස් කරයි.

  1. සී ශ්‍රිතයක ස්ථිතික විචල්‍යයක් ඔබට ප්‍රකාශ කළ හැකිය. මෙම විචල්‍යය දෘශ්‍යමාන වන්නේ ශ්‍රිතය තුළ පමණි, කෙසේ වෙතත් එය ගෝලීය ලෙස හැසිරෙන්නේ එය එක් වරක් පමණක් ආරම්භ කර එහි වටිනාකම රඳවා තබා ගනිමිනි. මෙම උදාහරණයේ දී, ඔබ foo()එය අමතන සෑම අවස්ථාවකම වැඩි වන සංඛ්‍යාවක් මුද්‍රණය කරනු ඇත. ස්ථිතික විචල්‍යය ආරම්භ කරනු ලබන්නේ එක් වරක් පමණි.

    void foo ()
    {
    static int i = 0;
    printf("%d", i); i++
    }
  2. ස්ථිතිකයේ තවත් භාවිතයක් වන්නේ ඔබ .c ගොනුවක ශ්‍රිතයක් හෝ ගෝලීය විචල්‍යයක් ක්‍රියාත්මක කරන නමුත් එහි සංකේතය .objගොනුව මඟින් ජනනය කළ පිටතින් දෘශ්‍යමාන වීමට අවශ්‍ය නොවන විටය . උදා

    static void foo() { ... }

9

මම පැරණි ප්‍රශ්නයකට පිළිතුරු දීමට අකමැතියි, නමුත් කේ ඇන්ඩ් ආර් එය “සී ක්‍රමලේඛන භාෂාව” හි A4.1 කොටසේ පැහැදිලි කරන්නේ කෙසේදැයි කිසිවෙකු සඳහන් කර ඇතැයි මම නොසිතමි.

කෙටියෙන් කිවහොත්, ස්ථිතික යන වචනය අර්ථ දෙකක් සමඟ භාවිතා වේ :

  1. ස්ථිතික යනු ගබඩා පන්ති දෙකෙන් එකකි (අනෙක ස්වයංක්‍රීය වීම). ස්ථිතික වස්තුවක් එහි වටිනාකම ආයාචනා අතර තබා ගනී. සියලුම කොටස් වලින් පිටත ප්‍රකාශිත වස්තූන් සැමවිටම ස්ථිතික වන අතර ඒවා ස්වයංක්‍රීය කළ නොහැක.
  2. එහෙත්, විට static මූල පදය (අ ඉඟි පද ලෙස කේතය භාවිතා කරමින් එය මත විශාල අවධාරණය) ප්රකාශ සමග භාවිතා වන අතර, එය වස්තුවක් අභ්යන්තර සම්බන්ධතාවය නිසාම එය පරිවර්තනය ඒකකයක් තුළ පමණක් භාවිතා කළ හැකි නිසා ලබා දෙයි. නමුත් ශ්‍රිතයක් තුළ මූල පදය භාවිතා කරන්නේ නම්, එය වස්තුවෙහි ගබඩා පන්තිය වෙනස් කරයි (වස්තුව කෙසේ හෝ එම ශ්‍රිතය තුළ පමණක් දැකිය හැකිය). ස්ථිතිකයේ ප්‍රතිවිරුද්ධ දෙය නම් extern, එය වස්තුවකට බාහිර සම්බන්ධතාවයක් ලබා දෙයි.

පීටර් වැන් ඩර් ලින්ඩන් "විශේෂ C සී ක්‍රමලේඛනය" තුළ මෙම අර්ථ දෙක ලබා දෙයි:

  • ශ්‍රිතයක් තුළ, ඇමතුම් අතර එහි වටිනාකම රඳවා ගනී.
  • ක්‍රියාකාරී මට්ටමින්, මෙම ගොනුවේ පමණක් දැකිය හැකිය.

තුන්වන ගබඩා පන්තියක් ඇත, ලියාපදිංචි වන්න . සමහර අය සිව්වන ගබඩා පන්තිය සඳහා වෙන් කර ඇති අතර, malloc සහ මිතුරන් විසින් ආපසු ලබා දෙන ගබඩාව සඳහාද මෙය සිදු කරයි.
ජෙන්ස්

En ජෙන්ස් ලේඛනය සම්පාදකයාට ඉඟියක් පමණි; සී ප්‍රභවය තුළ සිට රෙජිස්ටර් ගබඩාව බලාත්මක කළ නොහැක. එබැවින් මම එය ගබඩා පන්තියක් ලෙස නොසිතමි.
ජර්මන් නර්ඩ්

1
එය පැහැදිලිව කරන පරිදි මම, ඔබේ දැක්ම සමග ISO සී සම්මත එකග නොවන බයයි @GermanNerd registerවූ ගබඩා-පන්ති විශේෂණයක් (C99 ප්රමිතියේ දී 6.7.1 ගබඞා-පංති නිශ්චයකක්). එය හුදෙක් ඉඟියකට වඩා වැඩි ය, නිදසුනක් ලෙස , සම්පාදකයා ලේඛනයක් වෙන් කරන්නේ ද නැද්ද යන්න නොසලකා, &ගබඩා පන්තියක් ඇති වස්තුවක් මත ක්‍රියාකරුගේ ලිපිනය යෙදිය registerනොහැක.
ජෙන්ස්

En ජෙන්ස් මට & ගැන මතක් කිරීම ගැන ස්තූතියි. මම ඕනෑවට වඩා සී ++ කර ඇත ..... කෙසේ වෙතත්, 'රෙජිස්ටර්' යනු ගබඩා පන්තියේ පිරිවිතරයක් වන අතර, යථාර්ථයේ දී සම්පාදකයා විසින් 'ලේඛනය' සඳහා (නිෂ් less ල) 'ස්වයංක්‍රීය' පිරිවිතර සඳහා එකම යන්ත්‍ර කේතයක් නිර්මාණය කරනු ඇත. පිරිවිතර. එබැවින් ඉතිරිව ඇති එකම දෙය ලිපිනය ලබා ගැනීමට නොහැකි වීමේ ප්‍රභව කේත මට්ටම සීමා කිරීමයි. බීටීඩබ්ලිව්, මෙම කුඩා සාකච්ඡාව නිසා නෙට්බීන්ස් හි දෝෂයක් සොයා ගැනීමට මට හැකි විය; මගේ නවතම යාවත්කාලීනයේ සිට, එය නව සී ව්‍යාපෘතිවල g ++ මෙවලම් දාමයට පෙරනිමි වේ!
ජර්මන් නර්ඩ්

8

ඔබ ශ්‍රිත ස්ථිතිකයක විචල්‍යයක් ප්‍රකාශ කරන්නේ නම්, එහි අගය ශ්‍රිත ඇමතුම් තොගයේ ගබඩා නොවන අතර ඔබ නැවත ශ්‍රිතය ඇමතූ විට එය තවමත් පවතී.

ඔබ ගෝලීය විචල්‍ය ස්ථිතිකයක් ප්‍රකාශ කරන්නේ නම්, එහි විෂය පථය ඔබ ප්‍රකාශ කළ ගොනුව තුළට පමණක් සීමා වේ. මෙය ඔබේ මුළු වැඩසටහන පුරාම කියවිය හැකි හා වෙනස් කළ හැකි සාමාන්‍ය ගෝලීයයකට වඩා තරමක් ආරක්ෂිතයි.


6

C හි, ස්ථිතිකයට එහි භාවිතයේ විෂය පථය අනුව අර්ථ දෙකක් ඇත. ගෝලීය විෂය පථය තුළ, වස්තුවක් ගොනු මට්ටමින් ප්‍රකාශයට පත් කළ විට, එයින් අදහස් වන්නේ එම වස්තුව දෘශ්‍ය වන්නේ එම ගොනුව තුළ පමණක් බවයි.

වෙනත් ඕනෑම විෂය පථයක දී එය නිශ්චිත විෂය පථයට ඇතුළු වූ විවිධ කාලයන් අතර එහි වටිනාකම රඳවා ගන්නා වස්තුවක් ප්‍රකාශ කරයි. නිදසුනක් ලෙස, ක්‍රියා පටිපාටියක් තුළ int එකක් තෝරාගෙන තිබේ නම්:

void procedure(void)
{
   static int i = 0;

   i++;
}

ක්‍රියාපටිපාටියට පළමු ඇමතුම මත 'i' හි අගය ශුන්‍යයට ආරම්භ වන අතර, ක්‍රියා පටිපාටිය කැඳවනු ලබන සෑම අවස්ථාවකම අගය රඳවා ගනු ලැබේ. 'i' මුද්‍රණය කළහොත් එය 0, 1, 2, 3, ...


5

ශ්‍රිතවල ස්ථිතික විචල්‍යයන් එම ශ්‍රිතයට පළමු පිවිසුමේදී ආරම්භ වන අතර ඒවායේ ඇමතුම අවසන් වූ පසුවත් දිගටම පවතින බව සැලකිල්ලට ගැනීම වැදගත්ය; පුනරාවර්තන ශ්‍රිතයකදී ස්ථිතික විචල්‍යය ආරම්භ වන්නේ එක් වරක් පමණක් වන අතර සියලු පුනරාවර්තන ඇමතුම් වලට වඩා දිගටම පවතී.

විචල්‍යය ශ්‍රිතයකින් පිටත නිර්මාණය කර ඇත්නම්, එයින් අදහස් කරන්නේ ක්‍රමලේඛකයාට විචල්‍යය ප්‍රභව ගොනුවේ පමණක් භාවිතා කළ හැකි බවයි.


5

ඔබ මෙය mytest.cගොනුවකින් ප්‍රකාශ කරන්නේ නම් :

static int my_variable;

එවිට මෙම විචල්‍යය දැකිය හැක්කේ මෙම ගොනුවෙන් පමණි. විචල්‍යය වෙනත් තැනකට අපනයනය කළ නොහැක.

ඔබ ශ්‍රිතයක් තුළ ප්‍රකාශ කළහොත් විචල්‍යයේ අගය ශ්‍රිතය හැඳින්වෙන සෑම අවස්ථාවකම එහි අගය රඳවා තබා ගනී.

ස්ථිතික ශ්‍රිතයක් ගොනුවෙන් පිටත සිට අපනයනය කළ නොහැක. එබැවින් *.cගොනුවක, ඔබ ශ්‍රිත සහ විචල්‍යයන් ස්ථිතික යැයි ප්‍රකාශ කරන්නේ නම් එය සඟවයි.


4

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 ද විනාශ වේ.

ආරම්භක ස්ථිතික විචල්‍යයන් සී වැඩසටහනේ දත්ත කාණ්ඩයේ ගබඩා කර ඇති අතර ආරම්භ නොකළ ඒවා බීඑස්එස් කාණ්ඩයේ ගබඩා කර ඇත.

ස්ථිතික පිළිබඳ තවත් තොරතුරු: විචල්‍යයක් ගෝලීය හා ස්ථිතික නම්, එයට සී වැඩසටහනේ ආයු කාලය ඇත, නමුත් එයට ගොනු විෂය පථය ඇත. එය දෘශ්‍ය වන්නේ එම ගොනුවේ පමණි.

මෙය උත්සාහ කිරීමට:

file1.c

static int x;

int main()
{
    printf("Accessing in same file%d", x):
}

file2.c

    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 වෙත යොමු කිරීම සම්බන්ධ කිරීමට සම්බන්ධකයට නොහැකි වනු ඇත.

යොමුව:

  1. http://en.wikipedia.org/wiki/Translation_unit_(programming)
  2. http://en.wikipedia.org/wiki/Call_stack

දත්ත නොනැසී පවතින බව මට වැටහී ඇත, එයින් අදහස් වන්නේ එක් එක් ක්‍රියාකාරී ඇමතුමෙන් පසුව එය නැති නොවන බවයි, නමුත් static int var = 1;එක් වරක් නැවත වරක් අගය වෙනස් නොකරන්නේ ඇයි
Eames

3

ස්ථිතික විචල්‍යය යනු ඔබට ශ්‍රිතයක් තුළ භාවිතා කළ හැකි විශේෂ විචල්‍යයක් වන අතර එය ඇමතුම් අතර දත්ත සුරකිනු ඇති අතර එය ඇමතුම් අතර එය මකා නොදමයි. උදාහරණයක් වශයෙන්:

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).
රස්තා ජේඩි

2

ස්ථිතික විචල්‍ය අගයක් විවිධ ක්‍රියාකාරී ඇමතුම් අතර පවතින අතර විෂය පථය දේශීය වාරණයට සීමා වේ. ස්ථිතික var සෑම විටම අගය 0 සමඟ ආරම්භ වේ


2

නඩු 2 ක් ඇත:

(1) ප්‍රකාශිත දේශීය විචල්‍යයන් static: තොග වෙනුවට දත්ත කාණ්ඩයට වෙන් කර ඇත. ඔබ නැවත ශ්‍රිතය අමතන විට එහි වටිනාකම රඳවා ගනී.

(2) ගෝලීය විචල්‍යයන් හෝ ප්‍රකාශිත කාර්යයන් static: නොපෙනෙන පිටත සම්පාදන ඒකකය (එනම් සම්බන්ධ කිරීමේදී සංකේත වගුවේ ඇති දේශීය සංකේත වේ).


1

ස්ථිතික විචල්‍යයන්ට ඒවායේ විෂය පථයෙන් බැහැර වූ පසුවත් ඒවායේ වටිනාකම ආරක්ෂා කිරීමේ දේපලක් ඇත ! එබැවින් ස්ථිතික විචල්‍යයන් ඒවායේ පෙර පරාසය ඔවුන්ගේ පෙර විෂය පථය තුළ ආරක්ෂා කර ගන්නා අතර නව විෂය පථය තුළ නැවත ආරම්භ නොකෙරේ.

උදාහරණයක් ලෙස මෙය දෙස බලන්න - වැඩසටහන ක්‍රියාත්මක වන විට ස්ථිතික 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]

නවකයකු සඳහා ඉහත විස්තර කර නොමැති මා සොයාගත් ප්‍රධාන ඒවා මේවායි!


-2

සී ක්‍රමලේඛනයේදී, 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එය ක්‍රියාත්මක කරන විට එය ගණන් විචල්‍යය විනාශ කරයි.


2
> ඉහත වැඩසටහන මඟින් අපට මෙම ප්‍රතිදානය ලබා දෙනු ඇත: පළමු කවුන්ටරයේ ප්‍රතිදානය = 1 දෙවන කවුන්ටරයේ ප්‍රතිදානය = 1 <සත්‍ය නොවේ. ස්ථිතික විචල්‍යයන් ආරම්භ වන්නේ එක් වරක් පමණි. එබැවින් ප්‍රතිදානය 1, පසුව 2, සහ එසේ වනු ඇත.
ජර්මන් නර්ඩ්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.