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() के जरिए प्रोग्राम के निष्पादन के दौरान प्राप्त किया जाए।

No comments:

Post a Comment