2012-05-11 22 views
5

संभव डुप्लिकेट:
How are string literals compiled in C?पता तुलना और स्ट्रिंग भंडारण

मैं नीचे छोटे कोड लिखा था। इस कोड में, मुझे लगता है कि पहली और दूसरी "हैलो" स्ट्रिंग का पता तुलना की जाएगी। मैं इसमें उलझन में हूं। पहले देखो में, मैंने सोचा था कि दोनों तारों को केवल स्मृति में संग्रहीत किया जाएगा और इस प्रकार अलग-अलग पता होगा। लेकिन निष्पादन के बाद "बराबर" मुद्रित हो गया।

जब मैंने objdump देखा, तो मैं स्ट्रिंग हैलो को देखने में सक्षम नहीं था। मैं समझता हूं कि मैंने उन्हें स्टोर करने के लिए एक चर नहीं लिया है, लेकिन "हैलो" कहाँ संग्रहित किया जाएगा।

क्या इसे स्टैक पर संग्रहीत किया जाएगा ?? या क्या यह कोड सेगमेंट पर संग्रहीत किया जाएगा ??

#include<stdio.h> 
int main() 
{ 
    if ("hello" == "hello") 
     printf("\n equal "); 
    else 
     printf("\n not equal"); 
    return 0; 
} 

जब मैं if ("hello" == "hell1") को अगर हालत बदल गया है, "इसके बराबर नहीं" मुद्रित कर ली। फिर, स्ट्रिंग्स कहां और कैसे संग्रहीत हो रहे हैं। क्या इसे स्टैक पर संग्रहीत किया जाएगा ?? या क्या यह कोड सेगमेंट पर संग्रहीत किया जाएगा ??

यदि कोई यहां मुझे विस्तृत उत्तर देता है तो मैं वास्तव में सराहना करता हूं। धन्यवाद

+0

यदि आप इसके डिस्सेप्लर देखते हैं, तो आप देखेंगे कि बिल्कुल 'if' समकक्ष नहीं है! अनुकूलित किया गया! –

+0

संभावित डुप्लिकेट [एक मूल प्रश्न: सी में स्ट्रिंग अक्षर कैसे संकलित होते हैं?] (Http://stackoverflow.com/q/6680819/), [क्यों "ए"! = "ए" सी में है?] (Http : //stackoverflow.com/q/4843640/), [सी स्ट्रिंग अक्षर: वे कहां जाते हैं?] (http://stackoverflow.com/q/2589949/) – outis

उत्तर

3

आपके विशेष उदाहरण में, "हैलो" स्ट्रिंग कोड का भी हिस्सा नहीं हैं। कंपाइलर यह समझने के लिए पर्याप्त स्मार्ट है कि कोड हमेशा और हमेशा के लिए अनॉन प्रिंट "बराबर" होगा, इसलिए यह उन्हें पूरी तरह से अलग कर देता है।

यदि आपका कोड इस तरह दिख रही है, हालांकि:

#include<stdio.h> 
int main() 
{ 
    const char *h1 = "hello"; 
    const char *h2 = "hello"; 
    if (h1 == h2) 
     printf("\n equal "); 
    else 
     printf("\n not equal"); 
    return 0; 
} 

आप होगा अभी भी मिल "बराबर", भले ही, हालांकि, वास्तव में तुलना किया जाएगा (जब अतिरिक्त अनुकूलन के बिना संकलित)। यह एक अनुकूलन है - संकलक ने पाया कि आपके पास दो समान, हार्ड-कोड वाले तार हैं और परिणामस्वरूप बाइनरी में उन्हें विलय कर दिया गया है।

जबकि, यदि आपका कोड इस तरह देखा, संकलक नहीं कि वे एक ही कर रहे हैं (डिफ़ॉल्ट रूप से) लगता है कि करने में सक्षम होगा, और आप "इसके बराबर नहीं" संदेश दिखाई देगा:

#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 

int main() 
{ 
    char *h1 = malloc(sizeof(char) * 10); 
    char *h2 = malloc(sizeof(char) * 10); 

    strcpy(h1, "hello"); 
    strcpy(h2, "hello"); 

    if (h1 == h2) 
     printf("\n equal "); 
    else 
     printf("\n not equal"); 

    free(h1); 
    free(h2); 

    return 0; 
} 
+0

ऑप्टिमाइज़ेशन के बिना भी, एक तरह का अनुकूलन हुआ है आपके द्वारा दिखाए गए कोड में। 'H1' और' h2' दोनों एक ही स्थान पर इंगित करते हैं। मुझे लगता है कि हम संकलक को 'O0' पर भी बुनियादी अनुकूलन से नहीं रोक सकते हैं? यकीन नहीं है कि –

+0

@ पवनमंजुनथ मैंने इसे स्पष्ट करने के लिए अपनी पोस्ट का पुनर्गठन किया। –

+0

चूंकि यह एक पता तुलना है, तो कंपाइलर स्ट्रिंग तुलना की धारणा पर कोड को अनुकूलित कैसे कर सकता है? –

0

स्ट्रिंग अक्षर, क्योंकि आपके दो "hello" को संकलक द्वारा केवल-पढ़ने वाली मेमोरी में महसूस किया जा सकता है और इसके अतिरिक्त उन्हें एक ऐसे अक्षर का एहसास करने का अधिकार है यदि मूल्य मेल खाता है।

तो आपकी तुलना का परिणाम कार्यान्वयन परिभाषित किया गया है और आपके द्वारा दिए गए समान संकलक या विभिन्न अनुकूलन विकल्पों के विभिन्न संस्करणों के लिए भी भिन्न हो सकता है।

+0

असल में, उनके उदाहरण में, "हैलो" बिल्कुल '.TEXT' में संग्रहीत नहीं है। लेकिन आप मेरी पोस्ट में संशोधित कोड के लिए सही हैं। –

+0

@ महमूद अल-कुडसी, आपके कंपाइलर के लिए यह मामला हो सकता है या नहीं। यह मंच का कार्यान्वयन विवरण है, विभिन्न कंपाइलर्स अलग-अलग करेंगे। –

1

यदि दो स्ट्रिंग बराबर की तुलना में बराबर हैं, जैसे "हैलो" == "हैलो", तो मुख्य रूप से कोई तुलना नहीं है क्योंकि पवन मंजुनाथ ने कहा था। विधानसभा इस प्रकार है:

 
    .file "hello.c" 
    .section .rodata 
.LC0: 
    .string "\n equal " 
    .text 
.globl main 
    .type main, @function 

लेकिन अगर इन दो स्ट्रिंग, बराबर नहीं है "hello2" == की तरह "हैलो", तो संकलक स्मृति में आवंटित करेगा।उनके लिए रॉडाटा, जैसा कि निम्नानुसार लगता है,

 
    .file "hello.c" 
    .section .rodata 
.LC0: 
    .string "hello2" 
.LC1: 
    .string "hello" 
संबंधित मुद्दे