Char s [] और char * s में क्या अंतर है?


506

सी में, कोई इस तरह से घोषणा में एक स्ट्रिंग शाब्दिक का उपयोग कर सकता है:

char s[] = "hello";

या इस तरह:

char *s = "hello";

तो अंतर क्या है? मैं जानना चाहता हूं कि भंडारण अवधि के दौरान वास्तव में क्या होता है, दोनों संकलन और चलाने के समय पर।



8
char * s = "hello", यहाँ s रन टाइम में किसी अन्य स्ट्रिंग को इंगित कर सकता है। मेरा मतलब है कि यह लगातार पॉइंटर नहीं है आप रन टाइम p = "निशांत" पर एक और वैल्यू असाइन कर सकते हैं, जबकि s [] यहाँ s लगातार पॉइंटर है ।। .. यह एक और स्ट्रिंग को पुन: असाइन नहीं किया जा सकता है लेकिन हम एस [इंडेक्स] पर एक और चरित्र मान असाइन कर सकते हैं।
निशांत कुमार

जवाबों:


540

यहाँ अंतर यह है कि

char *s = "Hello world";

मेमोरी के केवल-पढ़ने वाले भागों"Hello world" में जगह लेगा , और इसके लिए एक संकेतक बना देगा जो इस मेमोरी पर किसी भी लेखन ऑपरेशन को अवैध बनाता है।s

करते हुए:

char s[] = "Hello world";

शाब्दिक स्ट्रिंग को केवल-पढ़ने वाली मेमोरी में रखता है और स्टैक पर नए आवंटित मेमोरी में स्ट्रिंग को कॉपी करता है। इस प्रकार बना रहा है

s[0] = 'J';

कानूनी।


22
शाब्दिक स्ट्रिंग "Hello world"दोनों उदाहरणों में "मेमोरी के केवल-पढ़ने योग्य भागों" में है। सरणी के साथ उदाहरण वहाँ इंगित करता है, सरणी के साथ उदाहरण वर्ण तत्वों को कॉपी करता है।
दोपहर

28
pmg: दूसरे मामले में शाब्दिक स्ट्रिंग स्मृति में जरूरी नहीं है कि वह एक ही सन्निहित वस्तु के रूप में मौजूद हो - यह सिर्फ एक आरंभिक है, संकलक काफी गूंज "बाइट तत्काल बाइट" निर्देशों की एक श्रृंखला का उत्सर्जन कर सकता है जिसमें वर्ण मान निहित होते हैं उन्हें।
कैफे

10
चार सरणी उदाहरण जरूरी नहीं कि स्ट्रिंग को स्टैक पर रखें - यदि यह फ़ाइल स्तर पर दिखाई देता है, तो यह संभवतः इसके बजाय किसी प्रकार के आरंभिक डेटा खंड में होगा।
कैफे

9
मैं बाहर बात करने के लिए है कि चार रों = "XX" नहीं है चाहें है केवल पढ़ने के लिए स्मृति में होना (कुछ कार्यान्वयन उदाहरण के लिए, कोई MMus है)। N1362 c1x ड्राफ्ट में कहा गया है कि इस तरह की सरणी को संशोधित करने से अपरिभाषित व्यवहार होता है। लेकिन +1 वैसे भी, क्योंकि उस व्यवहार पर भरोसा करना एक मूर्खतापूर्ण बात है।
paxdiablo

3
मुझे एक फाइल पर एक स्वच्छ संकलन मिलता है जिसमें char msg[] = "hello, world!"; प्रारंभिक डेटा अनुभाग में सिर्फ स्ट्रिंग समाप्त होता है। जब char * constकेवल-पढ़ने के लिए डेटा अनुभाग में समाप्त होने की घोषणा की जाती है। gcc-4.5.3
gcbenison

152

सबसे पहले, फ़ंक्शन तर्क में, वे बिल्कुल बराबर हैं:

void foo(char *x);
void foo(char x[]); // exactly the same in all respects

अन्य संदर्भों में, char *एक सूचक आवंटित करता है, जबकि char []एक सरणी आवंटित करता है। पूर्व मामले में स्ट्रिंग कहां जाती है, आप पूछते हैं? संकलक स्ट्रिंग शाब्दिक रूप से धारण करने के लिए एक स्थिर अनाम सरणी को गुप्त रूप से आवंटित करता है। इसलिए:

char *x = "Foo";
// is approximately equivalent to:
static const char __secret_anonymous_array[] = "Foo";
char *x = (char *) __secret_anonymous_array;

ध्यान दें कि आपको कभी भी इस सूचक के माध्यम से इस अनाम सरणी की सामग्री को संशोधित करने का प्रयास नहीं करना चाहिए; प्रभाव अपरिभाषित होते हैं (अक्सर दुर्घटना का अर्थ होता है):

x[1] = 'O'; // BAD. DON'T DO THIS.

सरणी सिंटैक्स का उपयोग करके इसे सीधे नई मेमोरी में आवंटित किया जाता है। इस प्रकार संशोधन सुरक्षित है:

char x[] = "Foo";
x[1] = 'O'; // No problem.

हालाँकि यह सरणी केवल तब तक रहती है जब तक कि इसका कंटैनिंग स्कोप न हो, इसलिए यदि आप किसी फ़ंक्शन में ऐसा करते हैं, तो इस ऐरे में पॉइंटर लौटाएं या लीक न करें - इसके साथ एक कॉपी बनाएं strdup() या इसी तरह । यदि सरणी को वैश्विक दायरे में आवंटित किया गया है, तो निश्चित रूप से, कोई समस्या नहीं है।


72

यह घोषणा:

char s[] = "hello";

एक ऑब्जेक्ट बनाता है - charआकार 6 की एक सरणी, जिसे sमूल्यों के साथ आरंभीकृत किया जाता है 'h', 'e', 'l', 'l', 'o', '\0'। यह सरणी स्मृति में कहाँ आवंटित की गई है, और यह कितने समय तक रहती है, यह इस बात पर निर्भर करता है कि घोषणा कहाँ दिखाई देती है। यदि घोषणा एक फ़ंक्शन के भीतर है, तो यह उस ब्लॉक के अंत तक जीवित रहेगा जब तक यह घोषित नहीं किया जाता है और लगभग निश्चित रूप से स्टैक पर आवंटित किया जाता है; यदि यह किसी फ़ंक्शन के बाहर है, तो संभवतः इसे "इनिशियलाइज़्ड डेटा सेगमेंट" के भीतर संग्रहित किया जाएगा जो कि प्रोग्राम चलने पर निष्पादन योग्य फ़ाइल से राइटेबल मेमोरी में लोड हो जाता है।

दूसरी ओर, यह घोषणा:

char *s ="hello";

दो ऑब्जेक्ट बनाता है:

  • एक केवल पढ़ने के लिए 6 की सरणी charमूल्यों से युक्त रों 'h', 'e', 'l', 'l', 'o', '\0'है, जो कोई नाम नहीं है और है स्थिर भंडारण अवधि (जिसका अर्थ है कि यह कार्यक्रम के पूरे जीवन के लिए रहता है); तथा
  • एक प्रकार का पॉइंटर-टू-चर, जिसे कहा जाता है s, जो उस अनाम, रीड-ओनली एरे में पहले वर्ण के स्थान के साथ आरम्भ होता है।

अनाम रीड-ओनली सरणी आमतौर पर प्रोग्राम के "टेक्स्ट" सेगमेंट में स्थित होती है, जिसका अर्थ है कि यह डिस्क से रीड-ओनली मेमोरी में लोड होता है, कोड के साथ ही। sमेमोरी में पॉइंटर चर का स्थान इस बात पर निर्भर करता है कि घोषणा कहाँ दिखाई देती है (पहले उदाहरण की तरह)।


1
"हेलो" मेमोरी के लिए दोनों घोषणाओं को कॉम्प्लेक्स समय पर आवंटित किया जाता है? और दूसरी बात चार * पी = "हैलो" यहाँ "हेल्लो" को टेक्स्ट सेगमेंट में संग्रहीत किया जाता है, जैसा कि आपने अपने उत्तर में कहा है ... और क्या है एस के बारे में [] = "हैलो" यह पहले टेक्स्ट सेगमेंट भाग में भी संग्रहीत करेगा और रन समय के दौरान स्टैक में कॉपी करेगा जैसा कि रिकार्ड ने कहा है। कृपया इस बिंदु को स्पष्ट करें।
निशांत कुमार

2
@ निशांत: इस char s[] = "hello"मामले में, "hello"बस एक इनिलाइज़र है जो कंपाइलर को बता रहा है कि ऐरे को कैसे इनिशियलाइज़ किया जाना चाहिए। टेक्स्ट सेगमेंट में इसके अनुरूप स्ट्रिंग हो सकती है या नहीं हो सकती है - उदाहरण के लिए, यदि sस्टैटिक स्टोरेज की अवधि है, तो यह संभावना है कि "hello"प्रारंभिक डेटा सेगमेंट में एकमात्र उदाहरण - ऑब्जेक्ट sही होगा। यहां तक ​​कि अगर sस्वचालित भंडारण की अवधि है, तो इसे एक कॉपी (जैसे। movl $1819043176, -6(%ebp); movw $111, -2(%ebp)) के बजाय शाब्दिक दुकानों के अनुक्रम द्वारा आरंभ किया जा सकता है ।
कैफे

अधिक सटीक रूप से, जीसीसी 4.8 इसे डालता है .rodata, जो लिंकर स्क्रिप्ट फिर उसी खंड में डंप करता है .textमेरा जवाब देखिए ।
सीरो शांतिली 郝海东 iro iro i

@ कफ, रिकार्ड द्वारा पहले उत्तर में, यह लिखा गया है कि char s[] = "Hello world";शाब्दिक स्ट्रिंग को रीड-ओनली मेमोरी में रखा जाता है और स्टैक पर नए आवंटित मेमोरी में स्ट्रिंग को कॉपी करता है। लेकिन, आपका जवाब केवल वाचन में शाब्दिक स्ट्रिंग के बारे में बोलता है जो केवल मेमोरी में है और वाक्य का दूसरा भाग छोड़ता है जो कहता है copies the string to newly allocated memory on the stack:। तो, क्या दूसरा भाग निर्दिष्ट नहीं करने के लिए आपका उत्तर अधूरा है?
केपीएमजी

1
@AjaySinghNegi: जैसा कि मैंने अन्य टिप्पणियों (इस उत्तर के लिए, और रिकार्ड के उत्तर में) में कहा है, स्ट्रिंग char s[] = "Hellow world";केवल एक इनिशियलाइज़र है और जरूरी नहीं कि इसे एक अलग रीड-ओनली कॉपी के रूप में संग्रहीत किया जाए। यदि sस्थिर भंडारण अवधि है, तो स्ट्रिंग की एकमात्र प्रति के स्थान पर एक रीड-राइट सेगमेंट में होने की संभावना है s, और फिर भी नहीं तो कंपाइलर लोड-तत्काल निर्देशों के साथ सरणी को आरम्भ करने के लिए चुन सकता है या कॉपी करने के बजाय इसी तरह केवल पढ़ने के लिए स्ट्रिंग से। मुद्दा यह है कि इस मामले में, इनिशियलर स्ट्रिंग में ही कोई रनटाइम उपस्थिति नहीं है।
कैफे

60

घोषणाओं को देखते हुए

char *s0 = "hello world";
char s1[] = "hello world";

निम्नलिखित काल्पनिक स्मृति मानचित्र ग्रहण करें:

                    0x01 0x02 0x03 0x04
        0x00008000: 'एच' 'ई' 'एल' 'एल'
        0x00008004: 'ओ' '' 'डब्ल्यू' 'ओ'
        0x00008008: 'r' 'l' 'd' 0x00
        ...
s0: 0x00010000: 0x00 0x00 0x80 0x00
s1: 0x00010004: 'h' 'e' 'l' 'l'
        0x00010008: 'ओ' '' 'डब्ल्यू' 'ओ'
        0x0001000C: 'r' 'l' 'd' 0x00

स्ट्रिंग शाब्दिक स्थैतिक भंडारण अवधि के साथ "hello world"एक 12-तत्व सरणी char( const charC ++ में) है, जिसका अर्थ है कि जब प्रोग्राम शुरू होता है और कार्यक्रम समाप्त होने तक आवंटित किया जाता है तो इसके लिए मेमोरी आवंटित की जाती है। एक स्ट्रिंग शाब्दिक की सामग्री को संशोधित करने का प्रयास अपरिभाषित व्यवहार को आमंत्रित करता है।

रेखा

char *s0 = "hello world";

ऑटो स्टोरेज अवधि के साथ s0एक पॉइंटर के रूप में परिभाषित करता है char(जिसका अर्थ है कि चर s0केवल उस गुंजाइश के लिए मौजूद है जिसमें इसे घोषित किया गया है) और स्ट्रिंग शाब्दिक ( इस उदाहरण में) के पते को कॉपी करता 0x00008000है। ध्यान दें कि जब से s0एक स्ट्रिंग शाब्दिक को अंक है, यह (उदाहरण के लिए, किसी भी समारोह है कि इसे संशोधित करने की कोशिश करेगा करने के लिए एक तर्क के रूप में इस्तेमाल नहीं किया जाना चाहिए strtok(), strcat(), strcpy(), आदि)।

रेखा

char s1[] = "hello world";

ऑटो स्टोरेज अवधि के साथ ( s1तत्व charशाब्दिक से लंबाई लिया जाता है) के 12-तत्व सरणी के रूप में परिभाषित करता है और शाब्दिक की सामग्री को सरणी में कॉपी करता है । जैसा कि आप मेमोरी मैप से देख सकते हैं, हमारे पास स्ट्रिंग की दो प्रतियां हैं "hello world"; अंतर यह है कि आप इसमें निहित स्ट्रिंग को संशोधित कर सकते हैं s1

s0और s1अधिकांश संदर्भों में विनिमेय हैं; यहाँ अपवाद हैं:

sizeof s0 == sizeof (char*)
sizeof s1 == 12

type of &s0 == char **
type of &s1 == char (*)[12] // pointer to a 12-element array of char

आप s0भिन्न स्ट्रिंग शाब्दिक या किसी अन्य चर को इंगित करने के लिए चर को फिर से असाइन कर सकते हैं । आप s1भिन्न सरणी को इंगित करने के लिए चर को पुन: असाइन नहीं कर सकते हैं ।


2
मुझे लगता है कि काल्पनिक मेमोरी मैप को समझना आसान है!
आधी रात को

32

C99 N1256 ड्राफ्ट

चरित्र स्ट्रिंग शाब्दिक के दो अलग-अलग उपयोग हैं:

  1. आरंभ करें char[]:

    char c[] = "abc";      

    यह "अधिक जादू" है, और 6.7.8 / 14 "प्रारंभिककरण" में वर्णित है:

    वर्ण प्रकार का एक वर्ण वर्ण स्ट्रिंग शाब्दिक द्वारा प्रारंभ किया जा सकता है, वैकल्पिक रूप से ब्रेसिज़ में संलग्न है। चरित्र स्ट्रिंग शाब्दिक के क्रमिक वर्ण (यदि कमरे में या यदि सरणी अज्ञात आकार का है, तो समाप्त करने वाले अशक्त चरित्र सहित), सरणी के तत्वों को आरंभीकृत करते हैं।

    तो यह सिर्फ एक शॉर्टकट है:

    char c[] = {'a', 'b', 'c', '\0'};

    किसी भी अन्य नियमित सरणी की तरह, cसंशोधित किया जा सकता है।

  2. हर जगह: यह एक उत्पन्न करता है:

    इसलिए जब आप लिखते हैं:

    char *c = "abc";

    यह समान है:

    /* __unnamed is magic because modifying it gives UB. */
    static char __unnamed[] = "abc";
    char *c = __unnamed;

    नोट से निहित कलाकारों char[]के लिए char *है, जो हमेशा कानूनी है।

    फिर यदि आप संशोधित करते हैं c[0], तो आप संशोधित भी करते हैं __unnamed, जो कि यूबी है।

    यह 6.4.5 "स्ट्रिंग शाब्दिक" पर प्रलेखित है:

    5 अनुवाद चरण 7 में, एक बाइट या मूल्य शून्य का कोड प्रत्येक मल्टीबीट चरित्र अनुक्रम में जोड़ा जाता है जो एक स्ट्रिंग शाब्दिक या शाब्दिक परिणाम होता है। मल्टीबाइट कैरेक्टर सीक्वेंस का उपयोग तब स्टैटिक स्टोरेज की अवधि और लंबाई को व्यवस्थित करने के लिए किया जाता है। चरित्र स्ट्रिंग शाब्दिकों के लिए, सरणी तत्वों में चार वर्ण होते हैं, और मल्टीबाइट वर्ण अनुक्रम के व्यक्तिगत बाइट्स के साथ आरंभिक होते हैं ...]]

    6 यह स्पष्ट नहीं है कि क्या ये सरणियाँ अलग-अलग हैं बशर्ते कि उनके तत्वों में उचित मूल्य हों। यदि प्रोग्राम ऐसे सरणी को संशोधित करने का प्रयास करता है, तो व्यवहार अपरिभाषित है।

6.7.8 / 32 "प्रारंभिक" एक प्रत्यक्ष उदाहरण देता है:

उदाहरण 8: घोषणा

char s[] = "abc", t[3] = "abc";

"सादा" वर्ण सरणी वस्तुओं को परिभाषित करता है sऔर tजिनके तत्व वर्ण स्ट्रिंग शाब्दिक के साथ आरंभिक होते हैं।

यह घोषणा समान है

char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };

सरणियों की सामग्री परिवर्तनीय हैं। दूसरी ओर, घोषणा

char *p = "abc";

pप्रकार "पॉइंटर टू चार" के साथ परिभाषित करता है और इसे एक ऑब्जेक्ट के साथ इंगित करने के लिए टाइप करता है "वर्ण का प्रकार" लंबाई 4 के साथ जिसका तत्व एक चरित्र स्ट्रिंग शाब्दिक के साथ आरम्भ किया गया है। यदि pसरणी की सामग्री को संशोधित करने के लिए उपयोग करने का प्रयास किया जाता है , तो व्यवहार अपरिभाषित है।

जीसीसी 4.8 x86-64 ईएलएफ कार्यान्वयन

कार्यक्रम:

#include <stdio.h>

int main(void) {
    char *s = "abc";
    printf("%s\n", s);
    return 0;
}

संकलन और विघटित:

gcc -ggdb -std=c99 -c main.c
objdump -Sr main.o

आउटपुट में शामिल हैं:

 char *s = "abc";
8:  48 c7 45 f8 00 00 00    movq   $0x0,-0x8(%rbp)
f:  00 
        c: R_X86_64_32S .rodata

निष्कर्ष: GCC char*इसे .rodataअनुभाग में संग्रहीत करता है , अंदर नहीं .text

हालांकि ध्यान दें कि डिफ़ॉल्ट लिंकर स्क्रिप्ट डालता है .rodataऔर .textउसी सेगमेंट में होता है, जिसने निष्पादित किया है, लेकिन कोई लिखित अनुमति नहीं है। इसके साथ मनाया जा सकता है:

readelf -l a.out

जिसमें है:

 Section to Segment mapping:
  Segment Sections...
   02     .text .rodata

यदि हम ऐसा ही करते हैं char[]:

 char s[] = "abc";

हमने प्राप्त किया:

17:   c7 45 f0 61 62 63 00    movl   $0x636261,-0x10(%rbp)

तो यह स्टैक में संग्रहीत (सापेक्ष %rbp) हो जाता है ।


15
char s[] = "hello";

sएक सरणी होने की घोषणा करता है, charजो आरंक्षक (5 + 1 chars) को पकड़ने के लिए काफी लंबा है और सरणी में दिए गए स्ट्रिंग शाब्दिक के सदस्यों को कॉपी करके सरणी को आरंभीकृत करता है।

char *s = "hello";

sएक या एक से अधिक (इस मामले में अधिक) के लिए एक संकेतक होने की घोषणा करता है charऔर इसे शाब्दिक युक्त एक निश्चित (केवल पढ़ने के लिए) स्थान पर इंगित करता है "hello"


1
फ़ंक्शंस में उपयोग करने के लिए क्या विधि बेहतर है यदि s को नहीं बदला जाएगा, f (const char s []) या f (const char * s)?
साइहोडेलिया

1
@psihodelia: एक फ़ंक्शन घोषणा में कोई अंतर नहीं है। दोनों ही मामलों sमें एक सूचक है const char
सीबी बेली

4
char s[] = "Hello world";

यहाँ, sवर्णों की एक सरणी है, जिसे हम चाहें तो अधिलेखित किया जा सकता है।

char *s = "hello";

एक स्ट्रिंग शाब्दिक का उपयोग इन वर्ण ब्लॉक को मेमोरी में कहीं बनाने के लिए किया जाता है जिसे यह पॉइंटर sइंगित कर रहा है। हम यहां उस वस्तु को फिर से असाइन कर सकते हैं जो इसे बदलकर इंगित कर रही है, लेकिन जब तक यह एक स्ट्रिंग शाब्दिक को वर्णों के ब्लॉक को इंगित करता है, जिसे यह इंगित नहीं किया जा सकता है।


@bo पर्सन दूसरे मामले में पात्रों का ब्लॉक क्यों नहीं बदला जा सकता है?
पंकज महतो

3

एक अतिरिक्त के रूप में, कि मानते हैं, के रूप में केवल पढ़ने के प्रयोजनों के लिए दोनों के उपयोग के समान है, आप के साथ या तो अनुक्रमण द्वारा चार उपयोग कर सकते हैं []या *(<var> + <index>) प्रारूप:

printf("%c", x[1]);     //Prints r

तथा:

printf("%c", *(x + 1)); //Prints r

जाहिर है, यदि आप करने का प्रयास करते हैं

*(x + 1) = 'a';

संभवत: आपको एक सेगमेंटेशन फ़ॉल्ट मिलेगा, क्योंकि आप रीड-ओनली मेमोरी एक्सेस करने की कोशिश कर रहे हैं।


यह किसी भी तरह से अलग नहीं है, x[1] = 'a';जिसमें सेगफॉल्ट (साथ ही प्लेटफॉर्म पर निर्भर करता है)।
10

3

बस जोड़ने के लिए: आपको उनके आकारों के लिए अलग-अलग मान भी मिलते हैं।

printf("sizeof s[] = %zu\n", sizeof(s));  //6
printf("sizeof *s  = %zu\n", sizeof(s));  //4 or 8

जैसा कि ऊपर बताया गया है, एक सरणी के '\0'लिए अंतिम तत्व के रूप में आवंटित किया जाएगा।


2
char *str = "Hello";

उपरोक्त सेट्स शाब्दिक मान "हैलो" को इंगित करने के लिए ऊपर है जो प्रोग्राम की बाइनरी इमेज में हार्ड-कोडेड है, जिसे केवल-पढ़ने के लिए मेमोरी के रूप में चिह्नित किया गया है, इसका मतलब है कि इस स्ट्रिंग शाब्दिक में कोई भी परिवर्तन अवैध है और यह विभाजन दोषों को फेंक देगा।

char str[] = "Hello";

स्टैक पर नव आवंटित मेमोरी में स्ट्रिंग को कॉपी करता है। इस प्रकार इसमें कोई भी परिवर्तन करने की अनुमति है और कानूनी है।

means str[0] = 'M';

"मेलो" के लिए स्ट्रिंग को बदल देगा।

अधिक जानकारी के लिए, कृपया इसी तरह के प्रश्न से गुजरें:

जब मुझे "char * s" के साथ आरंभिक स्ट्रिंग में लिखने पर एक विभाजन दोष मिलता है, लेकिन "char s []" नहीं?


0

के मामले में:

char *x = "fred";

x एक अंतराल है - इसे सौंपा जा सकता है। लेकिन इस मामले में:

char x[] = "fred";

x एक लवल्यू नहीं है, यह एक प्रचलन है - आप इसे असाइन नहीं कर सकते।


3
तकनीकी रूप से, xएक गैर-परिवर्तनीय अंतराल है। हालांकि लगभग सभी संदर्भों में, यह अपने पहले तत्व के लिए एक संकेतक का मूल्यांकन करेगा, और वह मूल्य एक प्रतिद्वंद्विता है।
कैफे

0
char *s1 = "Hello world"; // Points to fixed character string which is not allowed to modify
char s2[] = "Hello world"; // As good as fixed array of characters in string so allowed to modify

// s1[0] = 'J'; // Illegal
s2[0] = 'J'; // Legal

-1

यहाँ टिप्पणियों की रोशनी में यह स्पष्ट होना चाहिए कि: char * s = "हैलो"; एक बुरा विचार है, और इसका उपयोग बहुत संकीर्ण दायरे में किया जाना चाहिए।

यह इंगित करने का एक अच्छा अवसर हो सकता है कि "कांस्ट शुद्धता" एक "अच्छी बात" है। जब भी और जहाँ भी आप कर सकते हैं, "कोड" कीवर्ड का उपयोग अपने कोड की रक्षा करने के लिए, "आराम से" कॉल करने वाले या प्रोग्रामर से करें, जो आमतौर पर पॉइंट में आने पर सबसे "आराम" होते हैं।

पर्याप्त मेलोड्रामा, यहां वह है जो "कॉन्स्ट" के साथ संकेत देने वाले को प्राप्त कर सकता है। (नोट: किसी को दाएं-बाएं सूचक की घोषणाओं को पढ़ना है।) पॉइंटर्स खेलते समय अपने आप को बचाने के 3 अलग-अलग तरीके हैं:

const DBJ* p means "p points to a DBJ that is const" 

- अर्थात, DBJ ऑब्जेक्ट को p के माध्यम से नहीं बदला जा सकता है।

DBJ* const p means "p is a const pointer to a DBJ" 

- अर्थात, आप p के माध्यम से DBJ ऑब्जेक्ट को बदल सकते हैं, लेकिन आप पॉइंटर p को स्वयं नहीं बदल सकते।

const DBJ* const p means "p is a const pointer to a const DBJ" 

- अर्थात, आप सूचक p को स्वयं नहीं बदल सकते, और न ही p के द्वारा DBJ ऑब्जेक्ट को बदल सकते हैं।

संकलित कॉन्स्ट-एंट म्यूटेशन से संबंधित त्रुटियों को संकलन समय पर पकड़ा जाता है। कब्ज के लिए कोई रनटाइम स्पेस या स्पीड पेनल्टी नहीं है।

(मान लें कि आप C ++ कंपाइलर का उपयोग कर रहे हैं, निश्चित रूप से?)

--DBJ


यह सब सही है, लेकिन इसका सवाल से कोई लेना-देना नहीं है। और जहाँ तक C ++ कंपाइलर के बारे में आपकी धारणा है, सवाल C के रूप में टैग किया गया है, C ++ के रूप में नहीं।
फैबियो का कहना है कि

Char * s = "const string" के बारे में कुछ भी बुरा नहीं है;
पॉल स्मिथ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.