मैं memcpy को बेहतर ढंग से समझने की कोशिश कर रहा हूँ। यहां एक उदाहरण दिया गया है जिसके साथ मैं प्रयोग कर रहा था:

int arr[] = {10, 20, 30, 40};
int dest[] = {1, 2, 3, 4};

void *ptr = &dest;

printf("Before copy: %d, %d, %d, %d\n", *(int*)ptr, *(int*)ptr + 1, *(int*)ptr + 2, *(int*)ptr + 3);

memcpy(dest, arr, 3*sizeof(int));

printf("After copy: %d, %d, %d, %d\n", dest[0], dest[1], dest[2], dest[3]);
printf("After copy: %d, %d, %d, %d\n", *(int*)ptr, *(int*)ptr + 1, *(int*)ptr + 2, *(int*)ptr + 3);

मुझे पिछले दो प्रिंट स्टेटमेंट से अलग परिणाम कैसे मिल रहे हैं? पहला वाला मेरी अपेक्षा के अनुरूप व्यवहार करता है, लेकिन दूसरा नहीं करता है।

0
Maydayfluffy 4 अक्टूबर 2018, 16:21

2 जवाब

सबसे बढ़िया उत्तर

आप पहले printf से केवल इसलिए भ्रमित हो रहे हैं क्योंकि dest को लगातार पूर्णांकों के साथ प्रारंभ किया गया है। प्रयत्न

int dest[] = { 4, 72, 0, -5 };

बजाय।

आपकी वास्तविक समस्या ऑपरेटर प्राथमिकता है: *a + b पार्स (*a) + b के रूप में, *(a + b) नहीं (बाद वाला a[b] के बराबर है)।


वैसे, मुझे यकीन नहीं हो रहा है

void *ptr = &dest;
*(int *)ptr

कानूनी ही। मानक कहता है कि किसी भी (ऑब्जेक्ट) पॉइंटर को void * में बदला जा सकता है और बिना किसी जानकारी के वापस किया जा सकता है, लेकिन यहां आप टाइप ए से void * टाइप बी (जहां ए! = बी) में कनवर्ट कर रहे हैं।

विशेष रूप से: &dest का प्रकार int (*)[4] है (4 इंच की सरणी का सूचक), int * नहीं। इसे ठीक करने के लिए, करें

void *ptr = dest;

बजाय। या सिर्फ int *ptr = dest;, तो आपको कास्ट करने की भी जरूरत नहीं है।

4
melpomene 4 अक्टूबर 2018, 16:25

जब आप मान प्रिंट करते हैं:

printf("Before copy: %d, %d, %d, %d\n", *(int*)ptr, *(int*)ptr + 1, *(int*)ptr + 2, *(int*)ptr + 3);

आप जो सोचते हैं उसे प्रिंट नहीं कर रहे हैं। व्यंजक *(int*)ptr + 1 ptr लेता है, इसे एक int * में बदल देता है, फिर उस सूचक को निष्क्रिय कर देता है, जो आपको पहले तत्व का मान देता है, फिर उस तत्व के मान में 1 जोड़ देता है। यह पॉइंटर वैल्यू में नहीं जुड़ता है क्योंकि डिरेफरेंस ऑपरेटर * को एडिशन ऑपरेटर + की तुलना में उच्च प्राथमिकता है।

मनचाहा व्यवहार पाने के लिए आपको कोष्ठक जोड़ना होगा:

printf("Before copy: %d, %d, %d, %d\n", *(int *)ptr, *((int *)ptr + 1), *((int *)ptr + 2), *((int *)ptr + 3));
1
dbush 4 अक्टूबर 2018, 16:26