1.3
— Variables, initialization, और assignment पर एक नज़र
Variables
एक statement जैसे x = 5; देखने में काफी सीधा लगता है । आप देखकर बता सकते हो की किसी variable
x को इसके value के रूप में 5 assign किया जा रहा है । लेकिन असल में x क्या है ? x एक variable है ।
C++ में variable memory के एक छोटे से भाग
को कहते हैं जिसका इस्तेमाल programs information store करने के लिए करते हैं । आप variable को एक मेलबोक्स (letterbox) की तरह समझ सकते हैं, जहां आप information डाल सकते हो और उसे पुनः प्राप्त कर सकते हो । सभी computers
में memory होता है, जिसे हम RAM
(random access memory) के नाम से जानते
हैं । RAM programs के इस्तेमाल के लिए
होता है । जब किसी variable को define किया जाता है, memory का एक छोटा सा भाग उस variable के लिए RAM में सुरक्षित कर लिया जाता है ।
इस section में, हम केवल integer variables के बारे में जानेंगे । एक integer एक पूर्ण संख्या (whole number) होता है, जैसे 1,2,3,-1,-12
या 16 । एक integer variable ऐसा variable है जो केवल integer values store कर सकता है ।
एक variable define करने के लिए हम एक declaration
statement का इस्तेमाल करते हैं । यहाँ किसी variable
x को एक integer
variable (variable जो केवल whole
numbers अर्थात पूर्ण संख्या store कर सकता है) के रूप में define करने का उदाहरण दिया जा रहा है :
|
1
|
int x;
|
जब CPU द्वारा इस statement
का execution
होता है, RAM में memory का एक छोटा सा भाग x के लिए सुरक्षित कर लिया जाता है (जिसे instantiation कहा जाता है) । उदाहरण के लिए, चलिए मान लेते हैं की variable x के लिए memory location 140 को सुरक्षित किया गया है । अब जब भी program को variable x मिलेगा, इसे पता होगा की variable x का value प्राप्त करने के
लिए इसे RAM के memory
location 140 में देखना होगा ।
Variables
के साथ किया जाने वाला एक सबसे साधारण
काम assignment है । Assignment
के लिए हमे assignment
operator की ज़रूरत पड़ती है, आम तौर पर जिसे = symbol से पहचाना जाता है । उदाहरण के लिए :
|
1
|
x = 5;
|
जब CPU इस statement
को execute करता है, ये computer को memory location 140 पर value 5 को store करने की आज्ञा देता
है । बाद में std::cout की मदद से हम इस value को screen पर print कर सकते हैं ।
|
1
|
std::cout << x; // variable x (memory
location 140) के value को console पर print करेगा ।
|
l-values और r-values
C++ में, variables l-value (उच्चारण: एल
वैल्यू) type के होते हैं । l-value एक ऐसा value है जिसका कोई निश्चित memory address होता है । सभी variables का एक address होता है, इसलिए सभी variables
l-values हैं । l-value का नाम l-value इसलिए पड़ा क्यूंकि केवल यही (l-values) किसी assignment statement की बायीं ओर रह
सकते हैं । जब हम कोई assignment करते हैं तो assignment operator के बायीं ओर का भाग एक l-value होना चाहिए । इसलिए, statement जैसे 5 = 6; compile errors प्रदान करेंगे क्यूंकि 5 l-value नहीं है । Value 5 का कोई memory address नहीं है, इसलिए इसपर कुछ assign नहीं किया जा सकता । 5 का मतलब 5 है, ना ही 5 का मान बदल सकता है, और क्यूंकि ये कोई variable नहीं है, इसका कोई memory
address भी नहीं होगा । इसलिए 5 को कभी भी किसी दुसरे value से नहीं बदला जा सकता । जब किसी l-value में कोई value assign किया जाता है, तो ये value उस memory address में पहले से मौजूद
किसी value को overwrite
कर देता है । एक उदाहरण के लिए, मान लीजिये आपने कोई value x define किया है । जब आप x को कोई value जैसे की 5, assign करोगे तो x के memory
address पे जो कुछ भी पहले से था, वो delete होकर नया value 5
store कर लिया जायेगा ।
l-values का उल्टा r-value होता है (उच्चारण: आर वैल्यू) । r-values ऐसे values हैं जो किसी l-value पे assign किये जा सके । r-values हमेशा evaluate होकर एक single value देते हैं । उदाहरण के लिए, 2 + 3 एक r-value है । यदि ये evaluate होगा तो केवल एक ही value, 5 मिलेगा । Single numbers (जैसे की 5, जो evaluate होने पर 5 ही देगा),
variables (जैसे की x, जो evaluate होकर वो value देगा, जो आखरी बार इसे assign किया गया था) या expressions (जैसे की 2 + x, जो evaluate होकर x + 2 का value प्रदान करेंगे) r-values के उदाहरण हैं ।
यहाँ कुछ examples दिए जा रहें हैं, जो r-values के evaluation
के तरीके को दर्शाते हैं:
|
1
2
3
4
5
6
7
8
|
int y; // y
को एक integer
variable के रूप में define किया गया
y = 4; // 4
evaluate होकर 4 देता है, जो फिर y को assign कर दिया जाता है
y = 2 + 5; // 2 + 5 evaluate होकर 7 देता है, जो फिर y को assign कर दिया जाता है
int x; // x
को एक integer
variable के रूप में define किया गया
x = y; // y
evaluate होकर 7 देता है (y पर आखरी assignment), जो फिर x को assign कर दिया जाता है
x = x; // x
evaluate होकर 7 देता है, जो फिर x को assign कर दिया जाता है
(बेकार!)
x = x + 1; // x + 1 evaluate होकर 8 देता है, जो फिर x को assign कर दिया जाता है
|
चलिए आखरी assignment statement को ज़रा करीब से देखते हैं, क्यूंकि सबसे ज्यादा confusions इसी तरह के statements में आते हैं ।
|
1
|
x = x + 1;
|
इस statement में,
variable x का इस्तेमाल दो तरह से हुआ है । Assignment
operator के बायीं ओर “x” एक l-value (variable जिसका memory
address है) की तरह use किया गया है वहिं इसके दायीं ओर, x एक r-value की तरह use किया गया है जो उपरोक्त example में evaluate होकर 7 देगा । C++ इस statement को कुछ इस तरह से evaluate करेगा:
|
1
|
x = 7 + 1;
|
जो ये साफ़ दर्शाता है की C++ variable x को 8 assign करने वाला है ।
programmers
l-values और r-values के बारे में ज्यादा चर्चा नहीं करते, इसलिए इन नामों को याद रखना ज़रूरी नहीं है । यहाँ ध्यान बस इस बात पर
देना है की assignment statement में बायीं ओर कुछ
ऐसा होना चाहिए जिसका कोई memory address हो (जैसे की एक variable) । दायीं ओर की सभी चीजें कोई एक single
value देने के लिए evaluate होंगी ।
Initialization
vs assignment
C++ में दो ऐसे concepts हैं, जिसे अक्सर नए programmers
एक ही समझ बैठते हैं: Assignment
और Initialization
जब कोई variable define किया जाता है, उसे assignment operator (=) की सहायता से कोई value assign किया जा सकता है:
|
1
2
|
int x; // यहाँ variable x को define किया गया
x = 5; // यहाँ variable x को value 5 assign किया गया
|
C++ आपको एक ही statement में किसी variable को define और उसे कोई value
assign करने की छुट देता है, इस क्रिया को initialization कहा जाता है ।
|
1
|
int x = 5; // variable x को value 5 के साथ initialize
किया गया
|
किसी variable को तभी initialize
किया जा सकता है जब उसे define कर रहें हो ।
यद्दपि ये दोनों concepts लगभग एक ही हैं और अक्सर एक जैसा ही काम करते हैं, हम आने वाले sections में कुछ ऐसे cases देखेंगे जहाँ कुछ variables केवल initialize किये जा सकते हैं, या C++ उनपर assignment
की अनुमति नहीं देता । इसी कारण से, इन दोनों concepts के बीच फर्क जान लेना ज़रूरी है ।
Uninitialized
variables
कुछ programming languages से अलग, C/C++ अपने आप किसी variable को किसी निश्चित value (जैसे की 0) के साथ initialize
नहीं करता (performance
को बेहतर बनाये रखने के लिए) । इसलिए, जब compiler के द्वारा किसी variable के लिए memory location सेट किया जाता हैं, तो variable का default
value वो बन जाता है जो पहले से उस location में कचड़े की तरह पड़ा था! एक variable जिसे कोई value assign नहीं किया गया हो, वो एक uninitialized variable कहलाता है ।
Note: कुछ compilers, जैसे की Visual
Studio, memory में स्थित सामग्री को खुद-ब-खुद initialize
कर देंगे यदि आपने development
के लिए debug
build configuration सेट किया हुआ है । Release
build configuration में ऐसा कुछ नहीं
होता ।
Uninitialized
variables अजीबो-गरीब results दे सकते हैं । यहाँ “अजीबो-गरीब results” कहने का मतलब ऐसे program results हैं, जिसकी आप कल्पना भी नहीं कर सकते ।
नीचे के program पर नज़र डालें:
|
1
2
3
4
5
6
7
8
9
10
|
int main()
{
// एक integer variable x declare किया गया
int x;
// अब x का value
print किया जा रहा है (ये खतरनाक है, क्यूंकि x uninitialized है)
std::cout << x;
return 0;
}
|
यहाँ, computer variable x को कोई ऐसा memory assign करेगा जो अब तक कोई value store करने के लिए use नहीं किया गया है । फिर ये इस memory में स्थित value को cout के पास भेजेगा, जिसका काम value को print करना है । लेकिन cout आखिर क्या print करेगा ? इसका जवाब किसी को
भी नहीं पता । आप जब इस program को run करोगे तो हो सकता
है की print किया जाने वाला value हर program run के साथ बदलता जाता
है । जब Alex (learncpp को बनाने वाले) ने Visual
Studio 2013 compiler के साथ इस program को run किया, तो results कुछ इस प्रकार थे:
पहले बार में 7177728 और उसके अगले बार 5277592 ।
यदि आप इस program को खुद भी run करना चाहते हैं, तो इन बातों का ध्यान रखें:
- पक्का कर लें की आप release build
configuration का ही इस्तेमाल कर रहे हैं
। (इसपर इनफार्मेशन के लिए देखें section 0.6a -- Build configurations) । ऐसा ना होने पर ये program वो value
print करेगा जिस value के साथ आपके compiler ने variable
को initialize किया है । Visual studio में अकसर ये 858993460 होता है ।
- यदि आपका compiler आपको ये program run नहीं करने दे रहा, बल्कि variable x को एक uninitialized variable बता रहा है, to इस solution
को आजमाकर देखें:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// #include "stdafx.h" // Uncomment करें यदि आप Visual Studio user हैं
#include <iostream>
void doNothing(const int &x)
{
}
int main()
{
//
एक integer
variable x declare किया गया
int
x;
//
compiler को ऐसा बताया जा रहा है की variable
x का इस्तेमाल पहले हुआ है
doNothing(x);
//
अब x का value print किया जा रहा है
(ये खतरनाक है, क्यूंकि x
uninitialized है)
std::cout
<< x;
}
|
Uninitialized
variables का इस्तेमाल करना नए programmers
द्वारा की जाने वाली सबसे बड़ी गलतियों
में से एक है । दुर्भाग्यवश, इसी गलती program को debug करते वक़्त खोजने
में भी सबसे अधिक समय लग सकता है (क्यूंकि यदि uninitialized
variable को किसी memory
spot पे कोई सही value, जैसे की 0 मिल गया, तो आपको ऐसा ही लगेगा की program में कोई खराबी नहीं है)
यहाँ एक अच्छी बात भी है की आजकल के ज्यादातर compilers,
uninitialized variable को print करने के लिए लिखे गए statement की जगह पर warning दे सकते हैं यदि किसी variable का इस्तेमाल बिना assignment के हुआ है । उदाहरण के लिए, ऊपर दिए गए program को compile करते वक़्त Visual
Studio 2005 express ये warning देता है:
c:vc2005projectstesttesttest.cpp(11) : warning C4700:
uninitialized local variable 'x' used
Variables
को definition
के साथ ही initialize
कर देना एक अच्छी आदत है । ये
सुनिश्चित करता है की program में इस्तेमाल किये जा रहे हर एक variable का एक सही value है । ये program को debug करना भी आसान बना
देता है यदि program में किसी और जगह
आपने कोई गलती की है तो ।
Rule: अपने variables को initialize ज़रूर करें ।
Quiz
दिए गए programs क्या-क्या print करेंगे ?
दिए गए programs क्या-क्या print करेंगे ?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
int x = 5;
x = x - 2;
std::cout << x << std::endl; // #1
int y = x;
std::cout << y << std::endl; // #2
// x + y is an r-value in this context, so
evaluate their values
std::cout << x + y << std::endl;
// #3
std::cout << x << std::endl; // #4
int z;
std::cout << z << std::endl; // #5
|

No comments:
Post a Comment