Const int *, const int * const, සහ int const * අතර වෙනස කුමක්ද?


1378

මම හැම විටම භාවිතා කරන ආකාරය දක්වා අවුල් const int*, const int * constහා int const *නිවැරදිව. ඔබට කළ හැකි හා කළ නොහැකි දේ නිර්වචනය කරන නීති මාලාවක් තිබේද?

පැවරුම්, කාර්යයන් වෙත යොමු වීම යනාදී සියලු කළ යුතු හා නොකළ යුතු දේ දැන ගැනීමට මට අවශ්‍යය.


176
බොහෝ C සහ C ++ ප්‍රකාශන තේරුම් ගැනීමට ඔබට "ඔරලෝසුව / සර්පිලාකාර රීතිය" භාවිතා කළ හැකිය .
ජේම්ස් මැක්නෙලිස්

53
cdecl.org යනු ඔබ වෙනුවෙන් සී ප්‍රකාශන ස්වයංක්‍රීයව පරිවර්තනය කරන විශිෂ්ට වෙබ් අඩවියකි.
ඩේව්

6
Al කැල්මරියස්: වර්ගය-නම / තිබිය යුතු තැන ආරම්භ කරන්න, ඔබට හැකි විට දකුණට, ඔබට අවශ්‍ය විට වමට යන්න . int *(*)(char const * const). වරහන් කළ දකුණට ආරම්භ කරන්න, *එවිට අපට වමට යා යුතුය : pointer. පාරෙන් පිටත අපට දකුණට ගමන් කළ හැකිය : pointer to function of .... එවිට අපට වමට යා යුතුය : pointer to function of ... that returns pointer to int. (The ...) පරාමිතිය පුළුල් කිරීම සඳහා නැවත නැවත කරන්න : pointer to function of (constant pointer to constant char) that returns pointer to int. පැස්කල් වැනි පහසුවෙන් කියවිය හැකි භාෂාවකින් සමාන එක පේළියේ ප්‍රකාශය කුමක් විය හැකිද?
මාර්ක් කේ කෝවන්

1
Ark මාක්කෝවන් පැස්කල්හි එය එවැනි දෙයක් වනු ඇත function(x:^char):^int. එහි ක්‍රියාකාරී වර්ග යනු ශ්‍රිතයක් සඳහා දර්ශකයක් වන බැවින් එය නියම කිරීමට අවශ්‍ය නොවන අතර පැස්කල් විසින් නිරවද්‍යතාව බලාත්මක නොකරයි. එය වමේ සිට දකුණට කියවිය හැකිය.
කැල්මේරියස්

5
"කොන්ස්ට්" හි වම්පස ඇති පළමු දෙය නියතයි. “කොන්ස්” යනු වමට f ත ම දෙය නම්, එහි දකුණට ඇති පළමු දෙය නියත ය.
කප්කේක්

Answers:


2242

එය පසුපසට කියවන්න ( ඔරලෝසුව / සර්පිලාකාර රීතිය අනුව ):

  • int* - int වෙත දර්ශකය
  • int const * - int int වෙත යොමු කිරීම
  • int * const - int වෙත const pointer
  • int const * const - const int වෙත const pointer

දැන් පළමුවැන්න constවර්ගයේ දෙපස විය හැකිය:

  • const int * == int const *
  • const int * const == int const * const

ඔබට පිස්සු වැටීමට අවශ්‍ය නම් ඔබට මෙවැනි දේ කළ හැකිය:

  • int ** - දර්ශකය සිට දර්ශකය දක්වා int
  • int ** const - int වෙත දර්ශකයකට නියත දර්ශකය
  • int * const * - int වෙත නියත දර්ශකයකට දර්ශකයක්
  • int const ** - නියත දර්ශකයකට දර්ශකය
  • int * const * const - නියත දර්ශකයකට නියත දර්ශකය වෙතට
  • ...

මෙහි අර්ථය පිළිබඳව අප පැහැදිලි බව තහවුරු කර ගැනීම සඳහා const:

int a = 5, b = 10, c = 15;

const int* foo;     // pointer to constant int.
foo = &a;           // assignment to where foo points to.

/* dummy statement*/
*foo = 6;           // the value of a can´t get changed through the pointer.

foo = &b;           // the pointer foo can be changed.



int *const bar = &c;  // constant pointer to int 
                      // note, you actually need to set the pointer 
                      // here because you can't change it later ;)

*bar = 16;            // the value of c can be changed through the pointer.    

/* dummy statement*/
bar = &a;             // not possible because bar is a constant pointer.           

fooයනු නියත නිඛිලයකට විචල්‍ය දර්ශකයකි. මෙය ඔබ යොමු කරන දෙය වෙනස් කිරීමට ඉඩ දෙන නමුත් ඔබ පෙන්වා දෙන අගය නොවේ. බොහෝ විට මෙය සී-ස්ටයිල් නූල් වලින් දැකිය හැකි අතර එහිදී ඔබට a වෙත දර්ශකයක් ඇත const char. ඔබ යොමු කරන නූල ඔබට වෙනස් කළ හැකි නමුත් ඔබට මෙම නූල් වල අන්තර්ගතය වෙනස් කළ නොහැක. වැඩසටහනක දත්ත කාණ්ඩය තුළම නූල් ඇති විට මෙය වැදගත් වන අතර එය වෙනස් නොකළ යුතුය.

barයනු වෙනස් කළ හැකි අගයකට නියත හෝ ස්ථාවර දර්ශකයකි. මෙය අතිරේක සින්ටැක්ටික් සීනි නොමැතිව යොමු කිරීමක් වැනිය. මෙම කාරණය නිසා, සාමාන්‍යයෙන් ඔබ T* constදර්ශකයක් භාවිතා කිරීමට භාවිතා කරන්නේ ඔබ NULLදර්ශකයන්ට ඉඩ දිය යුතු නම් මිස .


488
දර්ශකය හෝ යොමු දත්ත වලට 'const' අදාළ වේද යන්න සොයා ගැනීමට ඔබට මතක තබා ගත හැකි නියමාකාර රීතියක් එකතු කිරීමට මම කැමතියි: ප්‍රකාශය තරු ලකුණට බෙදන්න, එවිට, වම් කොටසේ const keyword දිස්වන්නේ නම් (වැනි) 'const int * foo') - එය නියම කොටසට අයත් වේ, එය නිවැරදි කොටසේ නම් ('int * const bar') - එය දර්ශකය ගැන ය.
මයිකල්

14
Ic මයිකල්: නියමය මතක තබා ගැනීම / අවබෝධ කර ගැනීම සඳහා එතරම් සරල රීතියක් සඳහා මයිකල්ට කුඩෝස්.
සිවබුද්

10
E ජෙෆ්රි: වරහන් නොමැති තාක් කල් එය කියවන්න. එහෙනම්, හොඳයි ... typedefs භාවිතා කරන්න
Mooing Duck

12
+1, වඩා හොඳ සාරාංශයක් වනු ඇත: දර්ශක ප්‍රකාශ පිටුපසට කියවන්න , එයින් අදහස් වන්නේ, මයිකල්ගේ ප්‍රකාශයට ආසන්නව: පළමු තරු ලකුණෙන් සාමාන්‍ය වමේ සිට දකුණට කියවීම නවත්වන්න .
වුල්ෆ්

3
@gedamial එය කරයි, එය හොඳින් ක්‍රියාත්මක වේ, නමුත් ඔබ එය ප්‍රකාශයට පත් කරන අවස්ථාවේදීම එය පැවරිය යුතුය (ඔබට “const pointer” යලි පැවරිය නොහැකි නිසා). const int x = 0; const int *const px = &x; const int *const *const p = &px;හොඳින් ක්‍රියා කරයි.
රස්තා ජේඩි

366

ඔරලෝසුව / සර්පිලාකාර රීතිය ගැන නොදන්නා අය සඳහා: විචල්‍යයේ නමෙන් ආරම්භ කරන්න, දක්ෂිණාවර්තව චලනය කරන්න (මේ අවස්ථාවේ දී පසුපසට යන්න) ඊළඟ දර්ශකය හෝ වර්ගය වෙත යන්න . ප්‍රකාශනය අවසන් වන තුරු නැවත නැවත කරන්න.

මෙන්න නිරූපණයක්:

int වෙත දර්ශකය

const pontter to int const

int const වෙත දර්ශකය

const int වෙත යොමු කිරීම

const සිට int දක්වා


8
Example සංකීර්ණ උදාහරණය සඳහා ජෑන් සබැඳියට අවසර නොමැත. ඔබට එය කෙලින්ම මෙහි පළ කළ හැකිද, නැතහොත් බැලීමේ සීමාවන් ඉවත් කළ හැකිද?
R71

8
Open එය විවෘත ප්‍රවේශ අවසරයන් සියල්ලම භාවිතා කර ඇත ... අවාසනාවකට මෙන්, මම ලිපිය ලිවූයේ නැත. කෙසේ වෙතත්, ලිපියේ සංරක්ෂිත අනුවාදයක් තවමත් ක්‍රියාත්මක වේ: archive.is/SsfMX
Jan Rüegg

8
සංකීර්ණ උදාහරණය තවමත් දකුණේ සිට වමට ය, නමුත් සාමාන්‍යයෙන් වරහන් වර්‍ග නිරාකරණය කිරීම ඇතුළත් වේ. මුළු ඔරලෝසුවේ සර්පිලාකාර දෙය එය පහසු නොකරයි.
මැතිව්

4
අවසාන උදාහරණය: void (*signal(int, void (*fp)(int)))(int);archive.is/SsfMX වෙතින්
naXa

3
මෙම රීතිය මත රඳා නොසිටින්න. මෙය විශ්වීය නොවේ. එය අසමත් වන අවස්ථා තිබේ.
හක්ස්

149

මම හිතන්නේ සෑම දෙයකටම දැනටමත් මෙහි පිළිතුරු ලැබී ඇති නමුත් මට අවශ්‍ය වන්නේ ඔබ පරිස්සම් විය යුතු බවයි typedef! ඒවා පෙළ ආදේශන පමණක් නොවේ.

උදාහරණයක් වශයෙන්:

typedef char *ASTRING;
const ASTRING astring;

වර්ගය astringවේ char * const, නො const char *. මෙය මම සෑම විටම constවර්ගයේ දකුණට නැඹුරු වීමට එක් හේතුවක් වන අතර කිසි විටෙකත් ආරම්භයේ දී නොවේ.


20
මට නම් මෙය කිසි විටෙකත් දර්ශක ටයිප් නොකිරීමට හේතුවයි. මම වගේ දේවල් යහපත බලන්න එපා typedef int* PINT(මම සී පිළිවෙත් හා තවත් බොහෝ සංවර්ධකයින් සිට පැමිණි බව එහි යමක් කරන්නේ තබා උපකල්පනය). , මහත් වූ, මම වෙනුවට *සමඟ P, එය ටයිප් වේගවත් නැත, ප්ලස් ඔබ සඳහන් ප්රශ්නය හඳුන්වා.
මෙෆේන්

1
Ep මෙෆේන් - මට ඒක පේනවා. කෙසේවෙතත්, සුවිශේෂී සින්ටැක්ටික් රීතිය භාවිතා කිරීමෙන් වැළකී සිටිනවාට වඩා සුවිශේෂී සින්ටැක්ටිකල් රීතියක් (“කොන්ස්” ස්ථානගත කිරීම ගැන) නොකඩවා භාවිතා කිරීම සඳහා හොඳ භාෂා අංගයක් මග හැරීම මට පසුගාමී බවක් පෙනේ, එවිට ඔබට මෙම භාෂා අංගය ආරක්ෂිතව භාවිතා කළ හැකිය. .
TED

6
Ep මෙෆේන් PINTයනු යතුරු ලියනයක තරමක් ගොළු භාවිතයකි, විශේෂයෙන් cuz එය පද්ධති ගබඩාව මතකය සඳහා බියර් භාවිතා කරයි යැයි මට සිතේ. යතුරු ලියනය කරන ලද කාර්යයන් සමඟ සම්බන්ධ වීමට ඉතා ප්‍රයෝජනවත් වේ.
ඩාර්ක්නස්ෆිෂ් වෙත ළඟා වෙමින්

5
Az කැස්ඩ්‍රැගන් ස්තූතියි! එය නොමැතිව, මම වින් 32 ඒපී PVOIDහි යතුරු ලියනය කළ , සියල්ල අවුල් කරනු ඇත LPTSTR!
ඩේවිඩ් ලී

2
Ep මෙෆේන්: වර්ගයක් පිළිගැනීම සඳහා ලියා ඇති සමහර පැරණි මැක්‍රෝ භාවිතා කරන විට මට කිහිප වතාවක් pSomething භාවිතා කිරීමට සිදුවිය, නමුත් එම වර්ගය තනි අක්ෂරාංක හඳුනාගැනීමක් නොවන්නේ නම් එය බිඳී යනු ඇත. :)
Groo

56

හැමෝම පෙන්වා දුන් පරිදි:

අතර වෙනස කුමක් ද const X* p, X* const pසහ const X* const p?

ඔබ දකුණේ සිට වමට දර්ශක ප්‍රකාශ කියවිය යුතුය.

  • const X* p "p යනු නියත X ට යොමු කරයි": X වස්තුව p හරහා වෙනස් කළ නොහැක.

  • X* const p "p යනු නියත නොවන X ට නියත දර්ශකයක්": ඔබට p දර්ශකය p වෙනස් කළ නොහැක, නමුත් ඔබට p හරහා X වස්තුව වෙනස් කළ හැකිය.

  • const X* const p "p යනු නියත X ට නියත ලක්ෂ්‍යයකි": ඔබට දර්ශකය p ම වෙනස් කළ නොහැක, p හරහා X වස්තුව වෙනස් කළ නොහැක.


3
එය අමතක නොකරන්න const X* p;== X const * p;මෙන්"p points to an X that is const": the X object can't be changed via p.
ජෙසී චිෂොල්ම්

සරල හා ලස්සන පැහැදිලි කිරීමක්!
එඩිසන් ලො

50
  1. නිරන්තර යොමුව:

    විචල්යයක් සඳහා යොමු කිරීමක් (මෙහි int) නියත වේ. අපි විචල්‍යය ප්‍රධාන වශයෙන් යොමු කිරීමක් ලෙස යොමු කරන්නෙමු, මන්ද යොමු කිරීම් සත්‍ය වටිනාකමට වඩා කුඩා වන නමුත් අතුරු ආබාධයක් ඇති අතර එයට හේතුව එය සත්‍ය විචල්‍යයට අන්වර්ථයකි. අන්වර්ථයට අපගේ පූර්ණ ප්‍රවේශය හරහා අපි ප්‍රධාන විචල්‍යය අහම්බෙන් වෙනස් කළ හැකිය, එබැවින් මෙම අතුරු ආබාධ වැළැක්වීම සඳහා අපි එය නිරන්තරයෙන් කරමු.

    int var0 = 0;
    const int &ptr1 = var0;
    ptr1 = 8; // Error
    var0 = 6; // OK
  2. නිරන්තර දර්ශක

    නියත දර්ශකයක් විචල්‍යයකට යොමු වූ පසු එයට වෙනත් විචල්‍යයකට යොමු කළ නොහැක.

    int var1 = 1;
    int var2 = 0;
    
    int *const ptr2 = &var1;
    ptr2 = &var2; // Error
  3. නියතයට දර්ශකය

    කෙනෙකුට පෙන්වා දෙන විචල්‍යයක අගය වෙනස් කළ නොහැකි දර්ශකයක් නියතයට දර්ශකයක් ලෙස හැඳින්වේ.

    int const * ptr3 = &var2;
    *ptr3 = 4; // Error
  4. නියතයකට නියත දර්ශකය

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

    int var3 = 0;
    int var4 = 0;
    const int * const ptr4 = &var3;
    *ptr4 = 1;     // Error
     ptr4 = &var4; // Error

20

සාමාන්‍ය රීතිය නම්, constමූලික පදයට පෙර ඇති දෙයට එය අදාළ වේ. ව්‍යතිරේකය, ආරම්භයක් constපහත සඳහන් දේට අදාළ වේ.

  • const int*සමාන වන int const*අතර එහි අර්ථය “නියත int වෙත දර්ශකය” යන්නයි .
  • const int* constසමාන වන int const* constඅතර එහි අර්ථය “නියත int වෙත නියත දර්ශකය” යන්නයි .

සංස්කරණය කරන්න: නොකළ යුතු දේ සහ නොකළ යුතු දේ සඳහා, මෙම පිළිතුර ප්‍රමාණවත් නොවේ නම්, ඔබට අවශ්‍ය දේ පිළිබඳව වඩාත් නිවැරදි විය හැකිද?


19

මෙම ප්‍රශ්නය හරියටම පෙන්වන්නේ මා පිළිගත හැකි ආකාරයේ හැඳුනුම්පතකට පසුව මගේ ප්‍රශ්නයේ සඳහන් ආකාරයටම දේවල් කිරීමට මා කැමති ඇයි ?

කෙටියෙන් කිවහොත්, මම පාලනය මතක තබා ගැනීමට ඇති පහසුම ක්රමය "const" යයි බව ය සොයා පසු , එය අදාළ වන දෙයක්. එබැවින් ඔබේ ප්‍රශ්නයේදී, "int const *" යන්නෙන් අදහස් වන්නේ int නියත වන අතර "int * const" යන්නෙන් අදහස් කරන්නේ දර්ශකය නියත බවයි.

යමෙකු එය ඉදිරියෙන් තැබීමට තීරණය කරන්නේ නම් (උදා: "const int *"), විශේෂ ව්‍යතිරේකයක් ලෙස එය ඊට පසුව ඇති දෙයට අදාළ වේ.

බොහෝ අය එම විශේෂ ව්‍යතිරේකය භාවිතා කිරීමට කැමති වන්නේ එය වඩා හොඳ යැයි සිතන බැවිනි. මම එයට අකමැතියි, මන්ද එය ව්‍යතිරේකයක් වන අතර එමඟින් දේවල් ව්‍යාකූල වේ.


2
මම මේ ප්‍රශ්නය ඉරා දැමුවෙමි. තර්කානුකූලව එය අර්ථවත් කරයි. කෙසේ වෙතත් බොහෝ c ++ සංවර්ධකයින් ලියන const T*අතර එය වඩාත් ස්වාභාවික වී ඇත. ඔබ කවදා හෝ කොපමණ T* constවාරයක් භාවිතා කරනවාද , සාමාන්‍යයෙන් යොමු කිරීමක් හොඳ වනු ඇත. මට අවශ්‍ය වූ විට මේ සියල්ලෙන් මදක් මා boost::shared_ptr<const T>ලිවී ඒ වෙනුවට ලිවීය const boost::shared_ptr<T>. තරමක් වෙනස් සන්දර්භයක එකම ප්‍රශ්නය.
මැට් මිල

ඇත්ත වශයෙන්ම, මම නියතයන් භාවිතා කරනවාට වඩා නිරන්තර දර්ශක භාවිතා කරමි. එසේම, ඔබ දර්ශකයන් ඉදිරියේ දර්ශකයන් ඉදිරියේ ප්‍රතික්‍රියා කරන්නේ කෙසේද යන්න ගැන සිතා බැලිය යුතුය (යනාදිය) ඒවා දුර්ලභ බව පිළිගත යුතුය, නමුත් ඔබට මෙම තත්වයන් ඇප්ලොම් සමඟ හැසිරවිය හැකි ආකාරයෙන් සිතීම සතුටක් වනු ඇත.
ටෙඩ්

1
කොන්ස්ට් වර්ගයේ දකුණු පස තැබීමේ තවත් හොඳ වාසියක් නම්, දැන් ඕනෑම constදෙයක වම්පස ඇති සෑම දෙයක්ම කොන්ස් වර්ගය වන අතර, එහි දකුණට ඇති සියල්ල සැබවින්ම නියත ය. ගත int const * const * p;උදාහරණයක් ලෙස. නෑ මම සාමාන්‍යයෙන් එහෙම ලියන්නේ නැහැ, මේක උදාහරණයක් විතරයි. පළමුවැන්න const: int ටයිප් කරන්න, සහ const යනු int යනු const pointer හි අන්තර්ගතය වේ p. දෙවන නියතය: වර්ගය constint සිට pointer , const oblect යනු අන්තර්ගතයp
dgnuff

18

සරල භාවිතය const.

සරලම භාවිතය නම් කරන ලද නියතයක් ප්‍රකාශ කිරීමයි. මෙය සිදු කිරීම සඳහා යමෙක් නියතයක් විචල්‍යයක් ලෙස ප්‍රකාශ කරන නමුත් ඊට constපෙර එකතු කරන්න . යමෙකුට එය වහාම ඉදිකිරීම්කරු තුළ ආරම්භ කළ යුතුව ඇත, ඇත්ත වශයෙන්ම යමෙකුට එය පසුව වෙනස් කළ හැකි බැවින් පසුව අගය සැකසිය නොහැක. උදාහරණයක් වශයෙන්:

const int Constant1=96; 

Constant196 අගය සමඟ පරිකල්පනීය ලෙස හැඳින්වෙන පූර්ණ සංඛ්‍යාවක් නියතයක් නිර්මාණය කරයි .

වැඩසටහනේ භාවිතා වන පරාමිතීන් සඳහා එවැනි නියතයන් ප්‍රයෝජනවත් වන නමුත් වැඩසටහන සම්පාදනය කිරීමෙන් පසුව වෙනස් කිරීම අවශ්‍ය නොවේ. C preprocessor #defineවිධානය හරහා ක්‍රමලේඛකයන්ට එය වාසියක් ඇති අතර එය සම්පාදකයා විසින්ම තේරුම් ගෙන භාවිතා කරනු ලැබේ, ප්‍රධාන සම්පාදකයා වෙත ළඟා වීමට පෙර එය පෙර සැකසුම්කරු විසින් වැඩසටහන් පෙළට ආදේශ නොකරනු ඇත, එබැවින් දෝෂ පණිවිඩ වඩාත් ප්‍රයෝජනවත් වේ.

එය ද දර්ශකයන් සමඟ ක්‍රියා කරයි, නමුත් constදර්ශකය හෝ එය පෙන්වා දෙන දෙය නියත ද යන්න ද යන්න තීරණය කිරීමට යමෙකු ප්‍රවේශම් විය යුතුය . උදාහරණයක් වශයෙන්:

const int * Constant2 

Constant2එය නියත නිඛිලයකට විචල්‍ය දර්ශකයක් බව ප්‍රකාශ කරයි :

int const * Constant2

විකල්ප සින්ටැක්ස් එකක් වන අතර එය එසේ කරයි

int * const Constant3

Constant3එය විචල්‍ය පූර්ණ සංඛ්‍යාවක් සඳහා නියත දර්ශකයක් බව ප්‍රකාශ කරයි

int const * const Constant4

Constant4එය නියත නිඛිලයකට නියත දර්ශකයක් බව ප්‍රකාශ කරයි . මූලික වශයෙන් 'const' එහි ආසන්න වම්පස ඇති ඕනෑම දෙයකට අදාළ වේ (එහි කිසිවක් එහි නොමැති නම් එය එහි ආසන්න දකුණට අදාළ වේ).

ref: http://duramecho.com/ComputerInformation/WhyHowCppConst.html


9

සී ++ ගුරු ස්කොට් මේයර්ස් විසින් මෙම පොත මට හමු වන තෙක් මට ඔබ හා සමාන සැකයක් තිබුණි . ඔහු භාවිතා කිරීම පිළිබඳ විස්තර සහිතව කතා කරන මෙම පොතේ තුන්වන අයිතමය බලන්න const.

මෙම උපදෙස් පිළිපදින්න

  1. වචනය constතරු ලකුණෙහි වම්පස දිස්වන්නේ නම් , පෙන්වා ඇති දෙය නියත ය
  2. වචනය constතරු ලකුණට දකුණට දිස්වන්නේ නම් , දර්ශකය නියත වේ
  3. constදෙපසම පෙනේ නම් , දෙකම නියත ය

8

එය සරල නමුත් උපක්‍රමශීලී ය. අපි හුවමාරු කළ හැකි බව කරුණාකර මතක තබා constඕනෑම දත්ත වර්ගය සමඟ සුදුසුකම් ( int, char, float, ආදිය).

පහත උදාහරණ බලමු.


const int *p==> *pකියවීමට පමණි [ pනියත නිඛිලයකට දර්ශකයකි]

int const *p==> *pකියවීමට පමණි [ pනියත නිඛිලයකට දර්ශකයකි]


int *p const==> වැරදි ප්‍රකාශය. සම්පාදකයා සින්ටැක්ස් දෝෂයක් විසි කරයි.

int *const p==> pකියවීමට පමණි [p පූර්ණ සංඛ්‍යාවක් සඳහා නියත දර්ශකයකි]. මෙහි දර්ශකය pකියවීමට පමණක් බැවින් ප්‍රකාශය සහ අර්ථ දැක්වීම එකම ස්ථානයක තිබිය යුතුය.


const int *p const ==> වැරදි ප්‍රකාශය. සම්පාදකයා සින්ටැක්ස් දෝෂයක් විසි කරයි.

const int const *p ==> *pකියවීමට පමණි

const int *const p1 ==> *pසහ pකියවීමට පමණි [ pනියත නිඛිලයකට නියත දර්ශකයකි]. දර්ශකය ලෙසpකියවීමට පමණක් බැවින් ප්‍රකාශය සහ අර්ථ දැක්වීම එකම ස්ථානයක තිබිය යුතුය.


int const *p const ==> වැරදි ප්‍රකාශය. සම්පාදකයා සින්ටැක්ස් දෝෂයක් විසි කරයි.

int const int *p ==> වැරදි ප්‍රකාශය. සම්පාදකයා සින්ටැක්ස් දෝෂයක් විසි කරයි.

int const const *p ==> *pකියවීමට පමණක් වන අතර එය සමාන වේint const *p

int const *const p ==> *pසහ pකියවීමට පමණි [ pනියත නිඛිලයකට නියත දර්ශකයකි]. මෙහි දර්ශකය pකියවීමට පමණක් බැවින් ප්‍රකාශය සහ අර්ථ දැක්වීම එකම ස්ථානයක තිබිය යුතුය.


6

C ++ හි නිරවද්‍යතාව වටා තවත් සියුම් කරුණු තිබේ. මෙහි ඇති ප්‍රශ්නය සී ගැන පමණක් යැයි මම සිතමි, නමුත් ටැගය C ++ බැවින් මම ඊට අදාළ උදාහරණ කිහිපයක් දෙන්නෙමි:

  • ඔබ බොහෝ විට නූල් වැනි විශාල තර්ක ඉදිරිපත් කරන TYPE const &අතර එමඟින් වස්තුව වෙනස් කිරීම හෝ පිටපත් කිරීම වළක්වයි. උදාහරණයක් :

    TYPE& TYPE::operator=(const TYPE &rhs) { ... return *this; }

    නමුත් TYPE & constඅර්ථ විරහිත වන්නේ යොමු කිරීම් සැමවිටම සංයුක්ත වන බැවිනි.

  • පංතිය වෙනස් නොකරන පංති ක්‍රම ඔබ සැමවිටම ලේබල් කළ යුතුය const, එසේ නොමැතිනම් ඔබට එම ක්‍රමය TYPE const &යොමු කිරීමකින් ඇමතිය නොහැක . උදාහරණයක් :

    bool TYPE::operator==(const TYPE &rhs) const { ... }

  • ප්‍රතිලාභ අගය සහ ක්‍රමය යන දෙකම නියත විය යුතු පොදු අවස්ථා තිබේ. උදාහරණයක් :

    const TYPE TYPE::operator+(const TYPE &rhs) const { ... }

    ඇත්ත වශයෙන්ම, නියත ක්‍රම මඟින් අභ්‍යන්තර පන්ති දත්ත නොබැඳි ලෙස යොමු කිරීමක් ලෙස ආපසු ලබා නොදිය යුතුය.

  • මෙහි ප්‍රති As ලයක් වශයෙන්, යමෙකු බොහෝ විට const overloading භාවිතා කරමින් const සහ non non const නොවන ක්‍රමයක් නිර්මාණය කළ යුතුය. උදාහරණයක් ලෙස, ඔබ නිර්වචනය කරන්නේ නම් T const& operator[] (unsigned i) const;, එවිට ඔබට ලබා දී ඇති නියත නොවන අනුවාදය ද ඔබට අවශ්‍ය වනු ඇත:

    inline T& operator[] (unsigned i) { return const_cast<char&>( static_cast<const TYPE&>(*this)[](i) ); }

අෆයික්, සී හි නියත ශ්‍රිතයක් නොමැත, සාමාජික නොවන කාර්යයන් සී ++ තුළ සංයුක්ත විය නොහැක, කොන්ක්‍රීට් ක්‍රම මඟින් අතුරු ආබාධ ඇති විය හැකි අතර, සම්පාදකයාට අනුපිටපත් ශ්‍රිත ඇමතුම් වළක්වා ගැනීමට කොන්ස් ශ්‍රිත භාවිතා කළ නොහැක. ඇත්ත වශයෙන්ම, සරල int const &සඳහනක් පවා එය යොමු කරන වටිනාකම වෙනත් තැනක වෙනස් වන බවට සාක්ෂි දරයි.


6

මුල් නිර්මාණකරුවන් විසින් සී සහ සී ++ ප්‍රකාශන සින්ටැක්ස් අසාර්ථක අත්හදා බැලීමක් ලෙස නැවත නැවතත් විස්තර කර ඇත.

ඒ වෙනුවට, “පොයින්ටර් ටු ” වර්ගය නම් කරමු Type; මම එය අමතන්නම් Ptr_:

template< class Type >
using Ptr_ = Type*;

දැන් Ptr_<char>වෙත යොමු කිරීමකිchar .

Ptr_<const char> වෙත යොමු කිරීමකි const char .

සහ const Ptr_<const char>වෙත constයොමු කිරීමකිconst char .

එතන.

රූප විස්තරය මෙහි ඇතුළත් කරන්න


3
ඔබට පළමු වාක්‍යය සඳහා උපුටා දැක්වීමක් තිබේද?
sp2danny

@ sp2danny: ගූග්ලිං “සී සින්ටැක්ස් අසාර්ථක අත්හදා බැලීම” මගින් බර්න් ස්ට්‍රෝස්ට්‍රප් සමඟ සම්මුඛ සාකච්ඡා ගණනාවක් පමණක් ඇති කරයි. එහිදී ඔහු තම මතය එම දිශාවට ප්‍රකාශ කරයි. එබැවින් සී හි මුල් නිර්මාණකරුවන්ගේ දෘෂ්ටි කෝණයන් පිළිබඳ ප්‍රකාශයක් ගැන මට කිසිදු සඳහනක් නැත. එය ප්‍රමාණවත් තරම් ශක්තිමත් පර්යේෂණ ප්‍රයත්නයකින් සොයා ගත හැකිය, නැතහොත් ඔවුන්ගෙන් විමසීමෙන් එය ප්‍රතික්ෂේප කළ හැකිය, නමුත් එය දැන් පවතින ආකාරයට වඩා හොඳ යැයි මම සිතමි. හිමිකම් පෑමේ එම කොටස සමඟ, තවමත් තීරණය කර නොමැති අතර බොහෝ විට සත්‍ය වේ :)
චියර්ස් සහ හත්. - ඇල්ෆ්

1
"සී සහ සී ++ ප්‍රකාශන වාක්‍ය ඛණ්ඩය මුල් නිර්මාණකරුවන් විසින් අසාර්ථක අත්හදා බැලීමක් ලෙස නැවත නැවතත් විස්තර කර ඇත." C සඳහා වැරදියි කරුණාකර C පිළිබඳ ඔබේ වාක්‍යය වෙනස් කරන්න හෝ උපුටා දැක්වීම් කිහිපයක් සපයන්න.
ස්ටාර්ගටූර්

3
Ar ස්ටාර්ගේටූර්: පෙනෙන විදිහට ඔබ කලින් අදහස් කියවා ඇති අතර ඔබට පදික වේදිකාව සඳහා උත්තේජනය කළ හැකි යමක් සොයාගෙන ඇත. ඔබේ ජීවිතයට සුබ පැතුම්. කෙසේ වෙතත්, මා වැනි පැරණි-කාලීන අයට බොහෝ කාලයක් ගතවන පර්යේෂණයක නිරත නොවී අපට ඔප්පු කළ නොහැකි බොහෝ දේ මතක තබා ගත හැකිය. ඔයාට පුළුවන් මගේ වචනය ගන්න.
චියර්ස් සහ එච්. - ඇල්ෆ්


6

මට නම්, constඑනම් එය වමට හෝ දකුණට හෝ වමට හෝ දකුණට පෙනෙන දෙයට සාපේක්ෂව පිහිටීම *මට සැබෑ අරුත හඳුනා ගැනීමට උපකාරී වේ.

  1. A constසිට LEFT දක්වා *ඇඟවෙන්නේ දර්ශකය පෙන්වා ඇති constවස්තුව වස්තුවක් බවයි.

  2. A constසිට RIGHT දක්වා *ඇඟවෙන්නේ දර්ශකය constදර්ශකයක් බවයි.

පහත වගුව ස්ටැන්ෆර්ඩ් CS106L ස්ටෑන්ඩර්ඩ් සී ++ ක්‍රමලේඛන රසායනාගාර පා se මාලා පා er කයාගෙන් ලබාගෙන ඇත.

රූප විස්තරය මෙහි ඇතුළත් කරන්න


4

දෙපසින් int සමඟ ඇති නියතය නියත int වෙත යොමු කරයි :

const int *ptr=&i;

හෝ:

int const *ptr=&i;

constපසුව int වෙත නියත දර්ශකය* සාදනු ඇත :

int *const ptr=&i;

මෙම අවස්ථාවේ දී මේ සියල්ල නියත නිඛිලයට යොමු වේ , නමුත් මේ කිසිවක් නියත දර්ශකය නොවේ:

 const int *ptr1=&i, *ptr2=&j;

මෙම අවස්ථාවෙහිදී සියල්ලම නියත නිඛිලයට දර්ශකයක් වන අතර ptr2 නියත නිඛිලයට නියත දර්ශකය වේ . නමුත් ptr1 නියත දර්ශකය නොවේ:

int const *ptr1=&i, *const ptr2=&j;

3

මෙය බොහෝ දුරට දෙවන පේළියට ආමන්ත්‍රණය කරයි: හොඳම භාවිතයන්, පැවරුම්, ක්‍රියාකාරී පරාමිතීන් යනාදිය.

සාමාන්‍ය පුහුණුව. constඔබට හැකි සෑම දෙයක්ම කිරීමට උත්සාහ කරන්න . නැතහොත් එය වෙනත් ආකාරයකින් තැබීමට, සෑම දෙයක්ම constආරම්භ කිරීමට සලස්වන්න , ඉන්පසු අවම කට්ටලය හරියටම ඉවත් කරන්නconst වැඩසටහන ක්‍රියාත්මක වීමට ඉඩ දීම සඳහා අවශ්‍ය . නිරවද්‍යතාවය සාක්ෂාත් කර ගැනීම සඳහා මෙය විශාල උපකාරයක් වනු ඇති අතර, මිනිසුන් වෙනස් කිරීමට බලාපොරොත්තු නොවන දේට උත්සාහ කර ඒවා පැවරූ විට සියුම් දෝෂ හඳුන්වා නොදෙන බවට සහතික වනු ඇත.

වසංගතය මෙන් const_cast <> වළකින්න. ඒ සඳහා නීත්‍යානුකූල භාවිත අවස්ථා එකක් හෝ දෙකක් තිබේ, නමුත් ඒවා ඉතා අල්පය. ඔබ constවස්තුවක් වෙනස් කිරීමට උත්සාහ කරන්නේ නම් , එය ප්‍රකාශයට පත් කළ අය සොයා ගැනීමට ඔබ බොහෝ දේ කරනු ඇතconst පළමුවරට සිදුවිය යුතු දේ පිළිබඳව සම්මුතියකට එළඹීම සඳහා ඔවුන් සමඟ කාරණය කතා කිරීමටත් ඇත.

එය ඉතා පිළිවෙලට පැවරුම් කරා යොමු කරයි. ඔබට යමක් පැවරිය හැක්කේ එය නොනවතින නම් පමණි. ඔබට නියත දෙයක් වෙත පැවරීමට අවශ්‍ය නම්, ඉහත බලන්න. ප්‍රකාශනවල int const *foo;සහ int * const bar;වෙනස් දේවල ඇති බව මතක තබා ගන්න const- මෙහි ඇති වෙනත් පිළිතුරු මගින් එම ප්‍රශ්නය ප්‍රශංසනීය ලෙස ආවරණය කර ඇති බැවින් මම එයට නොයන්නෙමි.

ක්‍රියාකාරී පරාමිතීන්:

වටිනාකම අනුව ගමන් කරන්න: උදා: void func(int param)ඇමතුම් අඩවියේ ඔබ එක් ආකාරයකින් හෝ වෙනත් ආකාරයකින් ගණන් ගන්නේ නැත. ශ්‍රිතය ලෙස ප්‍රකාශ කිරීම සඳහා භාවිත අවස්ථා ඇති බවට තර්කය ඉදිරිපත් කළ හැකියvoid func(int const param) නමුත් එය ඇමතුම්කරුට කිසිදු බලපෑමක් ඇති නොකරන , එය ශ්‍රිතය මත පමණක් වන අතර, එමඟින් සම්මත වූ ඕනෑම අගයක් ඇමතුම අතරතුර ශ්‍රිතය මගින් වෙනස් කළ නොහැක.

යොමුව අනුව ගමන් කරන්න: උදා: void func(int &param)දැන් එය වෙනසක් ඇති කරයි. දැන් ප්‍රකාශයට පත් කර funcඇති පරිදි වෙනස් කිරීමට ඉඩ දී ඇති අතර param, ඕනෑම ඇමතුම් අඩවියක් ප්‍රතිවිපාක සමඟ කටයුතු කිරීමට සූදානම් විය යුතුය. void func(int const &param)කොන්ත්රාත්තුව වෙනස් කිරීම සඳහා ප්රකාශය වෙනස් කිරීම සහ funcදැන් වෙනස් කළ නොහැකි සහතික param, එනම් සම්මත වී ඇති දෙය නැවත එළියට එනු ඇත. අනෙක් අය සඳහන් කර ඇති පරිදි ඔබට වෙනස් කිරීමට අවශ්‍ය නොවන විශාල වස්තුවක් ලාභදායි ලෙස සම්මත කිරීම සඳහා මෙය ඉතා ප්‍රයෝජනවත් වේ. විශාල වස්තුවක් වටිනාකමින් සම්මත කිරීමට වඩා යොමු කිරීමක් සම්මත කිරීම බෙහෙවින් ලාභදායී වේ.

පොයින්ටර් සාමාර්ථයක්: උදා: void func(int *param)හා void func(int const *param)මේ දෙක දැන් නම් උත්සවය සඳහා පරීක්ෂා කිරීමට අවශ්ය බව වරනයක් සමග, ඔවුන්ගේ යොමු සගයන් සමග එච්චරමයි ඒකාන්ව nullptrසමහර අනෙකුත් ගිවිසුම්ගත වගකීමක් බව තහවුරු මිස funcඑය කවදාවත් ලැබෙන බව nullptrතුළ param.

එම මාතෘකාව පිළිබඳ මතය කොටස. මෙවැනි අවස්ථාවක නිවැරදි බව ඔප්පු කිරීම අසරණ දුෂ්කර ය, වැරැද්දක් කිරීම ඉතා පහසු ය. එබැවින් අවස්ථා ගන්න එපා, සෑම විටම දර්ශක පරාමිතීන් පරීක්ෂා කරන්න nullptr. ඔබ වේදනාව හා දුක් වේදනා වලින් බේරෙනු ඇති අතර දිගු කාලීනව දෝෂ සොයා ගැනීමට අපහසු වනු ඇත. චෙක්පතේ පිරිවැය සම්බන්ධයෙන් ගත් කල, එය අපිරිසිදු ය. සම්පාදකයා තුළ ස්ථිතික විශ්ලේෂණය මඟින් එය කළමනාකරණය කළ හැකි අවස්ථාවන්හිදී, ප්‍රශස්තකරණය කෙසේ හෝ එය මඟ හරිනු ඇත. MSVC සඳහා සබැඳි කාල කේත උත්පාදනය හෝ GCC සඳහා WOPR (මම හිතන්නේ) සක්‍රිය කරන්න, එවිට ඔබට එය පුළුල් ලෙස වැඩසටහනක් ලැබෙනු ඇත, එනම් ප්‍රභව කේත මොඩියුල සීමාව ඉක්මවා යන ක්‍රියාකාරී ඇමතුම් වලදී පවා.

දවස අවසානයේදී ඉහත කරුණු සියල්ලම සෑම විටම දර්ශකයන්ට යොමු වීමට වැඩි කැමැත්තක් දක්වයි. ඒවා සෑම තැනකම ආරක්ෂිතයි.


3
  • නම් constවේ වමට ඇති *, එය අගය කිරීමට යොමු (එය ඒක යන්න ප්රශ්නයක් නොවේ const intහෝ int const)
  • නම් constවේ අයිතිය පිළිබඳ *, එය පෙන්නුම් කරන්නක් තමන් වෙත සඳහන්
  • එය දෙකම එකවර විය හැකිය

වැදගත් කරුණක්: const int *p ඔබ සඳහන් කරන අගය නියත යැයි අදහස් නොකෙරේ !! . එයින් අදහස් කරන්නේ ඔබට එම දර්ශකය හරහා එය වෙනස් කළ නොහැකි බවයි (අර්ථය, ඔබට $ * p = ... `පැවරිය නොහැක). වටිනාකම වෙනත් ආකාරවලින් වෙනස් කළ හැකිය. උදා

int x = 5;
const int *p = &x;
x = 6; //legal
printf("%d", *p) // prints 6
*p = 7; //error 

මෙය බොහෝ දුරට ශ්‍රිත අත්සන් වල භාවිතා කිරීමට අදහස් කරයි, ශ්‍රිතයට අහම්බෙන් සම්මත කළ තර්ක වෙනස් කළ නොහැකි බවට සහතික වීම.


2

අනෙක් කරුණු පැහැදිලි කිරීම් අනුගමනය කරමින් සී සඳහා සම්පූර්ණත්වය සඳහා, සී ++ සඳහා විශ්වාස නැත.

  • pp - දර්ශකය සිට දර්ශකය දක්වා
  • p - දර්ශකය
  • දත්ත - උදාහරණ ලෙස පෙන්වා ඇති දෙය x
  • තද - කියවීමට පමණි විචල්‍යය

දර්ශකය

  • p දත්ත - int *p;
  • p දත්ත -int const *p;
  • p දත්ත -int * const p;
  • p දත්ත -int const * const p;

පොයින්ටරයට පොයින්ටරය

  1. pp p දත්ත - int **pp;
  2. pp p දත්ත -int ** const pp;
  3. pp p දත්ත -int * const *pp;
  4. pp p දත්ත -int const **pp;
  5. pp p දත්ත -int * const * const pp;
  6. pp p දත්ත -int const ** const pp;
  7. pp p දත්ත -int const * const *pp;
  8. pp p දත්ත -int const * const * const pp;
// Example 1
int x;
x = 10;
int *p = NULL;
p = &x;
int **pp = NULL;
pp = &p;
printf("%d\n", **pp);

// Example 2
int x;
x = 10;
int *p = NULL;
p = &x;
int ** const pp = &p; // Definition must happen during declaration
printf("%d\n", **pp);

// Example 3
int x;
x = 10;
int * const p = &x; // Definition must happen during declaration
int * const *pp = NULL;
pp = &p;
printf("%d\n", **pp);

// Example 4
int const x = 10; // Definition must happen during declaration
int const * p = NULL;
p = &x;
int const **pp = NULL;
pp = &p;
printf("%d\n", **pp);

// Example 5
int x;
x = 10;
int * const p = &x; // Definition must happen during declaration
int * const * const pp = &p; // Definition must happen during declaration
printf("%d\n", **pp);

// Example 6
int const x = 10; // Definition must happen during declaration
int const *p = NULL;
p = &x;
int const ** const pp = &p; // Definition must happen during declaration
printf("%d\n", **pp);

// Example 7
int const x = 10; // Definition must happen during declaration
int const * const p = &x; // Definition must happen during declaration
int const * const *pp = NULL;
pp = &p;
printf("%d\n", **pp);

// Example 8
int const x = 10; // Definition must happen during declaration
int const * const p = &x; // Definition must happen during declaration
int const * const * const pp = &p; // Definition must happen during declaration
printf("%d\n", **pp);

විරූපණයේ N- මට්ටම්

දිගටම කරගෙන යන්න, නමුත් මනුෂ්‍යත්වය ඔබව නෙරපා හරිනු ඇත.

int x = 10;
int *p = &x;
int **pp = &p;
int ***ppp = &pp;
int ****pppp = &ppp;

printf("%d \n", ****pppp);

0
  1. const int*- නියත intවස්තුවට දර්ශකය .

ඔබට දර්ශකයේ අගය වෙනස් කළ හැකිය; ඔබට intවස්තුවේ වටිනාකම වෙනස් කළ නොහැක , දර්ශකය පෙන්වා දෙයි.


  1. const int * const- නියත intවස්තුවට නියත දර්ශකය .

ඔබට දර්ශකයේ වටිනාකම හෝ intදර්ශකය පෙන්වා දෙන වස්තුවේ වටිනාකම වෙනස් කළ නොහැක .


  1. int const *- නියත intවස්තුවට දර්ශකය .

මෙම ප්‍රකාශය 1 ට සමාන වේ. const int*- ඔබට දර්ශකයේ අගය වෙනස් කළ හැකි නමුත් ඔබට intවස්තුවේ වටිනාකම වෙනස් කළ නොහැක , දර්ශකය පෙන්වා දෙයි.


ඇත්ත වශයෙන්ම, 4 වන විකල්පයක් ඇත:

  1. int * const- intවස්තුවට නියත දර්ශකය .

ඔබට දර්ශකය පෙන්වා දෙන වස්තුවේ වටිනාකම වෙනස් කළ හැකි නමුත් ඔබට දර්ශකයේ වටිනාකම වෙනස් කළ නොහැක. දර්ශකය සෑම විටම එකම intවස්තුවකට යොමු කරනු ඇති නමුත් මෙම වස්තුවේ මෙම අගය intවෙනස් කළ හැකිය.


ඔබට යම් ආකාරයක C හෝ C ++ ඉදිකිරීමක් තීරණය කිරීමට අවශ්‍ය නම් ඔබට ඩේවිඩ් ඇන්ඩර්සන් විසින් සාදන ලද ඔරලෝසුව / සර්පිලාකාර රීතිය භාවිතා කළ හැකිය ; නමුත් රොස් ජේ. ඇන්ඩර්සන් විසින් සාදන ලද ඇන්ඩර්සන්ගේ නීතිය සමඟ පටලවා නොගත යුතුය .

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.