Theory
जो राज़ arrays ने पूरे unit रखा
छोटे-छोटे रहस्य जमा हो गए हैं। scanf("%s", name) को कोई & नहीं चाहिए था। पिछले lesson के reveal ने *(p + 2) को बिलकुल marks[2] जैसा बर्ताव करते दिखाया।
अब कबूलनामे का वक़्त:
Array का नाम values रखने वाला variable नहीं है। वह box zero का ADDRESS है।
marks और &marks[0] एक ही चीज़ हैं। एक बार यह दिख जाए, तो indexing, pointer walking और C के design का आधा हिस्सा एक तस्वीर में आ जाते हैं।
Theory
Coach का नाम ही उसकी जगह है
किसी ticket checker से "coach S4" कहिए और वह 60 berths की तस्वीर नहीं बनाता; वह यह सोचता है कि coach कहाँ से शुरू होता है। वहाँ से, "berth 23" एक तय चाल है। Array का नाम वैसे ही काम करता है: marks शुरुआती address को नाम देता है, और marks[23] का मतलब है "वहाँ से शुरू करो, 23 boxes चलो, box खोलो"। नाम box zero पर गड़ा एक signpost है, और signposts हिलते नहीं।
Theory
एकीकरण, औपचारिक रूप से
int marks[5] = {70, 55, 90, 62, 78};
int *p = marks; /* no & needed: marks IS an address */
C, indexing को pointer arithmetic के रूप में परिभाषित करता है:
*marks[i] ≡ (marks + i)**
तो ये सभी एक ही box उठाते हैं: marks[2], *(marks + 2), *(p + 2), p[2], हाँ, p[2] भी: indexing किसी भी pointer पर काम करती है।
एक फ़र्क़ जो बचता है: p एक variable है (p++ legal, वह चल सकता है), जबकि marks एक constant address है (marks++ एक compile error है, signposts हिलते नहीं)।
Practical
चलते pointer से class का जोड़
#include <stdio.h>
int main() {
int marks[5] = {70, 55, 90, 62, 78};
int *p = marks;
int i, total = 0;
for (i = 0; i < 5; i++) {
total += *p; /* read the box */
p++; /* next box */
}
printf("Total: %d\n", total);
return 0;
}This example runs in Gri-Learn on the web, where you can edit it and see the output.
Quiz
int *p = marks; में marks से पहले & के बिना यह compile क्यों होता है?
- array का नाम पहले से अपने पहले element के address के बराबर होता है
- compiler arrays के लिए चुपचाप & डाल देता है
- यह दरअसल एक error है जिसे compilers सह लेते हैं
- arrays के pointers को कभी initialization नहीं चाहिए
Show the answer
array का नाम पहले से अपने पहले element के address के बराबर होता है
marks ही &marks[0] है: परिभाषा से एक address, इसलिए यह सीधे एक pointer में assign हो जाता है। कुछ डाला या माफ़ नहीं किया जाता। यही तथ्य पुराने scanf रहस्य को सुलझाता है: scanf("%s", name) काम करता है क्योंकि name पहले से एक address थमा देता है, जबकि scanf("%d", &marks) को & चाहिए क्योंकि एक सादा int variable नहीं देता।
Think first
चार वर्तनियाँ, एक box
int marks[5] = {70, 55, 90, 62, 78}; और int p = marks; के साथ, दिमाग़ में निकालिए: marks[3], (marks + 3), *(p + 3), p[3]। फिर पेचीदा हिस्सा: marks++ और p++ में से कौन सा legal है?
Show the answer
चारों 62 उठाते हैं: वे चार भेस में एक ही expression हैं, क्योंकि indexing ही *(base + offset) है।
p++ legal है (एक pointer variable चलता है); marks++ एक compile error है (array का नाम एक constant address है, गड़ा हुआ signpost)। वह legal/illegal जोड़ी array नाम और pointer के बीच सबसे ज़्यादा quote किया जाने वाला फ़र्क़ है, और एक गारंटीड exam line।
Quiz
चलते-pointer वाले code में, loop की तीसरी iteration पूरी होने के बाद (तीन p++ हो चुके), *p क्या देता है?
- 62, p अब marks[3] को point करता है
- 90, p marks[2] पर रुका रहता है
- 70, p हर round शुरुआत पर लौट आता है
- Garbage: p array छोड़ चुका
Show the answer
62, p अब marks[3] को point करता है
हर p++ pointer को एक box आगे गाड़ देता है: तीन increments के बाद p, marks[3] पर खड़ा है, 62 रखते हुए। वह array सिर्फ पाँचवें increment के बाद छोड़ता है, जब loop पहले ही रुक चुका होता है। एक चलते pointer की position को round-दर-round track करना इस topic का मानक trace सवाल है।
Watch out
Marks कहाँ कटते हैं
जवाब में marks++: तुरंत error, नाम constant है; एक अलग pointer से चलिए। sizeof की उलझन: sizeof(marks) पूरा array है (यहाँ 20 bytes); sizeof(p) सिर्फ pointer का अपना size है, वे अलग होते हैं भले ही marks और p "एक ही जगह point करते" हों। अंत के आगे चलना: loop की सीमा p की रखवाली करती है; p++ की गिनती भूलिए और आप out of bounds हैं, चुपचाप।
Theory
Unit 3 बंद होता है, और एक दरवाज़ा खुलता है
Arrays और pointers अब आपके दिमाग़ में एक ही subject हैं, ठीक जैसा C चाहता है। और Unit 4 का एक वादा, अगला: चूँकि array किसी function तक एक ADDRESS के रूप में पहुँचता है, functions आपके असली data को बदल सकते हैं, यही pass-by-reference की पूरी कहानी है। पर पहले: function असल में है क्या, और marks program उनमें बँटने के लिए क्यों तरस रहा है।
Summary
Key takeaways
- Array का नाम ही element zero का address है: marks ≡ &marks[0]।
- Indexing pointer arithmetic है: marks[i] ≡ *(marks + i); p[i] भी चलता है।
- int *p = marks; को & नहीं चाहिए, और p, p++ से array पर चल सकता है।
- marks++ गैर-कानूनी है (constant address); p++ legal है (variable)।
- sizeof(marks) = पूरा array; sizeof(p) = एक pointer।
- scanf("%s", name) समझ आया: name पहले से एक address है।
- याद रखने का hook: नाम box zero पर एक signpost है, और signposts हिलते नहीं।