2012-07-22 4 views
11
#include<stdio.h> 
int main(void){ 
    int *ptr,a,b; 
    a = ptr; 
    b = ptr + 1; 
    printf("the vale of a,b is %x and %x respectively",a,b); 

    int c,d; 
    c = 0xff; 
    d = c + 1; 
    printf("the value of c d are %x and %x respectively",c,d); 
    return 0; 
} 

बाहर डाल मूल्यक्यों एक सूचक + 1 ऐड 4 वास्तव में

the vale of a,b is 57550c90 and 57550c94 respectively 
the value of c d are ff and 100 respectively% 

यह वास्तव में ptr +1 पता चला है, कारण है कि यह इस तरह से व्यवहार करते हैं है?

+5

क्योंकि यह है कि पॉइंटर अंकगणित सी में कैसे काम करता है इसी तरह यह परिभाषित किया जाता है। जब आप 'int *' पॉइंटर में 1 जोड़ते हैं तो यह अगले 'int' ऑब्जेक्ट पर जाता है। जाहिर है, आपके प्लेटफ़ॉर्म 'int' पर 4 बाइट्स होते हैं। यह सी पॉइंटर्स के बारे में बुनियादी जानकारी है - जो कुछ आप किसी पुस्तक में पढ़ते हैं। – AnT

+1

इस तरह के एक प्रश्न के लिए [मेरा पिछला उत्तर] (http://stackoverflow.com/a/8772201/119527) देखें। –

+0

आपको पॉइंटर्स के लिए 'printf' प्रारूप तारों में'% p' का उपयोग करना चाहिए। इसके लिए '% x' का उपयोग न करें, यह पोर्टेबल नहीं है (क्योंकि पॉइंटर्स और 'int'-s की अलग-अलग बिट चौड़ाई हो सकती है)। –

उत्तर

20

विचार करें कि एक सूचक क्या है ... यह एक स्मृति पता है। स्मृति में प्रत्येक बाइट एक पता है। इसलिए, यदि आपके पास int है जो 4 बाइट्स है और इसका पता 1000 है, तो 1001 वास्तव में int का दूसरा बाइट है और 1002 तीसरा बाइट है और 1003 चौथा है। चूंकि int का आकार कंपाइलर से कंपाइलर में भिन्न हो सकता है, इसलिए यह आवश्यक है कि जब आप अपने पॉइंटर को बढ़ाते हैं तो आपको int में कुछ मध्य बिंदु का पता नहीं मिलता है। तो, आपके डेटा प्रकार के आधार पर कितने बाइट्स को छोड़ना है, यह पता लगाने का काम आपके लिए संभाला जाता है और आप जो भी मूल्य प्राप्त करते हैं उसका उपयोग कर सकते हैं और इसके बारे में चिंता नहीं करते हैं।

बेसिल स्टैरनविच बताते हैं कि यह राशि डेटा सदस्य की sizeof संपत्ति के आधार पर अलग-अलग होगी। यह भूलना बहुत आसान है कि यद्यपि पते अनुक्रमिक हैं, फिर भी आपके ऑब्जेक्ट्स के पॉइंटर्स को उन ऑब्जेक्ट्स को रखने के लिए आवश्यक वास्तविक मेमोरी स्पेस को ध्यान में रखना होगा।

24

क्योंकि संकेत सरणियों के साथ संगत होना करने के लिए तैयार कर रहे हैं:

*(pointer + offset) 

बाइट्स के मामले में काम नहीं करता है

pointer[offset] 

तो सूचक aritmetic के बराबर है, लेकिन sizeof(pointer base type) -bytes के मामले में आकार के ब्लॉक।

+0

, यह 8 बाइट्स जितना बड़ा हो सकता है। – Aftnix

+0

@Aftnix हाँ, लेकिन उसमें क्या समस्या है? –

+0

@Aftnix और नहीं, 256-बाइट आकार की संरचना में पॉइंटर बनाने पर विचार करें ... –

2

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

7

आप वास्तव में समय लेना चाहिए एक अच्छा सी प्रोग्रामिंग भाषा किताब पढ़ने के लिए (जैसे K&R "the C programming language")

सूचक अंकगणित एक मुश्किल विषय है। एक सूचक अतिरिक्त मतलब कुछ अगले बिंदु तत्व को पारित करने का मतलब है। इसलिए पता sizeof द्वारा इंगित तत्व द्वारा बढ़ाया गया है।

+0

मैं आज इस पुस्तकालय से पुस्तकालय से अनुरोध कर रहा हूं! – mko

1

एक सूचक p पर विचार करें। अभिव्यक्ति p+n(unsigned char *)p + n * sizeof *p (क्योंकि sizeof(unsigned char) == 1) की तरह है। इस प्रयास करें:

#include <stdio.h> 
#define N 3 

int 
main(void) 
{ 
    int i; 
    int *p = &i; 
    printf("%p\n", (void *)p); 
    printf("%p\n", (void *)(p + N)); 
    printf("%p\n", (void *)((unsigned char *)p + N * sizeof *p)); 
    return 0; 
} 
5

लघु जवाब

सूचक का पता वृद्धि की जाएगी sizeof(T) द्वारा जहां T प्रकार की ओर इशारा कर रहा है। तो int के लिए, सूचक sizeof(int) द्वारा बढ़ाया जाएगा।

क्यों?

अच्छी तरह से सबसे पहले और सबसे महत्वपूर्ण, मानक की आवश्यकता है।कारण यह व्यवहार उपयोगी है (सी के साथ संगतता के अलावा) इसलिए है क्योंकि जब आपके पास डेटा संरचना होती है जो एक सरणी या std::vector जैसी संगत स्मृति का उपयोग करती है, तो आप केवल एक को जोड़कर सरणी में अगले आइटम पर जा सकते हैं सूचक। यदि आप कंटेनर में nth आइटम पर जाना चाहते हैं, तो आप बस एन जोड़ें।

firstAddress + 2 लिखने में सक्षम होने के नाते firstAddress + (sizeof(T) * 2) की तुलना में कहीं आसान है, और firstAddress + (4 * 2) तरह sizeof(int) संभालने डेवलपर्स से उत्पन्न होने वाले कीड़े है 4 (यह नहीं हो सकता है) और लेखन कोड नहीं जा पाता।

वास्तव में, जब आप myArray[4] कहते हैं, तो आप myArray + 4 कह रहे हैं। यही कारण है कि सरणी सूचकांक 0 से शुरू होते हैं; आप पहले तत्व प्राप्त करने के लिए 0 जोड़ें (यानी myArray अंक सरणी के पहले तत्व को इंगित करें) और n nth प्राप्त करने के लिए।

यदि मैं एक बार में एक बाइट ले जाना चाहता हूं तो क्या होगा?

sizeof(char) आकार में एक बाइट होने की गारंटी है, तो आप एक char* उपयोग कर सकते हैं यदि आप वास्तव में एक समय में एक बाइट ले जाना चाहते हैं।

संबंधित मुद्दे