Friday, June 19, 2009

27.. सीखिए सी : फंक्शन - सामान्य परिचय

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

एक उदाहरण लेते हैं, रोटी बनाने का उदाहरण। नरम-गरम, सुस्वादु रोटी बनाना एक अत्यंत मुश्किल काम है। पर यदि हम उसके बनने की प्रक्रिया को छोटे-छोटे चरणों में बांटकर देखें तो वह बहुत ही सरल प्रतीत होगी – रोटी बनाने के चरण ये होते हैं, –

1. बाजार से गेहूं लाना।
2. गेंहूं से कंकड़-कचरा बीनना।
3. गेंहूं को चक्की में ले जाकर पिसवाना।
4. आटे को गूंथना।
5. रोटी बेलना।
6. बेली हुई रोटी को तवे पर सेंकना।
7. तवे पर सिंकी रोटी को आंच पर फुलाना।
8. तैयार रोटी पर घी मलना।

यद्यपि शुरू में रोटी बनाने का काम अत्यंत जटिल प्रतीत होता है, लेकिन ऊपर इसके जो आठ चरण बताए गए हैं, उनमें से प्रत्येक इतना सरल है कि कोई भी उसे आसानी से बिना घबराहट के कर सकता है। और इन सब घटकों को व्यस्थिति रीति से सही क्रम में करने का नतीजा होता है, तैयार रोटी।

यही अभिगम सी प्रोग्रामिंग में भी अपनाया जाता है। किसी भी समस्या को अधिक सरल छोटी समस्याओं में तोड़ा जाता है, और फिर प्रत्येक छोटी समस्या के लिए कोड लिखा जाता है। फिर इन कोडों को समायोजित किया जाता है, जिससे मूल समस्या का हल प्राप्त हो जाता है।

इस प्रक्रिया को अंजाम देने में हमें सी की फंक्शन नामक संरचना मदद करती है। फंक्शन वास्तव में एक छोटा सी प्रोग्राम ही होता है। प्रत्येक फंक्शन मूल समस्या के किसी एक छोटे पहलू का ही समाधान कर सकता है। पर कई फंक्शन मिलकर पूरी समस्या का हल कर डालते हैं।

हर सी प्रोग्राम में एक मूल फंक्शन होता है जो अन्य सभी फंक्शनों को समायोजित करता है और उन्हें यथा समय और यथा स्थान बुलाता है और उनसे आवश्यक काम करा लेता है। इस मूल फंक्शन को main फंक्शन कहा जाता है। आप इस फंक्शन से परिचित हैं, क्योंकि अब तक हमने जितने भी प्रोग्राम लिखे हैं उन सबमें वह विद्यामान रहा है। सच तो यह है कि सी के सभी प्रोग्राम में वह अनिवार्य रूप से रहता है।

आइए, इन सब बातों को हम वास्तविक कोड का उदाहरण लेकर समझते हैं। हम ऐसा एक प्रोग्राम लिखेंगे, जो दो संख्याओं को जोड़कर उनका योगफल हमें बताएगा।

पहले हम फंक्शनों का प्रयोग बिना किए यह प्रोग्राम लिखेंगे।

प्रोग्राम – 25
---------------------------------
/*function ka udaharan - 1*/

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

void main()
{
int a, b, c;
clrscr();
printf("\nDo sankhyaein darj kijiye: ");
scanf("%d%d", &a, &b);
printf("\n%d aur %d", a,b);
flushall();
c=a+b;
printf("\nAapne jo sandhyaein darj kien, unka yogphal hai, %d", c);

getchar();
}
---------------------------------

आउटपुट
---------------------------------
Do sankhyaein darj kijiye: 4 5
Aapne jo sandhyaein darj kien, unka yogphal hai, 9
---------------------------------

यह सीधा सा प्रोग्राम है जो दो संख्याओं का योगफल देता है। इसमें हमने फंक्शन का प्रयोग नहीं किया है। आइए देखें इस प्रोग्राम में हम फंक्शन का प्रयोग कैसे कर सकते हैं।

इस प्रोग्राम में एक ही मुख्य समस्या है, दो संख्याओं का योगफल प्राप्त करना। इसलिए हम इसी के लिए फंक्शन लिखेंगे। जो इस प्रकार होगा –

int yogphal (int a, int b)
{
int c;
c=a+b;
return c;
}

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

हर फंक्शन का एक नाम होना आवश्यक है। फंक्शन के नामकरण पर भी वे सभी नियम लागू होते हैं, जो किसी सी राशि के नामकरण पर लागू होते हैं। इन्हें जानने के लिए उस पिछले लेख को देख आएं, जिसमें इस विषय को विस्तार से समझाया गया था। हमने अपने इस फंक्शन का नाम yogphal रखा है। फंक्शनों को नाम देते समय भी ऐसा नाम देना चाहिए, जो उस फंक्शन द्वारा किए जानेवाले कार्य को सूचित करे। इससे जटिल और लंबें प्रोग्रामों में, जिनमें बीसियों फंक्शन हो सकते हैं, यह समझना आसान हो जाएगा कि कोई फंक्शन क्या करता है।

हर फंक्शन का एक टाइप (प्रकार) होता है, अर्थात वह किसी एक प्रकार की राशि को return करता है, यानी वापस भेजता है। यह टाइप सी की राशियों के विभिन्न टाइपों में से कोई हो सकता है, मसलन, int, char, float, long, इत्यादि। इनके अलावा यह टाइप अधिक जटिल प्रोयक्ता-परिभाषित टाइप भी हो सकता है, जैसे सरणी (array),struct, union, आदि। इनके बारे में हमने अभी सीखा नहीं है, आगे सीखेंगे।

फंक्शन के टाइप यानी प्रकार को दर्शाने के लिए उसके नाम से पहले उस टाइप के लिए जो कुंजी शब्द हो, उसे लिख दिया जाता है। हमारा उपर्युक्त फंक्शन दो int राशियों को जोड़ता है, जिससे योगफल के रूप में एक int राशि ही प्राप्त होती है, जिसे ही यह फंक्शन लौटा है। इसलिए हमारे उपर्युक्त फंक्शन का टाइप int है। इसलिए हम लिखेंगे –

int yogphal

फंक्शन किन्हीं राशियों पर कुछ कार्य करता है। ये राशियां उसे बुलानेवाला दूसरा फंक्शन उसे देता है। फंक्शन को कोई राशि देने की रीति होती है उन्हें फंक्शन के गोल कोष्ठकों में रखना। फंक्शन के गोल कोष्टकों में राशियों को रखते समय उनका प्रकार स्पष्ट करना आवश्यक है। हमारे उदाहरण में, yogphal फंक्शन दो int प्रकार की संख्याओं को जोड़ता है। इसलिए उसे दो int प्रकार की राशियां दी जाएंगी। इसलिए उसे ये राशियां देने की विधि यह होगी –

int yogphal (int a, int b)

इस पंक्ति में आया प्रथम शब्द int फंक्शन के प्रकार को सूचित करता है। yogphal फंक्शन का नाम है। और उसके गोल कोष्ठक में जो दो int प्रकार की राशियां, वे उसे बुलाने वाले फंक्शन ने उसे दी है।

इसके बाद आते हैं धनु कोष्ठक, जिनके अंदर फंक्शन के कोड की उक्तियां रहती हैं। हमारे फंक्शन में ये उक्तियां हैं –

int c;
c=a+b;
return c;

अब पूरे फंक्शन का हुलिया एक बार फिर देख लीजिए –

int yogphal (int a, int b)
{
int c;
c=a+b;
return c;
}

आप सोच रहे होंगे, कि यह फंक्शन काम कैसे करता होगा। हर फंक्शन तभी काम करेगा जब कोई अन्य फंक्शन, जिसमें main भी शामिल है, उसे बुलाए, और उसे आवश्यक राशियां प्रदान करे। फंक्शन के हमारे इस उदाहरण में यह काम main करेगा, इस तरह –

void main()
{
int a, b, c;
clrscr();
printf("\nDo sankhyaein darj kijiye: ");
scanf("%d%d", &a, &b);
flushall();
c=yogphal (a,b);
printf("\nAapne jo sandhyaein darj kien, unka yogphal hai, %d", c);

getchar();
}

यह पहले वाला ही प्रोग्राम है, केवल एक अंतर है। इसमें दोनों संख्याओं को जोड़ने वाला व्यंजक नहीं है, उसके स्थान पर यह पंक्ति है –

c=yogphal(a, b);

इसी पंक्ति में yogphal फंक्शन का आह्वान किया गया है। आह्वान करने की रीति यह है – फंक्शन का नाम लिखकर उसके गोल गोष्ठकों में उन राशियों को रखना जिन्हें हम उस फंक्शन को उपलब्ध कराना चाहते हैं। इस बार इन राशियों का प्रकार सूचक शब्द (int, char, आदि) लिखने की जरूरत नहीं है, क्यों इन राशियों को घोषित करते समय हमने उनका प्रकार भी प्रोग्राम को बता दिया है, जिसे कंप्यूटर याद रखता है।

आपने ध्यान दिया होगा कि फंक्शन का आह्वान करते समय, उसे एक अन्य राशि c के साथ = चिह्न द्वारा जोड़ा गया है, यानी यह फंक्शन एक तरह से c में कोई मान आरोपित कर रहा है, उसी तरह जैसे इस व्यंजक में –

c=5;

फंक्शन कोई न कोई मान वापस लौटाता है। हमारा yogphal फंक्शन भी एक मान लौटाता है। यदि आप yogphal फंक्शन को जांचें, तो आपको उसकी अंतिम पंक्ति के रूप में यह उक्ति नजर आएगी –

return c;

return सी भाषा का एक कुंजी शब्द है, जिसे हर उस फंक्शन के अंतिम पंक्ति के रूप में रहना चाहिए जो कोई मान लौटाता है। इस कुंजी शब्द के आगे वह राशि रखी जाती है, जिसे वह फंक्शन उसे बुलानेवाले फंक्शन को लौटाता है। हमारे उदाहरण में यह राशि c है, जिसमें a और b संख्याओं का योगफल है।

main प्रोग्राम की c राशि yogphal फंक्शन द्वारा लौटाई गई इस राशि को प्राप्त करती है।

इस पंक्ति के बाद main प्रोग्राम में c का मान वही होगा जो yogphal फंक्शन ने उसे दिया है।

इसका प्रमाण है, main फंक्शन की यह पंक्ति जो c के मान को कंप्यूटर स्क्रीन पर छापती है –

printf("\nAapne jo sandhyaein darj kien, unka yogphal hai, %d", c);

कंप्यूटर स्क्रीन में c की जगह a और b का योगफल छपता है।

यह रहा पूरे प्रोग्राम का कोड।

प्रोग्राम – 26
---------------------------------
/*function ka udaharan - 2*/

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

int yogphal (int a, int b)
{
int c;
c=a+b;
return c;
}

void main()
{
int a, b, c;
clrscr();
printf("\nDo sankhyaein darj kijiye: ");
scanf("%d%d", &a, &b);
flushall();
c=yogphal (a,b);
printf("\nAapne jo sandhyaein darj kien, unka yogphal hai, %d", c);

getchar();
}
---------------------------------

आउटपुट
---------------------------------
Do sankhyaein darj kijiye: 4 5
Aapne jo sandhyaein darj kien, unka yogphal hai, 9
---------------------------------

यह प्रोग्राम भी वही आउटपुट देता है, जो प्रोग्राम – 25 ने दिया था, पर इसके कोड में काफी अंतर है। इसमें संख्याओं को जोड़ने का काम main में नहीं किया गया है, बल्कि yogphal फंक्शन में किया गया है।

ध्यान दीजिए कि हमने फंक्शन yogphal के कोड को main के कोड से पहले रखा है। यह बहुत जरूरी है। अन्यथा कंप्यूटर को पता नहीं चल पाएगा कि yogphal फंक्शन जैसे किसी फंक्शन का अस्तिव है तथा उसमें घोषित राशियों के लिए (इस उदाहरण में int c) उसे कितनी स्मृति आरक्षित करनी है।

फंक्शन की अवधारणा प्रोग्रामन भाषाओं की एक अत्यंत महत्वपूर्ण अवधारणा है। इसलिए हम उसे विस्तार से अनेक लेखों में समझेंगे। इस लेख को हम यहीं समाप्त करते हैं।

यदि आप चाहें, तो इस लेख में दिए गए प्रोग्राम - 26 को इस तरह परिवर्तित करके देख सकते हैं कि वह योगफल की जगह दो संख्याओं का गुणनफल निकाल कर दे। इससे आपको फंक्शन लिखने का अभ्यास भी हो जाएगा।

Thursday, June 18, 2009

26. सीखिए सी : switch संरचना

पिछले एक लेख में हमने बताया था कि सी भाषा में विशाखन की मुख्य संरचना if...else वाली संरचना है। लेकिन जब बहुत सारे विकल्प हों, तो if...else संरचना अव्यवस्थित हो जाती है और उसे ठीक तरह से लिखना कठिन हो जाता है। आप अब तक समझ गए होंगे, कि जितने विकल्प होंगे, उतने ही else कथन भी होंगे, और इनमें से प्रत्येक में काफी मात्रा में कोड की पंक्तियां भी धनु कोष्ठकों में रह सकती हैं। इसलिए प्रोग्राम में if...else के कई कोड खंडों की भीड़-भाड़ हो जाती है और यह पता लगाना कठिन हो जाता है कि किसी कोड खंड का संबंध किस else उक्ति से है।

इसलिए सी में अधिक जटिल विशाखन को अंजाम देने के लिए एक अन्य संरचना भी है, जिसे switch संरचना कहते हैं। इसका रूप इस तरह होता है –

switch (sanket)
{
case 'saket का मान 1’ :
उक्तियां;
break;
case ‘sanket का मान 2’ :
उक्तियां;
break;
case ‘sanket का मान 3’ :
उक्तियां;
break;
.
.
.
.
case ‘sanket का मान n’ :
उक्तियां;
break;
default :
उक्तियां;
}

आप देख सकते हैं कि switch के धनु कोष्ठकों के भीतर अनेक case खंड है। प्रत्येक case खंड एक विकल्प का प्रतिनिधित्व करता है, यानी जितने विकल्प होंगे, उतने case खंड भी होंगे। इनके अलावा एक अंतिम विकल्प भी हो सकता है, जिसे default प्रतिनिधित्व करता है। जब कोई भी वांछित विकल्प न प्राप्त होने पर यदि कुछ कोड़ पंक्तियों का निष्पादन आवश्यक हो, तो इन्हें default के अंतर्गत रखा जा सकता है।

switch संरचना की शुरुआत इस पंक्ति से होती है।
switch (sanket)

यहां sanket सामान्यतः int या char प्रकार की कोई राशि होती है। इसे switch कथन से पहले घोषित किया जाता है और प्रोग्राम के दौरान यह कोई मान प्राप्त करता है, जिसे sanket का मान 1, sanket का मान 2, sanket का मान 3,.... sanket का मान n के रूप में ऊपर के उदाहरण में दर्शाया गया है।

इसके बाद switch कथन का कोड खंड आता है, जो धनु कोष्ठकों में घिरा रहता है। इन धनु कोष्ठकों के अंदर case शब्द के जरिए सभी विकल्पों और उनसे संबंधित कोड खंडों को रखा जाता है। जितने विकल्प होंगे, उतने case कथन तथा उसके कोड़ खंड भी होंगे। प्रत्येक कोड खंड की अंतिम उक्ति break उक्ति होगी। case कथन और उसके कोड खंड को लिखने की विधि यह है –

case ‘sanket का मान 1’ :
कोड खंड
break;

सबसे पहले case शब्द को लिखा जाता है। उसके बाद एकल उद्धरण चिह्नों में sanket राशि द्वारा प्राप्त किया जानेवाला कोई मान रखा जाता है।

उसके बाद कोलन (: ) होता है।

कोलन के बाद उस case से संबंधित कोड खंड रहता है। इस कोड खंड की अंतिम उक्ति break उक्ति होती है, ताकि वांछित विकल्प के कोड के निष्पादन के बाद प्रोग्राम switch संरचना से बाहर आ जाए।

switch में कई case खंड होते हैं, पर इन case खेडों में से प्रोग्राम के दौरान केवल एक case खंड का ही निष्पादन होता है।

मान लीजिए कि किसी प्रोग्राम में sanket के ये चार मान हो सकते हैं - a, b, c, d। तो switch संरचना इस तरह बनेगी –

switch (sanket)
{
case ‘a’ :
उक्तियां;
break;

case ‘b’ :
उक्तियां;
break;

case ‘c’ :
उक्तियां;
break;

case ‘d’ :
उक्तियां;
break;
}

और इस switch संरचना का निष्पादन इस तरह होगा –

मान लीजिए प्रोग्राम में sanket का मान c आता है। तब switch संरचना के case ‘a’ और case ‘b’ से संबंधित कोड खंडों का निष्पादन नहीं होगा। प्रोग्राम सीधे case ‘c’ के कोड खंड का निष्पादन करेगा। चूंकि case 'c' की अंतिम उक्ति break कथन है, इसलिए उसके निष्पादन से switch संरचना टूट जाएगी और case 'd' के कोड खंड का निष्पादन नहीं होगा। इसके बजाए प्रोग्राम switch संरचना के बाद वाली पंक्तियों का निषपादन करने लगेगा।

है न यह विशाखन को अंजाम देने के लिए if...else से बढ़िया तरीका?

आइए, एक उदाहरण के जरिए switch संरचना को समझते हैं। इस उदाहरण में हम एक कैलक्युलेटर का प्रोग्राम लिखेंगे। यह कैलक्युलेटर योग, व्यवकलन, गुणन और विभाजन, ये चार संक्रियाएं कर सकेगा। इस तरह हमारे प्रोग्राम की switch संरचना में चार विकल्प होंगे, यानी चार case खंड होंगे। प्रयोक्ता से पूछा जाएगा कि उसे कौन सी गणितीय संक्रिया करनी है। उसे + (योग के लिए), - (व्यवकलन के लिए), * (गुणन के लिए), और / (विभाजन के लिए) में से कोई एक चिह्न चुनकर अपनी पसंद जाहिर करनी होगी। उसके बाद उसे दो संख्याएं भी चुननी होंगी, जिन पर प्रयोक्ता द्वारा चुनी गई गणितीय संक्रिया लागू की जाएगी। तत्पशचात प्रोग्राम प्रयोक्ता से पूछेगा कि वह और भी कोई गणितीय संक्रिया करना चाहता है या नहीं? इसका उत्तर प्रयोक्ता को y (हां के लिए) या n (नहीं के लिए) दर्ज करना होगा। प्रोग्राम में एक do...while लूप भी है। दरअसल switch संरचना को इसी do...while लूप के भीतर रखा गया है। यह do...while लूप प्रयोक्ता द्वारा व्यक्त किए गए y या n के अनुसार या तो switch कथन को तोड़ देता है (प्रयोक्ता देवारा n चुने जान पर) या उसे दुहराता है (प्रयोक्ता द्वरा y चुने जाने पर।

प्रोग्राम – 24
---------------------------------
/*switch sanrachana ka udaharan - calculator program*/

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

void main()
{
float a,b,c;
char sanket, pasand;
clrscr();

do
{
printf("Ank ganitiya prachalak chuniye\n");
printf("+ yog ke liye\n");
printf("- vyavakalan ke liye\n");
printf("* gunan ke liye\n");
printf("/ vibhajan ke liye\n");
scanf("%c",&sanket);
flushall();
printf("\nDo sankhyaen darj kijiye\n");
scanf("%f %f",&a,&b);
flushall();

switch(sanket)
{
case '+': c=a+b;
printf("Inka yog hai, %f\n",c);
break;

case '-': c=a-b;
printf("Inka antar hai, %f\n",c);
break;

case '*': c=a*b;
printf("Inka gunanphal hai, %f\n",c);
break;

case '/': c=a/b;
printf("Inka vibhajanphal hai, %f\n",c);
break;
}

printf("\nKya aap aur ganit karna chahtehai?(y ya n)\n");
scanf("%c",&pasand);
flushall();
}while(pasand!='n');

}
---------------------------------

आउटपुट
---------------------------------
Ank ganitiya prachalak chuniye
+ yog ke liye
- vyavakalan ke liye
* gunan ke liye
/ vibhajan ke liye +
Do sankhyaen darj kijiye 4 5
Inka yog hai, 9.00000
Kya aap aur ganit karna chahtehai? y
Ank ganitiya prachalak chuniye
+ yog ke liye
- vyavakalan ke liye
* gunan ke liye
/ vibhajan ke liye *
Do sankhyaen darj kijiye 3 8
Inka yog hai, 24.00000
Kya aap aur ganit karna chahtehai?n
---------------------------------

इस प्रोग्राम में ध्यान देनेवाली बातें निम्नलिखित हैं –
1. a, b, c को float प्रकार की राशियों के रूप में घोषित किया गया है।
2. दूसरे scanf उक्ति के जरिए एक साथ दो राशियों का मान पकड़ा गया है, यानी प्रयोक्ता द्वारा दर्ज की गई दोनों संख्याओं को। आपने ऐसा पहले printf के साथ किया है, अब आपको मालूम हुआ यह कमाल scanf भी कर सकता है। ध्यान देने की बात यही है, कि scanf के कोष्ठकों में दुहरे उद्धरण चिह्नों के अंदर और अल्प विराम के बाद &चिह्न के साथ ये रेशियां सही क्रम में आएं तथा उद्धरण चिह्नों में उनके लिए सही सूचक प्रतीक लगाए जाएं, अर्थात, यदि राशि int प्रकार की हो, तो %d, यदि वह char प्रकार की हो तो %c, इत्यादि।
3. जैसा कि पहले समझाया गया है, प्रत्येक scanf के बाद flushall() का प्रयोग किया गया है ताकि वह प्रोयक्ता द्वारा दबाई गई ऐंटर कुंजी को इनपुट न मान ले।
4. switch कथन को do...while के भीतर रखा गया है।
5. do...while लूप तब तक चलता रहता है जब तक प्रयोक्ता pasand के लिए n नहीं दर्ज करता।

अब switch संरचना का उपयोग करते हुए कोई प्रोग्राम लिखिए। इससे आपको विशाखन की इस महत्वपूर्ण संरचना के कार्य करने की रीति और भी स्पष्ट हो जाएगी।

Saturday, May 23, 2009

25. सीखिए सी : continue, break और exit निर्देश

पिछले अध्याय में हमने while, do... while और for लूपों की चर्चा की और देखा कि किस प्रकार इन लूप संरचनाओं के उपयोग से हम प्रोग्राम की कुछ उक्तियों का निष्पादन बारबार करा सकते हैं। इन उक्तियों का आवर्तन तब तक चलता रहता है जब तक इनके गोल कोष्ठकों में विद्यमान तार्किक व्यंजक का मान 0 नहीं हो जाता।

लेकिन अनेक बार इन लूपों के तार्किक व्यंजक का मान 0 होने से पहले ही लूप से छूटना जरूरी होता है, क्योंकि तब तक प्रोग्राम का उद्देश्य सिद्ध हो चुका होता है, या उपयोगकर्ता प्रोग्राम से बाहर आना चाहता है। सी भाषा में इन स्थितियों से निपटने के लिए तीन निर्देश हैं, continue, break और exit।

इस तिकड़ी का सबसे नरम मिजाज वाला निर्देश continue निर्देश है। यदि किसी while वलय में प्रोग्राम नियंत्रण का सामना इस निर्देश से हो जाए, तो नियंत्रण तुरंत लूप के वर्तमान आवर्तन को त्यागकर लूप के तार्किक व्यंजक का पुनः परीक्षण करने चला जाता है, और यदि उसका मान 1 रहा तो वलय का एक नया आवर्तन आरंभ कर देता है।

break निर्देश continue से कुछ अधिक तेज-तर्रार है। किसी लूप वलय के भीतर इस निर्देश का सामना होने पर प्रोग्राम लूप तोड़ देता है, तथा लूप के बाद के निर्देशों का निष्पादन करने लगता है, भले ही लूप के तार्किक व्यंजक का मान अब भी 1 क्यों न हो।

तीसरा निर्देश exit है, जो सबसे अधिक उग्र स्वभाव का है, क्योंकि वह न केवल लूप को तोड़ देता है, बल्कि समस्त प्रोग्राम को ही खारिज कर देता है और आप वापस प्रचालन तंत्र में आ जाते हैं।

आइए इन लूप-भंजक तिकड़ियों का परिचय कुछ सरल प्रोग्रामों के माध्यम से प्राप्त करें।

प्रथम प्रोग्राम में 8 के 5 गुणजों का पता लगाया जाता है और जब पांच गुणज मिल जाते हैं, तब break निर्देश की सहायता से while लूप को तोड़ा जाता है।

प्रोग्राम – 21
---------------------------------
/*break nirdesh ka udaharan */

#include <stdio.h>
#include <conio.h>


void main()
{
clrscr();

int ganak=0;
int soochak=1;
while(1)
{
printf("%d ", 8*soochak);
soochak++;
ganak++;
if (ganak >= 5)
break;
}
getch();
}
---------------------------------

आउटपुट
---------------------------------
8 16 24 32 40
---------------------------------
इस प्रोग्राम में दो पूर्णांक राशियां घोषित की गई हैं, ganak और soochak। ganak को 0 और soochak को 1 का मान दिया गया है। while वलय के गोल कोष्ठकों में आप इस बार 1 संख्या देखकर कुछ हैरान हुए होंगे। यह 1 वहां इसलिए है क्योंकि हम वलय से निकलने के लिए while वलय के तार्किक व्यंजक के मान के 0 होने पर नहीं, बल्कि उसके धनु कोष्ठकों के भीतर छिपे break निर्देश पर निर्भर हैं। हम चाहते हैं कि while वलय तब तक चलता रहे जब तक यह break निर्देश उसे तोड़ न दे। इसके लिए हर स्थिति में while के कोष्ठकों का मान 1 होना जरूरी है। इसीलिए while के गोल कोष्ठकों में 1 रखा गया है।

while के भीतर पहली उक्ति printf() वाली है, जो 8 और soochak के वर्तमान मान के गुणनफल को स्क्रीन पर छापती है। ध्यान दें कि printf() के दुहरे उद्धरण चिह्नों के बाद %d के बाद एक रिक्त स्थान भी है, ताकि अगला अंक पहले अंक से बिलकुल सटकर न छपे और दोनों के बीच दूरी रहे। चूंकि प्रथम आवृत्ति पर soochak का मान 1 है, इसलिए स्क्रीन पर 8 और एक खाली जगह छपेगा।

इसके बाद दो इंक्रिमेंट निर्देश हैं जो क्रमशः soochak के मान को 2 और ganak के मान को 1 बना देते हैं। यह ganak ही वह राशि है, जो छपे हुए गुणजों की गिनती रखता है। इसके बाद if वाली उक्ति है, जो ganak के मान को 5 से तुलना करके देखता है, और उसके नीचे के break निर्देश का निष्पादन तभी होता है जब ganak का मान 5 से अधिक हो जाए।

अभी, चूंकि ganak का मान 1 है, जो 5 से कम है, if के निर्देशों का निष्पादन नहीं होता, और प्रोग्राम का नियंत्रण वापिस while उक्ति को लौट जाता है। यहां चूंकि कोष्ठकों में 1 है, नियंत्रण while की उक्तियों का निष्पादन करने लगता है और स्क्रीन पर 8 का अगला गुणज छपता है।

इस प्रकार पांच आवृत्तियां होती हैं, और तब if का तार्किक व्यंजक का मान 1 हो जाता है, क्योंकि अब ganak का मान 5 हो गया है। इसलिए ganak >= 5 व्यंजन का मान 1 हो जाता है और if की break वाली उक्ति का निष्पादन होता है। यह वलय को तोड़ देता है और नियंत्रण प्रोग्राम की अलगी उक्ति की ओर बढ़ता है, जो है return (0); वाली उक्ति। इसलिए प्रोग्राम का समापन हो जाता है।

इस उदाहरण में मामूली सा परिवर्तन करने पर वह exit निर्देश का एक अच्छा उदाहरण हो सकता है। इन परिवर्तनों के साथ उपर्युक्त प्रोग्राम नीचे दिया गया है। यहां break के स्थान पर exit (0) आया है।

प्रोग्राम – 22
---------------------------------
/*exit nirdesh ka udaharan */

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

void main()
{
clrscr();

int ganak=0;
int soochak=1;
while(1)
{
printf("%d ", 8*soochak);
soochak++;
ganak++;
if (ganak >= 5)
exit(0);
}

getch();
}
---------------------------------

आउटपुट
---------------------------------
8 16 24 32 49
---------------------------------

अब आइए इस परिवर्तित प्रोग्राम को दखें। जब ganak का मान 5 हो जाता है और if निर्देश के अंतर्गत आया exit (0) निर्देश के निष्पादन की नौबत आती है, तो वह तुरंत ही प्रोग्राम के नियंत्रण को प्रचालन तंत्र को, यानी डॉस को, लौटा देता है। exit (0); निर्देश के बाद कोई भी निर्देश रखना व्यर्थ है, क्योंकि इन निर्देशों का कभी निष्पादन नहीं होता। इस प्रोग्राम के अंत में जो getch() वाला निर्देश है, उसका इसी कारण निष्पादन नहीं होता। exit (0) के कारणउस तक पहुंचने से पहले ही प्रोग्राम का अंत हो जाता है।

एक और बात ध्यान देने लायक है। exit (0) stdlib का फंक्शन इसलिए उसका उपयोग करने के लिए हमें stdlib के हेडर फाइल को अपने प्रोग्राम में include करना होगा। इसीलिए इस प्रोग्राम के शुरू में यह पंक्ति है –

#include <stdlib.h>

अंतिम उदाहरण एक साथ इन तीनों निर्देशों का उदाहरण है, पर आप विशेष ध्यान continue निर्देश के कार्य पर दीजिए। continue निर्देश प्रोग्राम के उपयोगकर्ताओं को अनुचित सूचनाएं टंकित करने से रोकने में बहुत उपयोगी है। नीचे दिए गए इस अध्याय के अंतिम प्रोग्राम में हम चाहते हैं कि प्रोग्राम में उपयोगकर्ता केवल 1 या 0 में से कोई अंक ही ऐंटर करे। 1 while की उक्तियों के निष्पादन के लिए, और 0 प्रोग्राम से बाहर निकलने के लिए।

इस प्रोग्राम में while की उक्तियों में एक साधारण-सी printf() उक्ति है, पर उसके स्थान पर कोई लंबा-चौड़ा कोड या उप-प्रोग्राम भी हो सकता है। यहां हमारा उद्देश्य continue, आदि निर्देशों के कार्य करने की रीति को दर्शाना मात्र है। यदि उपयोगकर्ता 1 या 0 से अलग कोई कुंजी दबाता है, तो प्रोग्राम continue निर्देश की सहायता से उसे उसकी गलती की सूचना देता है, और दुबारा कोशिश करने को कहता है।

प्रोग्राम – 23
---------------------------------
/*continue, break aur exit nirdesh ka udaharan */

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

void main()
{
clrscr();

int vikalp;

printf("Kya aap aage badna chahte hai? 'Han' ke liye 1 aur 'na' ke liye 0 enter kijie: \n");
scanf("%d", &vikalp);
flushall();

while(1) {

if (vikalp != 1 && vikalp != 0)
{
printf("Aapne galat kunji dabai. Kripaya 1 ya 0 me se koi kunji dabaiye: \n");
scanf("%d", &vikalp);
continue;
}

if (vikalp == 1)
{
printf("Program me aapka swagat hai.\n");
break;
}

else if (vikalp == 0)
exit (0);
}
getch();
}
---------------------------------

आउटपुट
---------------------------------
Kya aap aage badna chahte hai? 'Han' ke liye 1 aur 'na' ke liye 0 enter kijie: 9
Aapne galat kunji dabai. Kripaya 1 ya 0 me se koi kunji dabaiye: 1
Program me aapka swagat hai.

Aapne galat kunji dabai. Kripaya 1 ya 0 me se koi kunji dabaiye: 0
(प्रोग्राम से आप बाहर आ जाते हैं।)

Aapne galat kunji dabai. Kripaya 1 ya 0 me se koi kunji dabaiye: 1
Program me aapka swagat hai.

Aapne galat kunji dabai. Kripaya 1 ya 0 me se koi kunji dabaiye:6
Aapne galat kunji dabai. Kripaya 1 ya 0 me se koi kunji dabaiye:
---------------------------------

इस प्रोग्राम में हमने प्रथम scanf() निर्देश के बाद flushall() का उपयोग किया है। यह इसलिए क्योंकि प्रोग्राम में आगे एक और scanf() कथन आता है, और यदि हम इनपुट स्ट्रीम को साफ न करें, उसमें रह गए ऐंटर कुंजी को दूसरा scanf() कथन पकड़ लेगा और उसे vikalp में रख देगा, जिससे हमारा प्रोग्राम ठीक से काम नहीं करेगा।

प्रथम if निर्देश के तार्किक व्यंजन पर भी ध्यान दें। वह है –

if (vikalp != 1 && vikalp != 0)

यहां दो तार्किक व्यंजक && (ऐंड अर्थात और) प्रचालक से जुड़े हुए हैं –

vikalp != 1
vikalp != 0

इसलिए इस तार्किक व्यंजक का मान तभी 1 बनेगा जब ये दोनों का मान 1 होगा। अन्य शब्दों में कहें, तो जब इनपुट 1 और 0 के अलावा कुछ होगा। जब ऐसा होता है, तो प्रोग्राम यह वाक्य प्रदर्शित करता है,

Aapne galat kunji dabai. Kripaya 1 ya 0 me se koi kunji dabaiye:

और इनपुट के लिए प्रतीक्षा करता है।

Monday, May 18, 2009

सीखिए सी - 24 : आवर्तन की संरचनाएं : for लूप

while और do... while लूपों में लूप के कोड़ खंड का कितनी बार आवर्तन होता है, यह निश्चित नहीं होता है। जब तक इनकी while उक्ति के गोल कोष्ठक में विद्यमान तार्किक व्यंजन का मान 1 होता है, कोड खंड का आवर्तन होता रहता है।

कई बार हमें इसकी आवश्यकता रहती है कि कोड खंड का आवर्तन पूर्वनिश्चित बार ही हो। इस तरह की आवश्यकताओं की पूर्ति हेतु सी में for लूप की व्यवस्था है, जो निश्चित बार आवर्तन करता है। यद्यपि for लूप निश्चित बार आवर्तन के लिए बना है, लेकिन वह अत्यंत लचीला है और उसे प्रोग्रामर while लूप के समान भी काम करा सकता है। लेकिन शुरुआत के लिए हम उसके मूल रूप से परिचय बढ़ाएं। for लूप का हुलिया इस प्रकार होता है:-

for (प्रारंभिक मान; शर्त; प्रारंभिक मान में वृद्धि)
{
उक्तियां;
}

ध्यान दें कि for लूप के गोल कोष्ठकों के बीच तीन उक्तियां हैं, जिन्हें दो अर्ध विरामें से अलग किया गया है। ये हैं:

  • प्रारंभिक मान
  • शर्त
  • प्रारंभिक मान में वृद्धि

for लूप को चलाने के लिए सबसे पहले एक लूप गणक निश्चित किया जाता है, जो int (पूर्णांक) प्रकार की कोई राशि होती है। इसे कोई प्रारंभिक मान दिया जाता है, जो सामान्यतः 0 अथवा 1 होता है, पर कोई भी पूर्ण संख्या हो सकता है।

इसके बाद for लूप के आवर्तन के लिए आवश्यक कोई शर्त रखी जाती है। सामान्यतः यह लूप गणक का किसी उच्चतम मान से छोटा होना या बड़ा होना होता है, पर कोई भी अन्य शर्त भी हो सकती है। इतना ही नहीं, यहां एक से अधिक शर्त भी हो सकते हैं, जिन्हें एंड (&&) या ओर (||) प्रचालकों से जोड़ा जा सकता है। संकलक इन सभी शर्तों का एक साथ मूल्यांकन करेगा और उनका सम्मिलित तार्किक मान निर्धारित करेगा। यदि यह मान 1 निकले, तो लूप की उक्तियों का निष्पादन होगा, यदि 0 निकले, तो लूप टूट जाएगा और संकलक प्रोग्राम में लूप के बाद आनेवाली उक्तियों का निष्पादन करने लगेगा।

तीसरी उक्ति लूप गणक के मान में वृद्धि करनेवाली उक्ति होती है। हमने while loop के संबंध में बताया था कि while लूप के कोड खंड में ऐसी कोई उक्ति होनी चाहिए जो लूप के शर्त को बदले, अन्यथा while loop अनंत काल तक चलता रहेगा। for लूप में इस उक्ति को उसके कोड खंड में न रखकर स्वयं for लूप के गोल कोष्ठकों के अंदर अंत में रखा जाता है। ऊपर के पैरा में बताया गया था कि for लूप में अक्सर तार्किक व्यंजक के रूप में लूप गणक को किसी पूर्वनिश्चित मान से तुलना कराया जाता है और यदि लूप गणक इस मान से छोटा या बढ़ा हुआ, तो लूप टूट जाता है। इसके लिए यह आवश्यक है कि लूप के हर आवर्तन के बाद लूप गणक का मान घटे या बढ़े। इससे संबंधित उक्ति for लूप के गोल कोष्ठकों में विद्यमान अंतिम उक्ति में रहता है। यही वह उक्ति है जो for लूप के तार्किक व्यंजन (लूप तोड़नेवाली शर्त) के मान में परिवर्तन लाता रहता है, और एक निश्चित बार for लूप के आवर्त के बाद उस तार्किक व्यंजन के मान को 0 कर देता है, जिससे लूप टूट जाता है।

आइए एक वास्तविक उदाहरण से for लूप के कार्य करने को समझें। इस छोटे प्रोग्राम में एक for लूप की मदद से 1 से 5 तक की संख्याओं को मुद्रित किया जाता है।

प्रोग्राम – 20
---------------------------------
/*for loop ka udaharan */

#incldue <stdio.h>
#incldue <conio.h>


void main()
{
clrscr();

int ganak;
for (gank=1; x<=5;ganak++)
{
printf(“%d\n”, ganak);
}
getch();
}
---------------------------------

आउटपुट:
---------------------------------
1
2
3
4
5
---------------------------------

आइए इस प्रोग्राम को समझते हैं। इसमें सबसे पहले एक int प्रकार की राशि घोषित की गई है, जिसका नाम ganak रखा गया है।

इस ganak राशि को for लूप के गोल कोष्ठक की प्रथम उक्ति में 1 का मान दिया गया है। for लूप की तार्किक व्यंयन के रूप में यह शर्त रखी गई है कि ganak का मान 5 से कम या उसके बराबर होना चाहिए। इस सी उक्ति को देखिए, जिसमें यह बात कही गई है:-

ganak<=5;

for लूप की तीसरी उक्ति में ganak पर इंक्रिमेंट प्रचालक का प्रयोग किया गया है:-

ganak++

for लूप के कोड खंड में केवल एक उक्ति है, जो ganak के मान को printf () की मदद से अलग पंक्ति में स्क्रीन पर मुद्रित करता है।

for लूप के हर आवर्तन में ganak का मान 1 से बढ़ जाता है (ganak++ के कारण) और जब उसका मान 6 हो जाता है, तो लूप टूट जाता है।

for लूप के गोल कोष्ठकों में दो अर्धविरामों से अलगाए गए तीन कोड क्षेत्रों में से प्रत्येक में एक से अधिक उक्तियां भी हो सकती हैं, यथा,

for (int ganak1=0, int ganak2 =100; शर्त 1 && शर्त 2 || शर्त 3; ganak1++, ganak2--)

उपर्युक्त for लूप में दो गणक हैं ganak1 और ganak2 और तीन शर्ते हैं जो && और || से जुड़े हुए हैं। लूप के हर आवर्तन में ganak1 का मान 1 से बढ़ता जाता है, और ganak2 का मान 1 से घटता जाता है।

इस तरह से for लूप को अनेक वास्तविक परिस्थितियों में प्रयोग किया जा सकता है, और उसे while लूप की तरह भी काम कराया जा सकता है, इस तरह:-

for (;शर्त;)
{
उक्तियां;
}

इसमें for लूप के गोल कोष्ठकों में केवल एक क्षेत्र में कोड है, यानी शर्त वाले क्षेत्र में, बाकी दो में कोई उक्ति नहीं है। अर्ध विरामों का प्रयोग फिर भी हुआ है क्योंकि ये for लूप के वाक्य-विन्यास का आवश्यक अंग हैं। यह for लूप while loop के समान कार्य करेगा और जब तक शर्त का मान 1 हो, लूप चलता रहेगा। हां, उसके कोड खंड में ऐसी कोई उक्ति होनी चाहिए जो कभी न कभी शर्त को गलत बनाए, अन्यथा यह लूप निरंतर चलता जाएगा।

आप पूछ सकते हैं कि यदि for लूप से while लूप का काम भी लिया जा सकता है तो while लूप है ही क्यों, उसका आवश्यकता ही क्या है?

इसका जवाब यह है कि प्रोग्रामों का एक आवश्यक गुण यह होता है कि वे कम से कम समय में निष्पादित हों। इसलिए प्रोग्रामर हमेशा ऐसे कोड लिखने का प्रयत्न करते हैं जिसका निष्पादन ज्यादा तेजी से हो। जब आप सी को कुछ बेहतर रूप से समझने लगेंगे, आपको विदित होगा कि एक ही काम को करने के लिए सी में कोड कई तरह से लिखे जा सकते हैं। पर उनमें से कुछ प्रकार अधिक तेजी से निष्पादित होंगे, कुछ कम तेजी से, और साधारण प्रोग्रामर और गुरु प्रोग्रामर में यही अंतर होता है कि गुरु प्रोग्रामर हमेशा ऐसा कोड लिखेगा जो अधिक तेजी से निष्पादित हो।

तो while लूप की संरचना for लूप की तुलना में अधिक सरल है और कंप्यूटर while लूप को for लूप से अधिक तेजी से निष्पादित करता है। आपने देखा है कि for लूप के गोल कोष्ठकों में तीन कोड क्षेत्र और प्रत्येक में कई उक्तियां हो सकती है। इसलिए जब कंप्यूटर for लूप का निष्पादन करता है, तो लूप के हर आवर्तन में उसे इन सभी उक्तियों का मूल्यांकन करना पड़ता है। सी के कुछ बड़े और जटिल प्रोग्रामों में लूप वाले खंडों का आवर्तन सैकड़ों बार हो सकता है। इसलिए for लूप का निष्पदान while लूप की तुलना में उल्लेखनीय रूप से धीमा होता है।

तो ध्यान रखनेवाली बात यह है कि जब आवर्तन कितनी बार होगा यह ठीक से पता न हो, तो while लूप का प्रयोग करें, और जब यह पता हो कि ठीक कितनी बार लूप का आवर्तन होगा, तो for लूप का प्रयोग करें।

और यदि लूप को कोड खंड का निष्पादन प्रथम बार हर स्थिति में (लूप की शर्त गलत होने की स्थिति में भी) कराना आवश्यक हो, तो do... while लूप का प्रयोग करें।

Sunday, May 17, 2009

सीखए सी - 23 : आवर्तन की संरचनाएं - do... while लूप

do... while लूप while लूप का ही एक रूप है। इसमें और while लूप में फर्क यह है कि जहां while लूप में लूप तोड़ने वाली शर्त शूरू में रहता है, do... while लूप में यह शर्त अंत में आता है, इस तरह:-

do
{
उक्तियां;
} while (शर्त);

do... while लूप में धनु कोष्ठकों के बीच कई उक्तियां हो सकती हैं। उनमें से एक उक्ति ऐसी भी होनी चाहिए जो लूप तोड़नेवाली शर्त को बदलती हो, वरना लूप अनंत समय तक चलता रहेगा।

while और do... while लूप की संरचना में एक अन्य अंतर यह है कि while लूप में गोल कोष्ठकों के बाद अर्ध विराम चिह्न (;) नहीं है, जबकि do... while लूप में गोल कोष्टकों के बाद अर्ध विराम चिह्न (;) होता है। यह एक महत्वपूर्ण अंतर है। यदि do... while लूप के अंत में अर्ध विराम चिह्न (;) न रखा जाए तो संकलक को पता नहीं चल पाएगा कि while (शर्त) do... while लूप का भाग है अथवा एक स्वतंत्र while लूप।

आइए एक उदाहरण से do... while लूप को समझते हैं।

प्रोग्राम – 19
---------------------------------
/*do... while ka udaharan */

#include <stdio.h>
#include <conio.h>

void main()
{
clrscr();

int vetan=0;
char santusht = 'n';

printf("\nKya aapko maloom hai ki computer jagt me vetan badana bahut saral hota hai? \n\nAapko keval apna vetan batana hai, baki sab computer sambhal lega. \n\nTo batayiye, aap ka vetan kya hai: ");
scanf("%d", &vetan);
flushall();

do
{
printf("\Ab aapka vetan hai %d. Kya aap is vetan se santusht hai? Han ke liye y aur na ke like n darj karen: ", vetan+500);
scanf ("%c", &santusht);
flushall();
vetan = vetan + 500;
}
while (santusht == 'n');

printf ("\nDhanyavad. Aasha hai ab aap achcha kaam karenge.");
getch();
}
---------------------------------

आउटपुट
---------------------------------
Kya aapko maloom hai ki computer jagt me vetan badana bahut saral hota hai?
Aapko keval apna vetan batana hai, baki sab computer sambhal lega.
To batayiye, aap ka vetan kya hai: 10000
Ab aapka vetan hai 10500. Kya aap is vetan se santusht hai? Han ke liye y aur na ke like n darj karen: n
Ab aapka vetan hai 11000. Kya aap is vetan se santusht hai? Han ke liye y aur na ke like n darj karen: y
Dhanyavad. Aasha hai ab aap achcha kaam karenge.
---------------------------------

इस प्रोग्राम में दो राशियां घोषित की गई हैं – vetan और santusht। पहली int प्रकार की राशि है, जिसे 0 का मान दिया गया है। दूसरी char प्रकार की राशि है, जिसे n का मान दिया गया है।

scanf के जरिए प्रयोक्ता के वेतना का पता लगाया जाता है और उसे vetan में संचित किया जाता है।

इसके बाद वाला कथन आपके लिए नया है, इसलिए इसके बारे में कुछ विस्तार से समझाते हैं। यह कथन है –

flushall();

यह stdio लाइब्रेरी का एक फंश्नन है। scanf एक जटिल फंक्शन है, जो कभी-कभी अवांछित परिणाम देता है। उसके द्वारा इनपुट किए गए राशि को ठीक से पकड़वाने के लिए कुछ तिकड़क करने पड़ते हैं। इस प्रोग्राम के उस printf कथन पर विचार कीजिए जिसमें प्रोग्राम चलानेवाले व्यक्ति से अपने वेतन का खुलासा करने को कहा गया है। इस कथन के बाद कंप्यूटर प्रयोक्ता द्वारा अपना वेतन इनपुट करने के लिए रुका रहता है। प्रयोक्ता कोई मान इनपुट करता है, जैसे 10000। उसके बाद यह सूचित करने के लिए कि उसने इनपुट कर दिया है, ऐंटर कुंजी को दबा देता है। अब कंप्यूटर के इनपुट स्ट्रीम में दो वर्ण जमा हो गए हैं, 10000 और ऐंटर कुंजी का वर्ण। इनमें से हमें केवल पहला इनपुट चाहिए। यदि दूसरा इनपुट, यानी ऐंटर, इनपुट स्ट्रीम में रह जाए, तो यह प्रोग्राम में आगे गड़बड़ी फैला सकता है क्योंकि अगली बार जब आप scanf का उपयोग करेंगे, तो वह इस ऐंटर वर्ण को पकड़ेगा क्योंकि यही इनपुट स्ट्रीम में सबसे आगे रहेगा। इस अवांछित स्थिति से बचने के लिए हर बार scanf का उपयोग करने के बाद इनपुट स्ट्रीम को खाली करना जरूरी है। flushall() वाला फंक्शन यही करता है, ताकि जब भी आप scanf का उपयोग करें, आपको प्रयोक्ता द्वारा किया गया इनपुट ही मिले न कि इनपुट स्ट्रीम में रह गया कोई फालतू का वर्ण।

तो इसे ध्यान में रखिए। scanf का उपयोग करने के बाद हमेशा flushall() का उपयोग करें। यदि किसी प्रोग्राम में scanf के कारण गलत परिणाम मिल रहे हों, तो scanf के बाद flushall(); कथन रखकर देखें। इससे आपका प्रोग्राम ठीक से चलने लगेगा।

ठीक है, अब हम प्रोग्राम – 19 की ओर लौटते हैं। इस flushall (); उक्ति के बाद do... while लूप का do वाला भाग आता है। इसके धनु कोष्ठकों में ये उक्तियां हैं –

{
printf("\Ab aapka vetan hai %d. Kya aap is vetan se santusht hai? Han ke liye y aur na ke like n darj karen: ", vetan+500);
scanf ("%c", &santusht);
flushall();
vetan = vetan + 500;
}

printf कथन आपके वेतन में 500 का इजाफा कर देता है। इसी कथन में आपसे यह भी पूछा जाता है कि क्या आप इस वेतन से संतुष्ट हैं?

इसके बाद, scanf आपके उत्तर को (n या y) santusht में सहेज लेता है। इसके बाद वही flushall() कथन है।

अंतिम पंक्ति में vetan को 500 से बढ़ा दिया जाता है।

इसके बाद do... while लूप का while वाला भाग आता है, जो यह है -

while (santusht == 'n');

यह साधारण while लूप के समान ही है, केवल एक अंतर है। इसके अंत में अर्ध विराम (;) है। यह महत्वपूर्ण है। यदि इसे छोड़ दिया जाए, तो do... while लूप ठीक से काम नहीं करेगा।

इस उक्ति पर पहुंचकर कंप्यूटर देखता है कि क्या santusht का मान n है? यदि n है, तो do की उक्तियों का आवर्तन करता है। यदि नहीं है, तो do... while लूप टूट जाता है, और प्रोग्राम में उसके बाद की उक्तियों का निष्पादन होता है। इस प्रोग्राम में do... while के बाद एक printf कथन है, जो प्रयोक्ता को धन्यवाद देता है। कंप्यूटर इसका निष्पादन कर देता है।

इस उदाहरण से आपको while और do... while लूप का अंतर स्पष्ट हो गया होगा। while लूप का प्रयोग सामान्य आवर्तन के लिए होता है। लेकिन यदि ऐसी कोई स्थिति हो जिसमें आवर्तन शुरू करने से पहले कुछ आवश्यक कोड पंक्तियों का निष्पादन जरूरी हो, तो do... while अधिक उपयुक्त है।

Saturday, May 16, 2009

सीखए सी - 22 : अभ्यास 3 का हल

1.
प्रोग्राम -15

---------------------------------

/*Abhyas - 3 : 1 ka hal*/
#include <stdio.h>
#include <conio.h>

void main()
{
clrscr();
int sankhya=0;
while (sankhya < 5)
{
printf("\nJaihindi!");
sankhya++;
}
getch();
}
---------------------------------

आउटपुट
---------------------------------
Jaihindi!
Jaihindi!
Jaihindi!
Jaihindi!
Jaihindi!
---------------------------------

2.
प्रोग्राम – 16

---------------------------------
/*Abhyas - 3 : 2 - kisi sankhya ki gunan talika (pahada) */

#include <stdio.h>
#include <conio.h>

void main()
{
clrscr();

int sankhya=0;
int ganak=1;
printf("\nAap kis sankhya ki gunan talika (pahada) banvana chate hai?");
scanf("%d",&sankhya);

while (ganak <= 10)
{
printf("\n%d x %d = %d", ganak, sankhya, ganak*sankhya);
ganak++;
}
getch();
}
---------------------------------

आउटपुट
---------------------------------
Aap kis sankhya ki gunan talika (pahada) banvana chate hai? 6
1 x 6 = 6
2 x 6 = 12
3 x 6 = 18
4 x 6 = 24
5 x 6 = 30
6 x 6 = 36
7 x 6 = 42
8 x 6 = 48
9 x 6 = 54
10 x 6 = 60
---------------------------------

इस प्रोग्राम के printf वाली उक्ति पर विशेष ध्यान दीजिए। उसे यहां मैं दुबारा दे रहा हूं –

printf("\n%d x %d = %d", ganak, sankhya, ganak*sankhya);

इसमें तीन %d वाले अंश हैं। प्रथम दो तो ganak और sankhya का प्रतिनिधित्व करते हैं, लेकिन तीसरा %d द्वारा gank और sankhya के गुणनफल को प्रदर्शित किया जाता है। यह गुणनफल printf के गोल कोष्ठकों के भीतर ही निकाला जाता है, इस व्यंजक में –

ganak*sankhya

printf के बारे में यह एक नई बात आपने सीखी है। इस तरह के अनेक शोटकट सी में संभव हैं। जैसे-जैसे आप सी को बहतर रूप से जानने लगेंगे, इन शोटकटों से आप परिचित होते जाएंगे।

3.
प्रोग्राम – 17

---------------------------------
/*Abhyas - 3 : 3 - 1 se lekar 100 sankhyaon ka yog */

#include <stdio.h>
#include <conio.h>


void main()
{
clrscr();

int yog=0;
int sankhya=1;
int ganak=1;

while (ganak <= 100)
{
yog=yog+sankhya++;
ganak++;
}
printf("\n1 se lekar 100 tak ki sankhayon ka yog %d hai.", yog);
getch();
}

---------------------------------

आउटपुट
---------------------------------
1 se lekar 100 tak ki sankhyaon ka yog 5050 hai.
---------------------------------

इस प्रोग्राम की केंद्रीय उक्ति यह है –

yog=yog+sankhya++;

yog नामक राशि में 1 से लेकर 100 तक के अंकों का योग जमा किया जाता है। हर बार जब while लूप घूमता है, yog में एक प्राकृतिक संख्या (sankhya) जोड़ी जाती है। yog का प्रारंभिक मान 0 रखा गया है। while लूप के हर आवर्तन में उसके साथ sankhya का मान जोड़ा जाता है। लूप के प्रत्येक आवर्तन में sankhya का मान 1 से बढ़ाया जाता है, इस कथन द्वारा –

sankhya++;

लूप तब टूटता है जब गणक का मान 101 हो जाता है।

4.
प्रोग्राम – 18

---------------------------------
/*Abhyas - 3 : 4 - 1 se lekar kisi vanchit sankhya tak ki sankhyaon ka yog */

#include <stdio.h>
#include <conio.h>


void main()
{
clrscr();

int yog=0;
int sankhya=1;
int ganak=1;
int vanchitsankhya=0;
printf("\nAap 1 se lekar kitni tak ki sankhyaon ka yog janna chahte hai? ");
scanf("%d",&vanchitsankhya);

while (ganak <= vanchitsankhya)
{
yog=yog+sankhya++;
ganak++;
}
printf("\n1 se lekar %d tak ki sankhayon ka yog %d hai.", vanchitsankhya, yog);
getch();
}
---------------------------------

आउटपुट
---------------------------------
Aap 1 se lekar kitni tak ki sankhyaon ka yog janna chahte hai? 25
1 se lekar 25 tak ki sankhayon ka yog 325 hai.
---------------------------------

इस प्रोग्राम में पिछले प्रोग्राम के 100 वाली संख्या की जगह vanchitsankhya के मान का प्रयोग किया जाता है। vanchitsankhya का मान प्रोग्राम के निष्पादन के दौरान scanf के जरिए प्राप्त किया जाता है।

Monday, May 11, 2009

सीखए सी - 21 : आवर्तन की संरचनाएं - while लूप

कंप्यूटर की एक खासियत यह है कि वह निर्देशों के किसी खंड का निष्पादन अनेक बार कर सकता है। इसे संभव बनानेवाली संरचनाओं को लूपिंग संरचनाएं कहते हैं। सी में इस प्रकार की तीन संरचनाएं हैं - while, do... while, और for। इस लेख में हम केवल while लूप पर विचार करेंगे।

while लूप
while लूप का रूप इस प्रकार होता है:

while (तार्किक व्यंजक)
{
उक्तियां;
}

while शब्द के आगे के गोल कोष्ठकों में एक या अधिक तार्किक व्यंजक रहते हैं। इनका सम्मिलित मान प्रारंभ में 1 होता है। इसके बाद धनु कोष्ठकों के भीतर एक या अधिक उक्तियां होती हैं। उनमें से कोई एक उक्ति गोल कोष्ठक में मौजूद किसी राशि को परिवर्तित करनेवाली उक्ति होती है। कंप्यूटर इन उक्तियों का निष्पादन तब तक करता रहता है, जब तक कि while के गोल कोष्ठक के भीतर मौजूद तार्किक व्यंजक का मान 0 नहीं हो जाता। ध्यान रहे कि तार्किक व्यंजकों के केवल दो मान हो सकते हैं, 0 या 1।

नीचे के प्रोग्राम में while वलय का उपयोग करते हुए 10 पंक्तियां मुद्रित की जाती हैं। प्रत्येक पंक्ति में उस पंक्ति की क्रम-संख्या भी छपती है।

प्रोग्राम-12
---------------------------------
/*while loop ka udaharan */

#include <stdio.h>
#include <conio.h>

void main()
{
clrscr();

int kram_sankhya=1;

while(kram_sankhya < 11)
{
printf("Yah pankti no. %d hai.\n", kram_sankhya);
kram_sankhya++;
}

getch();
}
---------------------------------

आउटपुट:
---------------------------------
Yah pankti no. 1 hai.
Yah pankti no. 2 hai.
Yah pankti no. 3 hai.
Yah pankti no. 4 hai.
Yah pankti no. 5 hai.
Yah pankti no. 6 hai.
Yah pankti no. 7 hai.
Yah pankti no. 8 hai.
Yah pankti no. 9 hai.
Yah pankti no. 10 hai.
---------------------------------

इस प्रोग्राम में सबसे पहले kram_sankhya नामक पूर्णांक राशि घोषित की गई है और उसे 1 का मान दिया गया है। तत्पश्चात while वलय शुरू होता है। उसके कोष्ठकों में एक तार्किक व्यंजक है, जो इस प्रकार है:

kram_sankya <11

इस तार्किक व्यंजक का मान 1 तब तक रहता है, जब तक kram_sankhya का मान 11 या उससे बड़ा नहीं हो जाता। फिलहाल उसका मान 1 है, क्योंकि हमने उसे प्रोग्राम के शुरू में यही मान दिया है। चूंकि यह मान 11 से कम है, उपर्युक्त तार्किक व्यंजन का मान भी 1 है।

इसके बाद धनु कोष्ठकों में वे उक्तियां हैं, जिन्हें बार-बार दुहराना है। हमारे इस छोटे से प्रोग्राम में ऐसी केवल दो उक्तियां ही हैं। पहली उक्ति में printf() का आह्वान है। यह एक संदेश के भीतर एक पूर्णांक राशि को छापता है। यह पूर्णांक राशि kram_sankhya है। शुरू में इसका मान 1 है, इसलिए printf() यह वाक्य छापता है:

Yah pankti no. 1 hai.

चूंकि संदेश के अंत में \n है, printf() उपर्युक्त पंक्ति के बाद एक नई पंक्ति शुरू कर देता है, यानी कर्सर अलगी पंक्ति के शुरू में चला जाता है।

प्रोग्राम की अगली उक्ति में kram_sankhya राशि पर इंक्रिमेंट प्रचालक ++ का प्रयोग हुआ है, जो kram_sankhya के मान को 1 से बढ़ा देता है, यानी 2 कर देता है। इसके बाद कोई और उक्ति नहीं है, इसलिए प्रोग्राम का नियंत्रण एक बार फिर while वलय के प्रारंभिक पंक्ति को लौटकर तार्किक व्यंजन का एक बार फिर परीक्षण करता है। चूंकि 2, 11 से छोटा है, इसलिए while के तार्किक व्यंजन का मान अब भी 1 बना हुआ है और प्रोग्राम नियंत्रण while वलय की उक्तियों की ओर बढ़ जाता है।

यह क्रम दस बार चलता है और हर बार इंक्रिमेंट प्रचालक kram_sankhya का मान 1 से बढ़ाता जाता है। दसवीं बर इंक्रिमेंट प्रचालक kram_sankhya का मान 11 कर देता है। इसके बाद जब प्रोग्राम का नियंत्रण while के प्रारंभ में जाकर तार्किक व्यंजन की समीक्षा करता है, तो पाता है कि अब तार्किक व्यंजक का मान 0 हो गया है, क्योंकि 11, 11 से छोटा नहीं है। अतः प्रोग्राम नियंत्रण वलय के भीतर नहीं घुसता और वलय के बाद वाली उक्ति की ओर बढ़ जाता है।

चूंकि वहां और कोई उक्ति नहीं है, इसलिए प्रोग्राम का समापन हो जाता है।

अब हम while वलय का उपयोग करते समय ध्यान में रखनेवाली दो बातों का उल्लेख करेंगे। ये हैं:

1. while वलय के कोष्ठकों में जिस राशि का परीक्षण होता है, उसे while वलय के पूर्व कोई प्रारंभिक मान देना जरूरी है। इस उदाहरण में यह राशि kram_sankhya है, और उसे 1 का मान दिया गया है।

2. धनु कोष्ठकों में मौजूद कोई एक उक्ति को इस राशि के मान में कोई परिवर्तन लाना चाहिए, तभी while वलय का समापन होगा। इस प्रोग्राम में इंक्रिमेंट प्रचालक kram_sankhya के मान को 1 से बढ़ाता जाता है, जिससे दसवीं आवृत्ति पर वह 11 का मान प्राप्त कर लेता है, जिससे while का तार्किक व्यंजन का मान 0 हो जाता है, और वलय टूट जाता है। यदि आप इस इंक्रिमेंट उक्ति को छोड़ देंगे, तो kram_sankhya का मान 1 पर ही निर्विकार बना रहेगा और while वलय बड़े मजे से अनंत काल तक घूमता रहेगा। इस अनंत वलय से पीछा छुड़ाना आपके लिए मुश्किल हो जाएगा। आपके प्रोग्रामों में इस प्रकार की अप्रिय स्थितियों से बचने के लिए while वलय का उपयोग करते समय ऊपर कही गई दोनों बातों पर गांठ बांध लीजिए।

आइए एक और उदाहरण देखें:

प्रोग्राम-13
---------------------------------
/*while loop ka ek aur udaharan */

#include <stdio.h>
#include <conio.h>

void main()
{

clrscr();

int kram_sankhya=10;


printf("\nUlti ginti shuru!!!");

while (kram_sankhya>=0)
{

printf("\n%d", kram_sankhya);
kram_sankhya--;
}

printf("\n\nYan ke rocket dago!\n");
getch();
}
---------------------------------

आउटपुट
---------------------------------
Ulti ginti shuru!!!
10
9
8
7
6
5
4
3
2
1
0
Yaan ke rocket dago!
---------------------------------

यह प्रोग्राम किसी रोकेट यान के उड़ान भरने के पहले की उल्टी गिनती का निर्दशन करता है।

यहां kram_sankhya को 10 का प्रारंभिक मान दिया गया है। while के तार्किक व्यंजक में इस बात का परीक्षण होता है कि kram_sankhya का मान 0 से बड़ा या उसके बराबर है, या नहीं। while के धनु कोष्ठकों में डिक्रिमेंट प्रचालक kram_sankhya के मान को हर आवृत्ति के दौरान 1 से कम करता जाता है, जिससे दसवीं आवृत्ति के अंत में उसका मान ऋणात्मक हो जाता है, यानी 0 से कम, और इस कारण से तार्किक व्यंजन का मान 0 हो जाता है, और while वलय बिखर जाता है।

लीजिए एक और उदाहरण। यह गणित के छात्रों के लिए काम का हो सकता है, क्योंकि इसमें किसी संख्या का क्रमगुणित (फैक्टोरियल) ज्ञात किया जाता है। किसी संख्या का क्रमगुणित वह संख्या है जो उस संख्या तथा उसके पहले के सभी धनात्मक पूर्ण संख्याओं को आपस में गुणा करने पर प्राप्त होता है। उदाहरण के लिए 5 का क्रमगुणित होगा 5 x 4 x 3 x 2 x 1 = 120

प्रोग्राम-14
---------------------------------
/*while loop ki madat se kramganit (factorial) ka parikalan*/

#include <stdio.h>
#include <conio.h>


void main()
{
clrscr();

int sankhya, sankhyadharak;
long kramgunit;

printf("25 se chota koi ek dhanatmak sankhya enter kijiye: \n");
scanf("%d", &sankhya);
sankhyadharak = sankhya;
kramgunit = 1;

while (sankhya > 1)
{
kramgunit = kramgunit * sankhya;
sankhya--;
}

printf ("%d ka kramgunit %ld hai.\n", sankhyadharak, kramgunit);
getch();
}
---------------------------------

आउटपुट
---------------------------------
25 se chota koi ek dhanatmak sankhya enter kijiye: 6
6 ka kramgunit 720 hai.
---------------------------------

यहां दो पूर्णांक राशियां घोषित की गई हैं, sankhya और sankhyadharak और एक long प्रकार की राशि kramgunit । kramgunit के लिए long प्रकार चुनना इसलिए आवश्यक है क्योंकि क्रमगुणित संख्याएं बहुत बड़ी-बड़ी संख्याएं होती हैं, और वे साधारण int राशियों में नहीं समाएंगी। उदाहरण के लिए यदि आप kramgunit को int प्रकार की राशि घोषित करें, तो आपका प्रोग्राम 7 से अधिक संख्याओं के लिए काम नहीं करेगा। आपको kramgunit के रूप में कोई ऋणात्मक संख्या प्राप्त होगी। यह इसलिए क्योंकि int प्रकार की राशि में 36,000 से अधिक बड़ी संख्याएं नहीं समा सकतीं। यद्यपि long राशि में int राशि से कहीं बड़ी संख्याएं समा सकती हैं, फिर भी उसकी भी एक सीमा है, जिससे बड़ी संख्याएं उसमें नहीं समाएंगी। यदि आप इस प्रोग्राम में sankhya के लिए कोई बड़ी संख्या दें, जैसे, 100, तो यह प्रोग्राम सही परिणाम नहीं देगा। इसलिए प्रोग्राम लिखते समय प्रोग्राम में घोषित राशियों की सीमाओं का खास ध्यान रखना जरूरी होता है। इस प्रोग्राम में हमने सूचित किया है कि जो संख्या दर्ज की जाए, वह 25 से छोटा हो।

आइए देखें कि यह प्रोग्राम कैसे काम करता है। चूंकि while वलय में डिक्रिमेंट प्रचालक sankhya के मान को बदलता है, इसलिए उसके प्रारंभिक मान को बचाकर रखने की आवश्यकता है, क्योंकि हम अंतिम printf() उक्ति में मूल संख्या को प्रदर्शित करना चाहते हैं। अतः sankhya के प्रारंभिक मान को sankhyadharak में आरोपित किया गया है।

ध्यान दीजिए कि kramgunit को while वलय के पहले 1 का मान दिया गया है। यह इसलिए क्योंकि while वलय में kramgunit की गणना करने के लिए kramgunit को sankhya के वर्तमान मान से गुणन किया जाता है। चूंकि किसी संख्या को 1 से गुणन करने पर उसका मान नहीं बदलता, इसलिए while वलय के प्रथम बार निष्पादित होने पर जब sankhya को kramgunit से गुणन किया जाता है, तो प्रोग्राम का अंतिम परिणाम प्रभावित नहीं होता।

while वलय के कोष्ठकों में वलय की हर आवृत्ति के पहले sankhya के मान का परीक्षण होता है और यह देखा जाता है कि वह 1 से बड़ा है या नहीं। वलय के धनु कोष्ठकों की उक्तियों का निष्पादन तभी होता है, जब sankhya का मान 1 से बड़ा होता है। धनु कोष्ठकों की उक्तियों में से डिक्रिमेंट वाला प्रचालक sankhya के मान को वलय की हर आवृत्ति पर 1 से घटाता जाता है, जिससे वलय अनंत वलय होने से बच जाता है।

ध्यान दीजिए कि आउटपुट प्रिंट करने वाले printf कथन में हमें दूसरी संख्या के लिए %ld निरूपण चिह्न का प्रयोग किया है। यह इसलिए क्योंकि हमने इस दूसरी संख्या को, यानी kramgunit को long प्रकार की राशि घोषित किया है, और printf में long प्रकार की राशियों के लिए निरूपण चिह्न %ld ही होता है।

अभ्यास -3
1. while वलय का उपयोग करते हुए "Jai Hindi!" संदेश की आवृत्ति पांच बार करवाइए।

2. while वलय की सहायता से किसी संख्या की गुणन तालिका (पहाड़ा) दर्शाइए। उदाहरण के लिए 3 का पहाड़ा इस प्रकार होगा:

1 x 3 = 3
2 x 3 = 6
3 x 3 = 9
...
...
10 x 3 = 30

3. while वलय की सहायता से 1 से लेकर 100 तक के पूर्णांकों का सम्मिलित योग ज्ञात कीजिए।

4. प्रश्न 3 में इस प्रकार की तब्दीली कीजिए कि 100 के बजाए n संख्याओं का कुल योग ज्ञात हो। इस n का मान scanf() के जरिए प्रोग्राम के निष्पादन के दौरान प्राप्त किया जाए।

Wednesday, May 6, 2009

सीखिए सी - 20 : सशर्त कथन ___ ?___ : ___

अभ्यास – 2 का हल

प्रोग्राम – 10
--------------------------------
/*Abhyas 2 ka hal */

#include <stdio.h>
#include <conio.h>

void main()
{

clrscr();

float praptank;

printf("Batayiye, pariksha me kitne ank aaye: ");
scanf("%f", &praptank);
if(praptank >= 60)
{
printf("\nFirst Division.");
}

else if (praptank >=50)
{
printf("\nSecond Division.");
}
else if(praptank >=40)
{
printf("\nThird Division.");
}
else
{
printf("\nFail.");
}
getch();
}
-------------------------------


आउटपुट
-------------------------------
Batayiye, pariksha me kitne ank aaye: 65
First Division.
Batayiye, pariksha me kitne ank aaye: 54
Second Division.
Batayiye, pariksha me kitne ank aaye: 45
Third Division
Batayiye, pariksha me kitne ank aaye: 35
Fail.
-------------------------------

अब आपने सीख लिया है कि सी प्राग्रामों में if ... else संरचना की मदद से किस तरह विशाखन को अंजाम दिया जाता है।

सी में विशाखन लाने के कुछ अन्य तरीके भी हैं, यथा ? प्रचालक और switch संरचना। इनमें से ? प्रचालक, जिसे सशर्त कथन (conditional statement) कहा जाता है, अधिक सरल है, और उसका विवेचन हम इस लेख में करेंगे। switch संरचना को ठीक से समझने के लिए continue, break और exit कथनों की थोड़ी जानकारी प्राप्त करना आवश्यक है। इन कथनों की जानकारी हम आवर्तन के बारे में सीखने के बाद प्राप्त करेंगे, और उसके बाद switch को भी समझेंगे।

? प्रचालक का रूप इस तरह होता है।

तार्किक कथन ? व्यंजक 1 : व्यंजक 2

यानी, इसके तीन भाग होते हैं, जिन्हें ? और : द्वारा अलगाया हुआ होता है।

पहला भाग एक तार्किक व्यंजक होता है, जिसका मूल्यांकन पहले होता है और इसके परिणाम स्वरूप सही (1) या गलत (0) का मान प्राप्त होता है। तार्किक कथन के मूल्यांकन से यदि सही का मान आए, तो व्यंजक 1 में विद्यमान मान प्राप्त होता है, और यदि गलत का मान आए, तो व्यंजक 2 का मान होता है।

स्पष्ट ही सशर्त कथनों के प्रयोग से केवल दो विकल्पों को संभाला जा सकता है। दो से अधिक विकल्प होने पर if... else अथवा switch कथनों का सहारा लेना अनिवार्य हो जाता है।

आइए, सशर्त कथनों को एक प्रोग्राम के जरिए समझते हैं।

प्रोग्राम -11
-------------------------------
/* ? prachalak (conditonal statement) ka udaharan */

#include <stdio.h>
#include <conio.h>

void main()
{
clrscr();

float praptank;
char parinaam;

printf("\nPariksha me kitne ank aaye: ");
scanf("%f", &praptank);

result = (praptank>=40) ? 'P' : 'F';

printf("\nParinaam: %c", result);

getch();
}
-------------------------------

आउटपुट
-------------------------------
Pariksha me kitne ank aaye: 56
Parinaam: P
Pariksha me kitne ank aaye: 34
Parinaam: F
-------------------------------

इस प्रोग्राम में दो राशियां घोषित की गई हैं, praptank जो float प्रकार की राशि है, और parinaam जो char प्रकार की राशि है। scanf के जरिए praptank में प्राप्तांक का मान जमा किया जाता है।

इसके बाद की पंक्ति को ध्यान पूर्वक देखिए। आपकी सुविधा के लिए उसे यहां दुबारा दिया जा रहा है –

result = (praptank>=40) ? 'P' : 'F';

इसमें ? प्रचालक का उपयोग किया गया है। क्या आप इस प्रचालक में विद्यमान तीन व्यंजकों को पहचान पाएं? वे हैं –
1. (praptank>=40)
2. 'P'
3. 'F'

प्रोग्राम की यह पंक्ति इस तरह से काम करती है –

सबसे पहले praptank >= 40 का मूल्यांकन किया जाता है। यदि praptank 40 या उससे बड़ा हुआ, तो इस व्यंजनक को 1 का मान मिलता है, यानी यह व्यंजन सही ठहरता है। यदि praptank 40 से कम हुआ, तो इस व्यंजक को 0 का मान मिलता है, यानी यह व्यंजक गलत ठहरता है। यदि praptank >= 40 का मान 1 हो, तो result में P मान रख दिया जाता है। यदि praptank >= 40 का मान 0 हो, तो result में F मान रख दिया जाता है।

सशर्त कथन, यानी ? प्रचालक हमेशा कोई एक मान लौटाता है। यदि उसकी प्रथम उक्ति का मान 1 है, तो वह ? के बाद वाला मान लौटाता है, और यदि प्रथम उक्ति का मान 0 है, तो : के बाद वाला मान। इस मान को किसी राशि में पकड़ा जा सकता है। उपर्युक्त उदाहरण में इस मान को result राशि में पकड़ा गया है। इसके लिए = प्रचालक का प्रयोग किया है। यह अपने दाहिनी ओर के मान को (इस उदाहरण में सशर्त कथन द्वारा लौटाए गए मान को) अपने बाईं ओर की राशि में जमा करता है, जो यहां result है।

सशर्त कथन के बाद वाला prinft उक्ति result के मान को दर्शाता है।

सशर्त कथन सी की उन विरल उक्तियों में से एक है जिन्हें त्रिपक्षीय (ternary) प्रचालक कहा जाता है, यानी ये तीन राशियों पर काम करते हैं। =, &&, / आदि अधिकांश अन्य प्रचालकों में केवल दो पक्ष ही होते हैं, बायां पक्ष (lvalue) और दायां पक्ष (rvalue)। लेकिन सशर्त कथन में ? और : अलगाए हुए तीन पक्ष होते हैं।

Tuesday, April 28, 2009

सीखिए सी -19 : विशाखन - if... else निर्देश

इस लेख में हम प्रोग्रामन भाषाओं की एक अत्यंत महत्वपूर्ण विशेषता के बारे में सीखेंगे, जो है विशाखन।

कंप्यूटर प्रोग्रामों में अनेक बार ऐसी स्थितियां आती हैं जिनमें कंप्यूटर को दो या अधिक विकल्पों में से किसी एक को चुनकर आगे बढ़ना पड़ता है। इसी को विशाखन कहते हैं। विशाखन के कारण ही कंप्यूटर प्रोग्राम अनेक जटिल कार्य कर पाते हैं।

इसे एक उदाहरण से समझते हैं। मान लीजिए कि हमें एक ऐसा प्रोग्राम लिखना है जो स्कूली बच्चों के प्राप्तांक स्वीकार करेगा और यदि प्राप्तांक 60% से ज्यादा हो, तो प्रदर्शित करेगा - Pratham Darja. यदि प्राप्तांक 50% और 60% के बीच हो तो प्रदर्शित करेगा - Dvitiya Darja. और यदि प्राप्तांक 40% और 50% के बीच हो तो प्रदर्शित करेगा – Tritiya Darja. और यदि प्राप्तांक 40% से कम हो, तो प्रदर्शित करेगा – Fail.

यहां कंप्यूटर उसे दी गई सूचना के अनुसार चार विकल्पों में से कोई एक विकल्प चुनेगा। इस तरह इस प्रोग्राम को चलाने पर हर बार अलग-अलग परिणाम प्राप्त होगा जो उसे दिए गए प्राप्तांक पर निर्भर करेगा।

इस तरह के प्रोग्राम लिखने में हमें सी की जो संरचना मदद करती है, वह है if... else वाली संरचना। इसके कई रूप होते हैं, सबसे सरल रूप यह है:

if (शर्तें)
{
सी की उक्तियां
}
else
{
सी की उक्तियां
}

इसमें if के आगे के गोल कोष्ठकों में सी की कोई तार्किक व्यंजक होता है, जिसका मान प्रोग्राम के चलने के समय सही अथवा गलत में से कोई एक होता है। यदि उसका मान सही हुआ, तो if के बाद के धनु कोष्ठकों के बीच विद्यमान उक्तियों का निष्पादन होता है और प्रोग्राम else के धनु कोष्ठकों में जो उक्तियां हैं, उन्हें छोड़ देता है। इसकी जगह यदि if के गोल कोष्ठकों में जो तार्किक व्यंजक है, उसका मान गलत हो, तो प्रोग्राम if के धनु कोष्ठकों की उक्तियों को छोड़कर else के धनु कोष्ठकों में जो उक्तियां हैं, उनका निष्पादन करता है।

आइए एक छोटे प्रोग्राम के जरिए इसे समझते हैं। इस प्रोग्राम में आपसे पूछा जाता है कि रात है या दिन, और प्राप्त उत्तर के अनुसार Raat ko taare chamakte hain. या Din ko suraj chamakta hai. में से कोई एक वाक्य प्रदर्शित किया जाता है।

प्रोग्राम 8
--------------------------------
/*if... else ka udaharan */

#include <stdio.h>
#include <conio.h>

void main()
{
clrscr();

char raat_din;

printf("Batayiye ki raat hain ya din. Raat ke liye R aur din ke liye D type kijiye: ");
scanf("%s", &raat_din);
if(raat_din=='D')
{
printf("\nDin mein suraj chamakta hai.");
}
else
{
printf("\nRaat ko tare chamakte hai.");
}
getch();
}
-------------------------------

आउटपुट
-------------------------------
यदि प्रयोक्ता R दर्ज करे
Raat ko tare chamakte hai.

यदि प्रयोक्ता D दर्ज करे
Din mein suraj chamakta hai.
-------------------------------

इस प्रोग्राम में खास रूप से if के गोल कोष्ठकों में जो व्यंजक है उसकी ओर ध्यान दीजिए। वह है

raat_din=='D'

यहां D अक्षर को एकल उद्धरण चिह्न ( ‘ और ‘) से घेरा गया है। यह महत्वपूर्ण है। सी में char प्रकार की राशियों को एकल उद्धरण चिह्नों से घेरा जाता है, और string प्रकार की राशियों को दुहरे उद्धरण चिह्नों से (“ और ”)। उदाहरण के लिए prinf() के गोल कोष्ठकों में जो वाक्य है, वह string प्रकार की राशि है, जिसे दुहरे उद्धरण चिह्नों से घेरा गया है।

जब प्रोग्राम if वाली उक्ति पर पहुंचता है, तो वह उसके गोल कोष्ठक के तार्किक व्यंजक का मूल्यांकन करता है और scanf() के जरिए raat_din राशि में जमा कराए गए वर्ण की तुलना D से करता है। यदि दोनों D ही हुए तो वह इस व्यंजक का मान 1 कर देता है, यानी सही, और प्रोग्राम if के धनु कोष्टकों के भीतर जो उक्ती है, उसका निष्पादन कर देता है, जिससे स्क्रीन पर

Din me suraj chamakta hai.

वाला वाक्य दिखाई देता है।

इसकी जगह यदि scanf() ने raat_din में R वर्ण को जमा कराया हो, तो if उक्ति के गोल कोष्ठक के भीतर के व्यंजक का मान 0 हो जाता है, यानी गलत, और प्रोग्राम if के धनु कोष्ठकों की उक्ति को छोड़कर else के धनु कोष्ठक की उक्ति का निष्पादन करता है, जिससे स्क्रीन पर यह वाक्य नजर आता है

Raat ko tare chamakte hai.

इस उदाहरण में दो ही विकल्प थे, पर if... else संरचना का उपयोग करके दो से अधिक विकल्पों को भी संभाला जा सकता है। इस तरह:-

if (शर्तें)
{
सी की उक्तियां
}
else if (शर्तें)
{
सी की उक्तियां
}
else
{
सी की उक्तियां
}

इसमें दो if... else कथनों को एक के बाद एक पिरोया गया है, जिससे तीन विकल्प प्राप्त होते हैं।

आइए प्रोग्राम 8 को ही थोड़ा और विस्तृत करके इस तीन विकल्प वाले if...else को समझते हैं। इसके लिए हम प्रोग्राम 8 को इस तरह बदलेंगे। यदि प्रयोक्ता R या D के सिवा कोई अन्य कुंजी को दबाए, तो प्रोग्राम यह संदेश प्रदर्शित करेगा:-

Aap ko D athava R me se koi kunji hi dabani thi.

प्रोग्राम 9
-------------------------------
/*Teen vikalp wale if... else ka udaharan */

#include <stdio.h>
#include <conio.h>

void main()
{
clrscr();

char raat_din;

printf("Batayiye ki raat hain ya din. Raat ke liye R aur din ke liye D type kijiye: ");
scanf("%s", &raat_din);
if(raat_din=='D')
{
printf("\nDin mein suraj chamakta hai.");
}
else if (raat_din=='R')
{
printf("\nRaat ko tare chamakte hai.");
}
else
printf("\nAap ko D athava R me se koi kunji hi dabani thi.");
getch();
}
-------------------------------

आउटपुट
-------------------------------
यदि प्रयोक्ता R दर्ज करे
Raat ko tare chamakte hai.

यदि प्रयोक्ता D दर्ज करे
Din mein suraj chamakta hai.

यदि प्रयोक्ता D या R के सिवा कोई अन्य कुंजी दबाए
Aap ko D athava R me si koi kujni hi dabani thi.
-------------------------------

इस प्रोग्राम में संकलक if उक्ति पर पहुंचकर उसके गोल कोष्ठक के भीतर के व्यंजक को scanf() द्वारा raat_din में जमा किए वर्ण के आधार पर सही या गलत का मान देता है। वह सही होने पर if के धनु कोष्ठकों की उक्ति का निष्पादन होता है और आगे के else if.. else के धनु कोष्ठकों की उक्तियों को संकलक लांघ जाता है। वह गलत होने पर if के धनु कोष्ठों की उक्ति को छोड़कर प्रोग्राम else if वाली उक्ति पर आ जाता है और उसके गोल कोष्ठकों के व्यंजक का मूल्यांकन करता है और उसे सही या गलत का मान देता है। यदि यह व्यंजक सही है, तो else if के धनु कोष्ठकों की उक्ति का निष्पादन होता है। यदि यह व्यंजक गलत है, तो प्रोग्राम else if के धनुकोष्ठकों की उक्ति को छोड़ देता है, और अंतिम else के धनु कोष्ठकों की उक्ति का निष्पादन करता है।

इस अंतिम else के आगे आप और if ... else जोड़कर तीन से अधिक विकल्पों वाले अधिक जटिल प्रोग्राम भी लिख सकते हैं।

क्यों न इस तरह का एक प्रोग्राम लिखने की कोशिश आप करें? इससे if ... else संरचना के काम करने की रीति आपको अच्छी तरह समझ में आ जाएगी। तो लिजिए, यह रहा

अभ्यास – 2

आपको इस लेख के प्रारंभ में जो उदाहरण दिया गया है उसके लिए if ... esle संरचना का उपोयग करते हुए एक प्रोग्राम लिखना है।

आपको एक ऐसा प्रोग्राम लिखना है जो स्कूली बच्चों के प्राप्तांक स्वीकार करेगा और यदि प्राप्तांक 60% से ज्यादा हो, तो प्रदर्शित करेगा - Pratham Darja. यदि प्राप्तांक 50% और 60% के बीच हो तो वह प्रदर्शित करेगा - Dvitiya Darja. और यदि प्राप्तांक 40% और 50% के बीच हो तो वह प्रदर्शित करेगा – Tritiya Darja. और यदि प्राप्तांक 40% से कम हो, तो वह प्रदर्शित करेगा – Fail.

यह प्रोग्राम लिखने की कोशिश कीजिए। अगले लेख में मैं इसका हल दूंगा, पर मैं चाहता हूं कि इससे पहले आप स्वयं ही इसे लिख डालें।

Monday, April 27, 2009

सीखिए सी - 18 : अभ्यास 1 का हल

पिछले लेख में मैंने आपसे एक सी प्रोग्राम लिखने को कहा था। क्या आप लिख पाए? यदि लिख पाए, और उसने वांछित परिणाम दिया तो आपको बधाई। यह साबित करता है कि आपने सी भाषा पर काफी अधिकार पा लिया है। इससे सी से संबंधित अधिक कठिन विषयों को सीखने में आपको सहूलियत रहेगी।

यदि आप प्रोग्राम नहीं लिख पाए, तो कोई बात नहीं। उसका कोड नीचे दिया गया है। उसे ध्यान से देखिए। इस प्रोग्राम में हमने कुछ नई विशेषताओं का समावेश किया है, जिसे हम आगे समझाएंगे।

प्रोग्राम -7
--------------------
/*Abhyas -1 */

#include <stdio.h>
#include <conio.h>

void main()
{
clrscr();

char naam[20];

printf("Kripaya apna naam batayen: ");
scanf("%s", &naam);
printf("\nAbhinandan %s ji.", naam);
getch();
}
----------------------
आउटपुट
Kripaya apna naam batayen: Balasubramaniam
Abhinandan Balasubramaniam ji.
----------------------
इस प्रोग्राम के शुरू में पूर्वसंकलक के लिए दो उक्तियां हैं:-

#include <stdio.h>
#include <conio.h>

इनमें से पहली उक्ति से आप परिचित हैं। यह पहले के प्रोग्रामों में भी आया है। यह सी के stdio वाली लाइब्रेरी का हेडर फाइल है।

दूसरी उक्ति सी के conio लाइब्रेरी का हेडर फाइल है। इसका उपयोग हमने इसलिए किया है क्योंकि हमने इस प्रोग्राम में इस लाइब्रेरी के एक फंक्शन का उपयोग किया है। यह फंक्शन है, clrscr()।

आइए अब आपको बताते हैं कि यह फंक्शन क्या करता है। कंप्यूटर कई प्रकार के आउटपुट स्क्रीन पर दिखाता रहता है। इन्हें वह एक के बाद एक के क्रम में स्क्रीन पर दर्शाता जाता है। इससे थोड़ी ही देर में कंप्यूटर स्क्रीन पर आउटपुट की बहुत सारी पंक्तियां जमा हो जाती हैं, जिससे नए आउटपुट की पंक्तियां ठीक से नजर नहीं आतीं। clrscr() फंक्शन स्क्रीन पर जितना भी पुराना आउटपुट हो, उसे सब मिटा देता है, जिससे नए आउटपुट की पंक्तियां स्क्रीन के ऊपरी भाग में साफ दिखाई देती हैं।

इस प्रोग्राम के अंत में एक और नया फंक्शन आप देखेंगे, यह है getch()। यह भी एक काम का फंक्शन है। यह फंक्शन कुंजीपटल से कोई एक कुंजी के दबाने तक प्रोग्राम को आउटपुट विधा में रोके रखता है। इससे आप प्रोग्राम द्वारा दर्शाए गए अंतिम आउटपुट को देख पाते हैं। अन्यथा कंप्यूटर बिजली की तेजी से अंतिम आउटपुट, अर्थात "Abhinandan Balasubramaniam ji." वाली पंक्ति को प्रदर्शित करके अपने आप बंद हो जाएगा। यह इतनी तेजी से होगा कि आप देख भी नहीं पाएंगे कि कंप्यूटर ने क्या दर्शाया।

getchar() के कारण प्रोग्राम कोई कुंजीपटल इनपुट के लिए रुका रहेगा, यानी जब तक आप कुंजीपटल की किसी कुंजी को न दबाएं, स्क्रीन दिखाई देता रहेगा, और आप प्रोग्राम के अंतिम आउटपुट को भली-भांति देख पाएंगे।

getch() फंक्शन भी stdio.h सी लाइब्रेरी का एक फंक्शन है।

इस प्रोग्राम की अंतिम विशेषता काफी महत्वपूर्ण है, इसलिए इसे ध्यानपूर्वक समझिए। हमने प्रोग्राम के शुरू में एक char राशि घोषित की है, जिसका नाम हमने naam रखा है, पर इस पंक्ति में आप एक नई बात देखेंगे। naam को इस तरह घोषित किया गया है:-

char naam[20];

यानी naam के आगे वर्ग कोष्ठकों मे 20 लिखा हुआ है। क्या आप बता सकते हैं, कि हमने ऐसा क्यों किया?

इसका उत्तर सरल है। आपने पहले सीखा था कि char राशि के लिए कंप्यूटर मात्र 8 बिट का स्थान आरक्षित करता है। इन आठ बिटों में अंग्रेजी वर्णमाला का कोई एक वर्ण समा सकता है। लेकिन किसी व्यक्ति के नाम में तो अनेक वर्ण होते हैं। उदाहरण के लिए, मेरा ही नाम लीजिए, Balasubramaniam. इसमें 15 वर्ण हैं। इसलिए यदि हम naam को मात्र char naam; के रूप में घोषित करें, तो उसमें केवल एक वर्ण समा पाएगा, यानी B वर्ण, और आपके प्रोग्राम के आउटपुट में भी केवल यही एक वर्ण दिखाई देगा, इस तरह:-

Abhinandan B ji.

क्यों न आप प्रोग्राम में यह परिवर्तन करके देखें। char naam[20]; की जगह केवल char naam; रखकर प्रोग्राम को चलाकर देखिए। साथ में scanf() और दूसरे printf() उक्ति में भी %s की जगह %c करना न भूलें। क्या आपको ऊपर्युक्त आउटपुट मिला?

इसलिए, नाम में विद्यमान अन्य वर्णों को पकड़ने के लिए हमें अधिक लंबी राशि की आवश्यकता है। char naam[20]; में हमने 20 char राशियों के बराबर की स्मृति naam के लिए आरक्षित कराई है। इतनी स्मृति में Balasubramaniam जैसे लंबे नाम पूरे आ जाएंगे, और हमारे प्रोग्राम के आउटपुट में नाम पूरा दिखाई देगा।

इस तरह की एक से अधिक char से बनी राशि को string राशि कहा जाता है। उसका चिह्न %s होता है। क्या आपने ध्यान दिया कि इस प्रोग्राम की scanf() उक्ति में तथा दूसरी prinf() उक्ति में हमने $s चिह्न का प्रयोग किया है? उसके स्थान पर यदि हम %c का प्रयोग करते, तो प्रोग्राम सही आउटपुट नहीं देता।

char naam[20] वाली उक्ति के बारे में कुछ अन्य आवश्यक बातों का जिक्र करके हम इस लेख को समाप्त करते हैं।

यह राशि वास्तव में प्रयोक्ता द्वारा निर्दिष्ट राशि का एक उदाहरण है। इस तरह की राशि को array कहा जाता है, जिसके लिए हिंदी में सरणी शब्द चलता है।

सी में दो तरह की राशियां होती हैं, एक, सी की अपनी राशियां, जैसे char, int, float, इत्यादि, और दो, प्रयोक्ता-निर्दिष्ट राशियां। इनका विस्तार संकलक द्वारा निर्दिष्टि नहीं किया जाता है, बल्कि प्रयोक्ता अपनी आवश्यकतानुसार इनका विस्तार बताते हैं। उदाहरण के लिए char naam[20] में हमने निर्दिष्टि किया है कि naam का विस्तार 20 char राशियों के बराबर होगा। इससे कंप्यूटर अपनी स्मृति में 20 सलग्न char कोषों को naam के साथ जोड़ देता है (अर्थात 160 बिट की जगह को)। स्मृति के इस खंड तक आप naam शब्द का उपयोग करके पहुंच सकते हैं, और वहां जो भी मान आप चाहे रखवा सकते हैं, अथवा वहां मौजूद मान को आउटपुट के रूप में ला सकते हैं।

सरणि (array) एक जटिल विषय है जिस पर हम आगे के लेखों में अधिक विस्तार से चर्चा करेंगे।

Saturday, April 25, 2009

सीखिए सी - 17 : अभ्यास-1

आइए, अब हम परखें कि आपने अब तक के लेखों को कितनी अच्छी तरह से समझा है। इसका बेहतरीन तरीका होगा अब तक अर्जित ज्ञान का उपयोग करते हुए एक सी प्रोग्राम लिखना।

तो तैयार हो जाइए, सी का एक प्रोग्राम लिखने के लिए।

एक ऐसा प्रोग्राम लिखिए जिसमें प्रयोक्ता से उसका नाम पूछा जाएगा (इसके लिए आप printf() का उपयोग करेंगे)। और प्रयोक्ता द्वारा बताए गए नाम को एक राशि में जमा करके आप उसे एक अभिनंदन वाक्य में पिरोकर स्क्रीन पर दर्शाएंगे। इसके लिए आपको एक char प्रकार की राशि घोषित करनी होगी और प्रयोक्ता के इनपुट को पकड़ने के लिए scanf() का उपयोग करना होगा।

इस प्रोग्राम का आउटपुट कुछ-कुछ इस प्रकार का होना चाहिए:-

Kripaya apna naam batayiye: Balasubramaniam
Abhinandan, Balasubramaniam ji.

तो चलिए, जल्दी से इस तरह का एक प्रोग्राम लिख डालिए।

अगले पोस्ट में इस अभ्यास का उत्तर दिया जाएगा, लेकिन मैं चाहूंगा कि उससे पहले आप खुद ही यह प्रोग्राम लिखकर तैयार रहें।

सीखिए सी - 16 : समाहार -1

आपमें से जिन लोगों ने अब तक प्रिंटेफ-स्कैनेफ के इन लेखों का साथ दिया है, उन्होंने सी भाषा की काफी बातें सीख ली हैं। इतनी कि अब आप कोई छोटा-मोटा सी प्रोग्राम स्वयं लिख सकते हैं। सी ही नहीं कोई भी कंप्यूटर भाषा सीखने का एक मात्र तरीका यह है कि उस भाषा में ढेर सारे प्रोग्राम लिखे जाएं। प्रोग्राम लिखने पर आपसे गलतियां भी होंगी, पर ये गलतियां आपको बताएंगी कि प्रोग्राम लिखने का सही तरीका क्या है। इसलिए अपनी गलतियों से घबराइए नहीं, न ही उनसे निरुत्साहित हों, बल्कि गलतियों को सीखने की प्रक्रिया का एक अनिवार्य अंग मानकर उनसे लाभ उठाइए।

अब तक के लेखों में हमने कुछ 6 सरल सी प्रोग्रामों के उदाहरण दिए हैं। क्या आपने इन प्रोग्रामों के कोड को अपने कंप्यूटर पर उतारकर, इन प्रोग्रामों को संकलित करके देखा था? क्या आपको इन प्रोग्रामों के वैसे ही परिणाम मिले थे, जैसे इन लेखों में बताया गया है? यदि नहीं मिले तो सोचिए आपसे कहां गलती हो गई। इन लेखों को दुबारा पढ़ें और पता लगाएं कि आपके प्रोग्राम की गलती को कैसे सुधारा जा सकता है। इस तरह सी की वाक्य-विन्यास शैली आपके मन में ठीक प्रकार से बैठ जाएगी, और आपसे आगे गलतियां नहीं होंगी।

यहां मैं नौसिखिए सी प्रोग्रामरों द्वारा आमतौर पर की जानेवाली कुछ गलतियों की सूची दे रहा हूं। यह आपको इन गलतियों से बचनने में मदद करेगी।

1. सी वाक्यों के अंत में ; न देना।

2. धनु कोष्ठक के दुहरे चिह्नों ({ और }) में से एक का छूट जाना।

3 गोल कोष्ठकों के दुहरे चिह्नों (( और ) ) में से एक का छूट जाना।

4. पूर्वसंकलक की उक्तियों से पहले # चिह्न न लगाना (जैसे #include <stdio.h> की जगह include <stdio.h> लिखना।

5. पूर्वसंकलक की उक्तियों के आगे ; चिह्न लगाना (जैसे #include<stdio.h>; लिखना।

6. printf() फलनक के कोष्ठकों में विद्यमान उक्ति को दुहरे उद्धरण चिह्नों (“ और “) से न घेरना।

7. printf() फलनक के कोष्ठकों की उक्ति के अंत में समापन उद्धरण चिह्न छूट जाना।

8. scanf() फलनक में राशि के नाम के पहले पता सूचक चिह्न & न लगाना।

9. किसी राशि को घोषित करते समय उसका प्रकार (int, char, long, इत्यादि) सूचक शब्द छोड़ देना।

10. राशि का नामकरण करते समय नामकरण के नियमों का उल्लंघन करना – जैसे, नाम के अक्षरों के बीच रिक्त स्थान होना, नाम के रूप में सी के आरक्षित शब्दों का उपयोग करना, नाम को किसी अंक से शुरू करना, नाम में अमान्य वर्ण (!, @, #,%,& आदि) रखना, इत्यादि।

इन गलतियों से यदि आप बचते चलें, तो आप सी के प्रोग्राम सफलतापूर्वक लिखते चले जाएंगे।

Friday, April 24, 2009

सीखिए सी -15 : scanf()

पिछले अध्याय में हमने देखा कि printf() की सहायता से हम किस प्रकार कंप्यूटर की स्मृति में से आंकड़े लाकर स्क्रीन पर प्रदर्शित कर सकते हैं। कई बार इसका उल्टा भी आवश्यक होता है, यानी कुंजीपटल पर अंकित सूचनाओं को कंप्यूटर की स्म़ृति में डालना। इस काम में printf() का भाई scanf() नामक फलनक हमारी मदद करता है। scanf() भी stdio.h संग्रह का फलनक है। आइए, उससे परिचय बढ़ाते हैं। निम्नलिखित प्रोग्राम को देखिए।

---------------------
प्रोग्राम 5

/* scanf() ka udaharan */

#include <stdio.h>

void main()
{
char aapki_pasand;
printf("Aapki pasand ka koi akshar enter kijiye:\n");
scanf("%c", &aapki_pasand);
printf("Aapne %c akshar enter kiya.\n", aapki_pasand);
}
---------------------
आउटपुट
Aapki pasand ka koi akshar enter kijiye: a
Aapne a akhsar enter kiya.
---------------------

इस प्रोग्राम में aapki_pasand नामक वर्ण राशि (char) घोषित की गई है, लेकिन उसे कोई मान नहीं दिया गया है। इसके बाद वाली उक्ति आपके लिए परिचित है, वह स्क्रीन पर Aapki pasand ka koi akshar enter kijiye: संदेश प्रदर्शित करता है। इस संदेश को प्रदर्शित करने के बाद नियंत्रण प्रचालन तंत्र, यानी डोस, को नहीं लौट जाता, जैसा कि अब तक के प्रोग्रामों में होता आया है, पर कर्सर विसर्ग चिह्न (:) के आगे रुक जाता है। यह इसलिए क्योंकि अगली उक्ति scanf() है, जो कुंजीपटल पर अंकित संकेतों को स्वीकारता है।

अब आप कुंजीपटल पर a वाली कुंजी दबाइए और उसके बाद ऐंटर कुंजी को। तुरंत ही आपको स्क्रीन पर यह वाक्य दिखाई देगा: Aapne a akshar enter kiya.

क्या यह जादू जैसा नहीं लगता? आपके प्रोग्राम को कैसे पता चला कि आपने कौन-सा अक्षर ऐंटर किया था? दरअसल यह सब scanf() का कमाल है।

scanf() का हुलिया printf() से बहुत मिलता-जुलता है, पर कुछ-कुछ भिन्न भी है। printf() के ही समान इसमें भी गोल कोष्ठकों के बीच एक उक्ति है, जो दुहरे उद्धरण चिह्नों से घिरी है।

इस उक्ति में वही प्रतिशत-चिह्न वाला संयुक्त वर्ण %c है जो आंकड़े का प्रकार दर्शाता है (इस उदाहरण में char)। उद्धरण चिह्नों के बाद printf() के ही समान यहां भी अल्प विराम चिह्न (,) है। उसके बाद चर राशि का नाम है, पर चर राशि के नाम के पहले और अल्प विराम के बाद आप यहां एक नया चिह्न देख रहे हैं, जो है &। इसे ऐंपरसैंड कहते हैं। आइए, इसके बारे में जानें।

कंप्यूटर ने apni_pasand नामक वर्ण राशि के लिए 8 बिट का स्थान आरक्षित करके उस स्थान के पते को apni_pasand नाम के साथ जोड़ दिया है। पर चूंकि हमने इस आरक्षित स्थान पर कोई मान नहीं रखा है, इसलिए वह जगह उपयोगी आंकड़े से भरी नहीं है। उस जगह पर a अक्षर को रखने के लिए हम scanf() का आह्वान करते हैं और उसे %c चिह्न द्वारा सूचित करते हैं कि हम कंप्यूटर की स्मृति में एक वर्ण को रखना चाहते हैं। अब scanf() के लिए यह जानना जरूरी है कि इस वर्ण राशि को कहां रखे। हम a को apni_pasand नामक चर राशि के लिए आरक्षित स्मृति-कोषों में रखना चाहते हैं। scanf() को इन कोषों का पता बताने के लिए इन कोषों से संबंधित राशि के नाम के पहले & चिह्न जोड़ा जाता है। किसी चर राशि के नाम के पहले & चिह्न जोड़ने से उस चर राशि के लिए आरक्षित स्मृति कोषों का पता प्राप्त होता है।

इसीलिए & को एड्रेस प्रचालक, यानी पता बतानेवाला प्रचालक, कहा जाता है।

हमारे प्रोग्राम में scanf() को &apni_pasand से apni_pasand के स्मृति-कोषों का पता मिल जाता है और वह a अक्षर को इन कोषों में रख देता है।

प्रोग्राम की अगली उक्ति का परिणाम यह सिद्ध कर देता है कि scanf() ने सचमुच ऐसा किया है क्योंकि आउटपुट में हमें %c के स्थान पर a अक्षर दिखाई देता है।

printf() के ही समान scanf() भी एक से अधिक चर राशियों को स्वीकार कर सकता है। देखिए कैसे:

-------------------------
प्रोग्राम-6

/* scanf() ek sath do rashiyon ko bhi pad sakta hai. */

#include <stdio.h>

void main()
{
char pahala_akshar;
char doosara_akshar;
printf("Apni pasand ke do akshar enter kijiye. Dono aksharon ke beech rikta sthan rakhiye: \n");
scanf("%c%c", &pahala_akshar, &doosara_akshar);
printf("Aapki pahli pasand hai %c aur doosari %c.\n", pahala_akshar,
doosara_akshar);
}
------------------------

आउटपुट:
Apni pasand ke do akshar enter kijiye. Donon aksharon ke beech rikta
sthan rakhiye: a b

Aapki pahli pasand hai a aur doosari b.

-------------------------
यहां दो वर्ण राशियां घोषित की गई हैं pahala_akshar और doosara_akshar, और scanf() से इनका मान प्राप्त किया जाता है। कुंजी-पटल द्वारा इन दोनों राशियों का मान (a और b) अंकित कीजिए। दोनों अक्षरों के बीच रिक्त स्थान होना जरूरी है, इसलिए a की कुंजी दबाने के बाद रिक्त-दंड (स्पेस-बार) को दबाइए और उसके बाद b की कुंजी को। इस रिक्त स्थान को देखकर scanf() समझ जाता है कि पहली राशि का मान पूरा हो गया है और कुंजी-पटल अब अगली राशि का मान प्रेषित करेगा। रिक्त-दंड के स्थान पर आप टैब अथवा ऐंटर कुंजी भी दबा सकते हैं। इन तीनों को श्वेत-स्थान देनेवाले वर्ण (वाइट स्पेस कैरक्टर) कहा जाता है, क्योंकि ये स्क्रीन पर या कागज पर दिखाई नहीं देते। अंत में ऐंटर कुंजी दबाइए, जिससे कंप्यूटर को मालूम पड़े कि आपने दोनों अक्षरों को ऐंटर कर दिया है।

scanf() के कोष्ठकों में इस बार दो %c चिह्न हैं और तदनुसार अल्प-विराम (,) के बाद दो राशियों के नाम भी हैं। दोनों राशियों के पहले & चिह्न भी लगा हुआ है।

प्रोग्राम के आउटपुट से हमें पता चलता है कि scanf() ने दोनों राशियों को ठीक प्रकार से स्मृति में पहुंचा दिया है।

इस अध्याय के प्रोग्रामों में हमने scanf() की सहायता से वर्ण राशियों को ही पढ़ा है, लेकिन scanf() अन्य प्रकार की राशियों को भी इतनी ही कुशलता से पढ़ सकता है। केवल उसके कोष्ठकों में दुहरे उद्धरण चिह्नों के बीच %c के स्थान पर अन्य राशियों के सूचक-चिह्न, यानी %d, %l या %f रखने की आवश्यकता है।

अंत में हम scanf() का उपयोग करते समय ध्यान में रखने की एक जरूरी बात फिर से दुहरा देते हैं। scanf() के लिए यह जानना आवश्यक होता है कि वह कुंजीपटल से प्राप्त सूचनाओं को कंप्यूटर की स्मृति में कहां रखे। यह जानकारी उसे उसके कोष्ठकों में मौजूद चर राशि के नाम के पहले & चिह्न जोड़कर दी जाती है। अपने प्रोग्रामों में scanf() का उपयोग करते समय इस & चिह्न की ओर विशेष ध्यान दीजिए, अन्यथा आपको scanf() से वांचित परिणाम नहीं प्राप्त होंगे।

Wednesday, April 22, 2009

सीखिए सी 14 : printf()

आप प्रोग्राम 1 में printf() फलनक (फंक्शन) से मिल चुके हैं। यह सी भाषा का एक अत्यंत उपयोगी फलनक है। यह फलनक stdio.h संग्रह में रहता है। इस लेख में हम इसके बारे में विस्तृत जानकारी प्राप्त करेंगे।

इसका पूरा नाम है प्रिंट फोर्मैट। इसका मुख्य काम है कंप्यूटर की स्मृति में संचित आंकड़ों को कंप्यूटर के स्क्रीन पर लाना। हमने पहले स्पष्ट किया था कि कंप्यूटर के स्मृति-कोषों में आंकड़े 0 और 1 के क्रम में रहते हैं और राशियों के नामकरण के दौरान char, int, float आदि सूचक शब्द जोड़कर प्रोग्राम कंप्यूटर को यह निर्देश देता है कि इन नामों से जुड़े स्मृति-कोषों में रखे आंकड़े किस प्रकार के हैं। printf() फलनक स्मृति में से आंकड़े लाकर प्रोग्राम में उन्हें जिस रूप में प्रदर्शित करने की आवश्यकता होती है, उस रूप में स्क्रीन पर प्रदर्शित करता है। इसके लिए वह अपने कोष्ठकों में दी गई सूचनाओं का उपयोग करता है। आइए एक उदाहरण से इन सब बातों को समझते हैं।

------------------------
प्रोग्राम-2

/* printf() ka udaharan */

#include <stdio.h>

void main ()
{
int namoone_ka_ank = 9;
printf("Namoone ka ank %d hai.\n", namoone_ka_ank);
}
------------------------------------

प्रोग्राम को संकलित करके चलाने पर स्क्रीन पर यह दिखता है:

आउटपुट:
Namoone ka ank 9 hai.

इस प्रोग्राम में namoone_ka_ank एक पूर्णांक राशि का नाम है। इस नाम के पूर्व लिखा गया int शब्द हमें यह सूचना देता है। इस पूर्णांक राशि को = चिह्न की सहायता से 9 का मान दिया गया है।

printf() के कोष्ठकों में आपको तीन-चार नई बातें दिखेंगी। अब हम उन्हें स्पष्ट करते हैं।

1. %d चिह्न
जैसा कि हमने देखा, आंकड़े char, int, long या float प्रकार के हो सकते हैं। किसी राशि को printf() द्वारा ठीक से प्रदर्शित कराने से पहले हमें printf() को यह बताना होता है कि वह जिस राशि को प्रदर्शित कर रहा है, वह किस प्रकार का है। यह सूचना उसे उसके कोष्ठकों में दुहरे उद्धरण चिह्नों के बीच %c, %d, %l, %s या %f चिह्न रखकर दी जाती है। ये चिह्न क्रमशः char, int, long, string और float को सूचित करते हैं।

प्रकारसूचक शब्दफोर्मैटिंग चिह्न
वर्णchar%c
पूर्णांकint%d
दीर्घ पूर्णांकlong%l
दशमलव अंकfloat%f
वाक्यांशstring%s


उपर्यूक्त प्रोग्राम में %d को देखकर printf() समझ जाता है कि उसे एक पूर्णांक राशि को %d के स्थान पर प्रदर्शित करना है। यह कौन-सी राशि है, इसकी सूचना printf() को उसके कोष्ठक में दुहरे उद्धरण चिह्नों के आगे लिखे गए चर राशि के नाम से पता चलता है।

2. , चिह्न
दुहरे उद्धरण चिह्नों के आगे जो अल्प विराम (,) है, उसकी ओर विशेष ध्यान दीजिए। यह अल्प विराम महत्व रखता है। यदि आप उसे छोड़ देंगे तो संकलक प्रोग्राम का संकलन उस स्थान पर आकर रोक देगा। सी भाषा में अल्प विराम (,) किसी उक्ति के दो हिस्सों को अलगाने के लिए उपयोग किया जाता है। इस उक्ति में अल्प विराम के बाद उस राशि का नाम है, जिसे printf() को प्रदर्शित करना है।

3. चर राशि का नाम namoone_ka_ank
हमारे प्रोग्राम में printf() वाली उक्ति में अल्प विराम के बाद namoone_ka_ank लिखा है। इसे देखकर printf() समझ जाता है कि उसे पूर्णांक के रूप में namoone_ka_ank नामक राशि को प्रदर्शित करना है। वह तुरंत कंप्यूटर की स्मृति में से उन आंकड़ों को ले आता है जो namoone_ka_ank नाम से जुड़े स्मृति कोषों में रखे हैं और इन आंकड़ों को पूर्णांक में बदलकर प्रदर्शित करता है। इसलिए हम आउटपुट वाक्य में %d के स्थान पर 9 देखते हैं, जो इस राशि का मान है।

4. \n चिह्न
printf() के कोष्ठकों में दुहरे उद्धरण चिह्नों के अंदर जो संदेश रखा गया है, उसके अंत में \n चिह्न है। इसे न्यू-लाइन वर्ण, यानी नई पंक्ति की सूचना देनेवाला वर्ण कहते हैं। कुंजी पटल के ऐंटर या रिटर्न नामक कुंजी को दबाने पर कर्सर एक नई पंक्ति की शुरुआत करता है। \n वर्ण इस ऐंटर या रिटर्न कुंजी का प्रतीक है। यद्यपि यह दो वर्णों से बना है (\ और n), लेकिन कंप्यूटर इसे एक वर्ण के रूप में पढ़ता है। वास्तव में \, जिसे बैकश्लैश कहा जाता है, कुछ वर्णों के साथ जुड़कर कुछ विशेष वर्ण पैदा करता है। ये विशेष वर्ण कुंजी पटल की उन कुंजियों को दर्शाते हैं जो स्क्रीन पर दिखाई नहीं देते, जैसे टैब, ऐंटर या रिटर्न, बैकस्पेस आदि।

इन विशेष वर्णों की सूची नीचे दी गई है।

विशेष वर्ण अर्थ
/n नई पंक्ति
/t टैब स्पेस



हमारे प्रोग्राम में \n को देखकर printf() संदेश के अंत में एक नई पंक्ति शुरू करता है, यानी कर्सर वाक्य पूरा होने के बाद अगली पंक्ति के शुरुआती स्थान पर चला जाता है।

printf() एक साथ अनेक राशियों को प्रदर्शित कर सकता है। आइए देखें कैसे।

-----------------------
प्रोग्राम-3

/* printf() dwara ek se adhik rashiyon ka pradarshan */

#include <stdio.h>

void main()
{
char namoone_ka_varna='a';
int namoone_ka_ank=9;
printf("Namoone ka varna %c hai aur namoone ka ank %d hai.\n",
namoone_ka_varna, namoone_ka_ank);
}
---------------------

आउटपुट:
Namoone ka varna a hai aur namoone ka ank 9 hai.

इस बार प्रोग्राम में दो राशियां घोषित की गई हैं: namoone_ka_varna और namoone_ka_ank. पहली char (वर्ण) प्रकार की राशि है और दूसरी int (पूर्णांक) प्रकार की।

namoone_ka_varna में a का मान आरोपित किया गया है। इसके लिए राशि के नाम के आगे आरोपण चिह्न = के बाद a को इकहरे उद्धरण चिह्नों से घेरकर रखा गया है, ऐसे - 'a'।

char प्रकार की राशियों में मान रखने की यही विधि है, यानी मान को इकहरे उद्धरण चिह्नों में दर्शाना।

nammone_ka_ank में 9 का मान आरोपित किया गया है।

इस बार printf() के कोष्ठकों में प्रतिशत चिह्न (%) वाले दो विशेष वर्ण हैं, %c और %d क्योंकि हम दो राशियों को प्रदर्शित करना चाहते हैं। तदनुसार दुहरे उद्धरण चिह्नों के बाद अल्प विराम के आगे भी दो राशियों के नाम हैं। ध्यान दें कि ये दोनों नाम उसी क्रम में हैं जिस क्रम में प्रतिशत चिह्न वाले वर्ण हैं, यानी namoone_ka_varna पहले और उसके बाद namoone_ka_ank। प्रतिशत-चिह्न-युक्त चिह्नों का क्रम और चर राशियों का क्रम समान होना बिलकुल आवश्यक है।
प्रोग्राम को संकलित करके चलाने पर आपको वांचित आउटपुट प्राप्त होता है:

Namoone ka varna a hai aur namoone ka ank 9 hai.

एक और उदाहरण लीजिए।

--------------------------
प्रोग्राम 4

/* printf() ka ek aur udaharan */

#include <stdio.h>

void main ()
{
float namoone_ka_ank = 9;
printf("Namoone ka ank %f hai.\n", namoone_ka_ank);
}
-----------------------------
आउटपुट:
Namoone ka ank 9.000000 hai.

क्या आप इस आउटपुट को देखकर चौंके? बात सीधी-सी है। ध्यान दीजिए कि हमने namoone_ka_ank को दशमलव अंक (float) घोषित किया है। सी भाषा में दशमलव अंकों में सामान्यतः दशमलव के बाद छह स्थान होते हैं। चूंकि हमने ये स्थान स्पष्ट नहीं किए हैं (हमने केवल 9 लिखा है), कंप्यूटर ने इन स्थानों को शून्य से भर दिया है।

Sunday, April 19, 2009

सीखिए सी 13 : प्रचालकों का वरीयता-क्रम

जब एक ही व्यंजक में अनेक प्रचालक हों, तब कभी-कभी यह निश्चित करना कठिन हो जाता है कि उनमें से किस प्रचालक का निष्पादन पहले होता है। उदाहरण के लिए इस अंकगणितीय व्यंजक को देखिए: 10 + 5 * 2। इसका मान 30 है, या 20?

यदि हम + प्रचालक के निष्पादन को पहले माने, तो 30 है और यदि * प्रचालक का निष्पादन पहले माने, तो 20 है। किंतु कंप्यूटर को इस प्रकार की द्विधात्मक स्थितियां पसंद नहीं हैं। इसलिए प्रचालकों की एक वरीयता क्रम मानी गई है और कंप्यूटर इसी क्रम के अनुसार अनेक प्रचालकों वाले व्यंजकों का मूल्यांकन करता है। वह ऊंची वरीयता वाले प्रचालक का निष्पादन नीची वरीयता वाले प्रचालकों के निष्पादन के पहले करता है।

प्रचालकों की वरीयता निम्नानुसार है:

() सबसे अधिक वरीयता
! ++ --
* / %
+ -
< <= > >=
&&
|| सबसे कम वरीयता

उपर्युक्त क्रम को तोड़ना हो, तो संबंधित राशियों को गोल कोष्ठक में रख दीजिए। चूंकि गोल कोष्ठक की वरीयता सबसे अधिक है, इसलिए कंप्यूटर उसके अंदर जो प्रचालक हैं, उनका निष्पादन सबसे पहले करेगा, चाहे इन प्रचालकों की वरीयता अन्य प्रचालकों से कम क्यों न हो।

मान लीजिए कि उपर्युक्त उदाहरण में आप 10 और 5 को पहले जोड़ना चाहते हैं और तत्पश्चात उनके योग को 2 से गुणन करना चाहते हैं। इसके लिए आप व्यंजक को इस प्रकार से लिखेंगे:

(10 + 5) * 2

प्रचालकों का वरीयता-क्रम किसी व्यंजक के दो पड़ौसी प्रचालकों पर ही (यानी कोई भी दो प्रचालक जो व्यंजक में निरंतर आते हों) लागू होता है, दूरस्थ प्रचालकों पर नहीं। आमतौर पर कंप्यूटर व्यंजकों का मूल्यांकन बाईं ओर से दाहिनी ओर करता है। वह बाईं ओर से सबसे पहले आए दो प्रचालकों की वरीयता की तुलना करता है और उनमें से जिसकी वरीयता अधिक हो, उसका निष्पादन करता है। तत्पश्चात वह बचे हुए प्रचालक की वरीयता की तुलना अगले प्रचालक से करता है और इन दोनों में से जिसकी वरीयता अधिक हो, उसका निष्पादन करता है। इत्यादि।

उदाहरण:
आइए, देखें कि कंप्यूटर निम्नलिखित व्यंजक का निष्पादन किस क्रम में करेगा:

10 + 4 - 21 * 6 / 7

कंप्यूटर इस व्यंजक का मूल्यांकन बाईं ओर से शुरू करेगा और पहले दो प्राचलकों, यानी + और - की वरीयता की तुलना करेगा। दोनों की वरीयता समान है, इसलिए वह + का निष्पादन करेगा क्योंकि वह व्यंजक में पहले आया है। इसका परिणाम होगा:

14 - 21 * 6 / 7

तत्पश्चात वह - और * की वरीयता की तुलना करेगा। * की वरीयता अधिक है। लेकिन इसका निष्पादन करने से पहले कंप्यूटर इसकी वरीयता को इसके अगले प्रचालक, यानी /, की वरीयता से करके देखेगा। इन दोनों की वरीयता समान है। इसलिए * का निष्पादन होगा:

14 - 126 / 7

अब बचते हैं - और / प्रचालक। इनमें से / प्रचालक की वरीयता अधिक है। अतः उसका निष्पादन होगा:

14 - 18

अब केवल एक प्रचालक - बचा है। इसके निष्पादन के बाद अंतिम परिणाम प्राप्त होगा, जो है:

-4।

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

Saturday, April 11, 2009

सीखिए सी - 12 : सी के प्रचालक

प्रचालक उन प्रतीकों को कहते हैं जो आंकड़ों और चर राशियों में विशिष्ट प्रकार की तब्दीलियां लाते हैं। सी के प्रचालक निम्नानुसार हैं:

1. अंकगणितीय प्रचालक
ये पांच हैं, +, -, *, / और %। इनमें से प्रथम चार जोड़ने, घटाने, गुणन करने और विभाजित करने के प्रचालक हैं। अंतिम को माड्युलस प्रचालक कहा जाता है। यह किन्हीं दो अंकों को विभाजित करने पर बची राशि को व्यक्त करता है।

उदाहरण:
8 % 3 = 5

8 को 3 से विभाजित करने पर 5 शेष रहता है। अतः, माड्युलस प्रचालक 5 का मान देता है।

2. तार्किक प्रचालक
तार्किक प्रचालक तीन हैं &&, || और !।

तार्किक प्रचालकों के केवल दो मान हो सकते हैं, सही या गलत, जिन्हें 1 या 0 से निर्दिष्ट किया जाता है। इन प्रचालकों में से प्रथम && को ऐंड (और) प्रचालक कहते हैं। यह 1 का मान तब देता है जब सब संकार्यों (ओपरेन्ड्स) का मान 1 हो। यदि किसी एक संकार्य का भी मान 0 हो, तो यह प्रचालक 0 नतीजा देता है।

दूसरा प्रचालक || है, जिसे ओर (या) प्रचालक कहते है। यह 1 का मान तब देता है जब किसी भी एक या उससे अधिक संकार्यों का मान 1 हो। यह 0 मान तभी देता है जब सभी संकार्यों का मान 0 हो।

अंतिम तार्किक प्रचालक ! नोट (नहीं) प्रचालक है। यह किसी तार्किक व्यंजक (एक्सप्रेशन) पर असर करता है और उसके मान को उलट देता है। ध्यान रहे कि तार्किक व्यंजकों के केवल दो ही मान हो सकते हैं, 1 या 0। अत:, यदि किसी तार्किक व्यंजक का प्रारंभिक मान 1 हो, तो उस पर नोट प्रचालक लगाने पर व्यंजक का नया मान 0 हो जाएगा।
इन प्रचालकों के प्रभाव को नीचे की तालिका में स्पष्ट किया गया है।

&& प्रचालक

संकार्य 1संकार्य 2संकार्य 1 && संकार्य 2
010
100
000
111

|| प्रचालक
संकार्य 1संकार्य 2संकार्य 1 || संकार्य 2
011
101
000
111

! प्रचालक
संकार्य 1! संकार्य 1
10
01

इन प्रचालकों का उपयोग if...else और while वाली उक्तियों में बहुत होता है, जिनके बारे में हम आगे के लेखों में सीखेंगे।

3. संबंधपरक प्रचालक
ये निम्नलिखित हैं:

प्रचालकअर्थ
= =के बराबर है
!=के बराबर नहीं है
<=से छोटा है या बराबर है
<से छोटा है
>=से बड़ा है या बराबर है
>से बड़ा है


इन प्रचालकों के भी केवल दो मान हो सकते हैं, 1 या 0।

उदाहरण:
व्यंजनमानटिप्पणी
4 == 80  यह व्यंजक गलत है, 4 8 के बराबर नहीं है
4 !== 81यह सही है, 4 8 के बराबर नहीं है
4 <= 81यह सही है, 4 8 से छोटा है
4 < 81यह सही है, 4 8 से छोटा है
4 >= 80यह गलत है, 4 8 से बड़ा नहीं है
4 > 80यह गलत है, 4 8 से बड़ा नहीं है


4. = प्रचालक
यह आरोपण प्रचालक है और आप इससे मिल चुके हैं। यह इसके बाईं ओर की चर राशि में इसके दाहिनी ओर की राशि का मान आरोपित करता है।

उदाहरण:
x =10;
x= y+z;
x=y=z=8;

अंतिम उदाहरण में आरोपण की प्रक्रिया दाहिनी ओर से बाईं ओर क्रमवार संपन्न होती है, यानी पहले z में 8 का मान आता है, फिर y में z का मान (जो अब 8 है), और अंत में x में y का मान। इस प्रकार तीनों का मान 8 हो जाता है।

ध्यान दीजिए कि == प्रचालक और = प्रचालक में जमीन आसमान का अंतर है। == एक संबंधसूचक प्रचालक है जो केवल यह बताता है कि उसके दोनों ओर के संकार्य बराबर हैं या नहीं। यदि वे बराबर हैं, तो वह 1 का मान देता है, अन्यथा 0 का। इसके विपरीत = प्रचालक आरोपण प्रचालक है जो उसके दाहिनी ओर के मान को बाईं ओर की चर राशि में आरोपित करता है।

5. & प्रचालक
इससे भी आप scanf() के प्रसंग में मिल चुके हैं। यह ऐड्रेस प्रचालक है, यानी पता बतानेवाला प्राचालक। इसे लगाकर हम किसी चर राशि से जुड़े स्मृति कोषों का पता जान सकते हैं।

ध्यान में रखें, तार्किक ऐंड प्रचालक (&&) और राशियों का पता बतानेवाला प्रचालक (&) पूर्णतः भिन्न हैं।

6. ++ और -- प्रचालक
इन्हें क्रमश: इंक्रिमेंट प्रचालक और डिक्रिमेंट प्रचालक कहा जाता है। इंक्रिमेंट प्रचालक किसी चर राशि के मान को 1 से बढ़ा देता है और डिक्रिमेंट प्रचालक किसी चर राशि के मान को 1 से कम कर देता है।

उदाहरण:
सी की उक्तिटिप्पणी
x = 10; x का प्रारंभिक मान 10 है।
x++; अब x का मान एक से बढ़कर 11 हो गया है।
x--; अब x का मान एक से कम होकर दुबारा 10 हो गया है।


ये दोनों प्रचालक राशि के बाईं ओर या दाहिनी ओर लग सकते हैं। दोनों स्थितियों में इनका प्रभाव अलग-अलग होता है। जब ये राशि के दाहिनी ओर लगते हैं, तो इंक्रिमेंट या डिक्रिमेंट का काम बाद में होता है। यदि ये प्रचलाक राशि के बाईं ओर लगे, तो इंक्रिमेंट या डिक्रिमेंट का काम पहले होता है। ऐरे की चर्चा करते समय हम इस बारीकी पर अधिक प्रकाश डालेंगे।

7. , (अल्प-विराम) प्रचालक
यह अनेक व्यंजकों को जोड़कर एक उक्ति बनाने में काम आता है।

उदाहरण:
int x,y,z;

यह एक उक्ति निम्नलिखित तीन उक्तियों के बराबर है:
int x;
int y;
int z;