Header Ads

ad728
  • New Updates

    Array of Pointers To String


    Array of Pointers To String

    एक String को हमेंशा एक One – Dimensional Array के रूप में Memory में Store होता है | इस Array को यदि Pointers के प्रयोग से उपयोग में लेना हो तो हम एक Pointer Variable Declare करते हैं और उस Pointer Variable में उस String का Base  Address दे देते हैं |

    इस Pointer  को Increment करके हम उस Array में अलग – अलग Locations पर स्थित Characters पर Pointer द्वारा Move कर सकते हैं | इस तरह से हम कह सकते हैं कि एक ऐसा One Dimensional Array जिसमें String Store हो, को एक ही Pointer द्वारा Access किया जा सकता है |

    इसी तर्क पर यदि हम आगे बढ़ें तो ये भी कह सकते हैं कि एक String प्रकार के One – Dimensional Array का Base Address प्राप्त करके यदि हम उस String के हर Character के साथ प्रक्रिया कर सकते हैं तो फिर एक ऐसा Two – Dimensional Array जिसमें कई Strings हो को भी एक Pointer द्वारा Access किया जा सकता है | कैसे ? आईये समझने कि कोशिश करते हैं |

    हमने Pointers के बारे में पढते समय ये बताया था कि एक Two – Dimensional Array को उस Array कि संख्या के अनुसार कई One – Dimensional Array के रूप में मान सकते हैं | यदि एक ऐसा Pointer प्रकार का Array Declare किया जाए , जिसमें हर One – Dimensional Array या Row का Base Address इस Array में Store कर दिया जाए तो हम इस Pointer Array द्वारा एक Two – Dimensional String Array को Handle कर सकते हैं |

    हम एक उदाहरण द्वारा इस बात को समझते हैं | माना यदि हमें किसी Variable में एक नाम Store करना जिसमें अधिकतम 10 अक्षरों का नाम Store हो सके तो हम निम्नानुसार एक One Dimensional Array Declare कर सकते हैं |

    
    char name[10];
    

    इस Array में हम केवल एक ही नाम Store कर सकते हैं | यदि हमें ये जरुरत हो कि हम 10 अक्षरों के 10 नाम Memory में Store करना चाहें तो या तो हमें इसी प्रकार के 10 अन्य Variables Declare करने होंगे जिसमें 10 अलग – अलग नाम Store किये जा सकें या फिर हम इस Array को ही ऐसा बना दें कि यही Array 10 नाम Accept कर सकें |

    यदि हम इसी Array द्वारा 10 नाम Memory में Store करना चाहते हैं , तो हमें इस Array को निम्नानुसार Two – Dimensional Array में परिवर्तित करना पडेगा |

    
    char name[10] [10];
    

    अब यदि इस Array में हम 10 अक्षरों तक के 10 नाम Store करें तो ये Memory में निम्नानुसार Store होंगे |

    हम Table में देख सकते हैं कि काफी Space Array द्वारा फालतू Reserve रहता है | यदि इसके स्थान पर एक Pointer Array Declare करने तो हम इस Space को बचा सकते हैं | हम एक Pointer Array में नाम Store करने के लिए निम्नानुसार Declaration कर सकते हैं –

    
    char *name[ ] = [“Shadab”];
    

     

    इस Declaration का मतलब है कि name नाम के Variable में String “Shadab” का Base Address है | यदि हम इस Pointer Array में Array Elements के Address Store ना करें यानी इसमें एक सामान Array ही रहने दे तो इसे हम निम्नानुसार भी लिख सकते हैं |

    
    char  name[ ] = “Shadab”;
    

    इस प्रकार से हम ये भी कह सकते हैं कि Array में “Shadab “ नाम का String Index Number 0 पर Store है | क्योंकि किसी Array में कोई भी पहला मान हमेंशा Index Number 0 पर Sore होता है | यानी हम इसे name[0] = “Shadab” भी लिख सकते हैं |

    इसका मतलब ये हुआ कि यदि Array को हम Pointer Array बनाते हैं तो इस Array में Index Number 0 पर String “Shadab” का Address Store होता है ( पूरा String नहीं ) और यदि हम इस Array को Pointer Array नहीं बनाते हैं तो यह एक char प्रकार का One – Dimensional Array ही होता है , जिसमें Characters का एक समूह जिसे String कहते है , Store होता है |

    माना कि String “Shadab” Memory में 1500 Storage Cell में जाकर Store होता है | तब name के Index Number 0 का Address 1500 होगा और ये String Access करने के लिए हमें Index Number 0 को name[0] Statement द्वारा Use करना पडेगा |

    यदि हम इस String को Pointer द्वारा Access करना चाहें तो हमें Pointer को Increment करना होगा , जिससे One By One Character Read होंगे | इसी Array को यदि Pointer प्रकार का Declare कर दिया जाए यानी *name कर दिया जाए तो इस Array में Index Number 0 पर Stored String “Shadab” का Base Address 1500 Store हो जाएगा | इस Pointer Array द्वारा भी यदि हम  Array के  Element को Access करना चाहें तो हमें name[0] Statement को ही Use करना होगा |

    यदि हम इस Array के मानों को Pointer द्वारा Read करना चाहें तो हम Character By Character इसे Read नहीं कर सकते हैं क्योंकि Variable का Address Stored होता है |

    इसलिए इस Array में केवल एक मान 1500 यानी String “Shadab” का Base Address Stored है ना कि String , जिसे Pointer को Increment करके One By One Character को Read किया जा सके |

    किसी Pointer array में किसी One – Dimensional Array का Base Address Store होना ये बताता है कि यदि इस Address के मान को Print किया जाए तो हमें पूरा String प्राप्त हो जाएगा | इस दोनों के अंतर को निम्न चित्र द्वारा बताया जा रहा है |

    
    char name[ ] = {“Shadab”};
    
    
    char *name[ ] = {“Shadab”};
    

     char *name = {“Shadab”}; को हम ये भी कह सकते हैं कि Array Name के Index Number 0 पर Element के रूप में एक One – Dimensional Array का Base Address Stored है | यानी name[0] = {“Shadab”};

    चुंकि Pointer Array *name एक One – Dimensional Array है और इसमें केवल एक ही Address Stored है | इसलिए हम चाहें तो इसमें आवश्यकतानुसार और भी कई One – Dimensional Arrays के Address Store कर सकते हैं | ऐसा करने के लिए हम निम्नानुसार Initialization कर सकते हैं –

    
    char *name[ ] ={“Shadab”, “Inthekhab”};
    

    इस Declaration से String Inthekhab”}; नाम का एक और One – Dimensional Array बन जाएगा और इस Array का Base Address name [l] Location पर Store होगा | इसे भी चित्र में दिखाया गया है |

     

    
    char name[ ] = {“Inthekhab”};
    
    
    char *name = {“Shadab” , “Inthekhab”};
    

    इस प्रकार से हम देखते हैं कि किस तरह से हम एक One Dimensional Pointer Array से Two Dimensional String Array को handle कर सकते हैं | Pointer का इस प्रकार से प्रयोग करके हम काफी Memory बचा सकते हैं क्योंकि Pointer को जब इस प्रकार से use किया जाता है , तब हमें Array कि Size Declare नहीं करनी होती है | ये Matter अच्छी तरह से समझ में आ जाए इसके लिए यहां एक उदाहरण द्वारा इसे बताया जा रहा है |

     

    Program

    
    #include<stdio.h>
    main()
    {
    char *n[4];
    int j;
    clrscr();
    for(j=0;j<4;j++)
    {
    printf("\n Enter String %d", j+1);
    gets(n[j]);
    }
    printf("\nBase Address of Row1 is %u ",n[0]);
    printf("\nBase Address of Row2 is %u ",n[1]);
    printf("\nBase Address of Row3 is %u ",n[2]);
    printf("\nBase Address of Row4 is %u ",n[3]);
    printf("\nValue of Row1 is %s ",n[0]);
    printf("\nValue of Row2 is %s ",n[1]);
    printf("\nValue of Row3 is %s ",n[2]);
    printf("\nValue of Row4 is %s ",n[3]);
    getch();
    }
    
    Output
    
    Enter String 1 Shadab
    Enter String 2 Inthekhab
    Enter String 3 Naushad
    Enter String 4 Saba
    Base Address of Row1 is 3432
    Base Address of Row2 is 36002
    Base Address of Row3 is 12803
    Base Address of Row4 is 36518
    Value of Row1 is Shadab
    Value of Row2 is Inthekab
    Value of Row3 is Naushad
    Value of Row4 is Saba
    

    इस Program में हम जब भी कोई String Input करते हैं , तो वह String Memory में किसी Location पर जा कर एक One Dimensional Array के रूप में Store हो जाती  है |

    चुंकि हमने यहां जो Array लिया है वो Pointer प्रकार का है और इस Array में केवल किसी भी One – Dimensional Array का Address ही Store हो सकता है | इसलिए हमारे द्वारा Input किया गया String Memory में इस Array में Store ना हो कर किसी भी अन्य Location पर Store हो जाता है |

    यहां हमने string Input करने के लिए एक Pointer प्रकार के Variable को माध्यम बनाया है इसलिए इस Pointer Array में उस String के प्रथम अक्षर का Address या Base Address उस Index Number के स्थान पर Element के रूप में Store हो जाता है जिस Index Number के प्रयोग से हम हमारे  String Input करते हैं |

    इस प्रकार से हम One – Dimensional Pointer Array द्वारा एक Two – Dimensional String Array को प्रयोग कर सकते हैं | इसी Array of Pointers To String का प्रयोग Command Line Arguments को Accept करने के लिए किया जाता है |

    कई बार हमें जरूरतें पडती हैं , जिसमें किसी मान को Store तो एक Character Array के रूप में किया गया होता है , लेकिन Access करते समय उस Character Array में Stored मान को Integer या Float प्रकार के मान के रूप Use करना होता है |

    इस स्थिति में हमें उस Array में Stored मान को Integer या Float प्रकार के मान में Convert करने की जरुरत पडती है | चलिए , हम इसी प्रकार की एक समस्या का समाधान प्राप्त करने की कोशिश करते हैं | निम्न Example Program में हम एक Character Array में Stored Integer प्रकार के मान को Integer प्रकार के मान में Convert करने के लिए एक Function Create कर रहे हैं |

    Program

    
    #include <ctype.h>
    /* atoi: convert String Integer to Numerical Integer */
    int atoi(char strInteger[])
    {
    int i, n, sign;
    for (i = 0; isspace(strInteger[i]); i++) /* skip white space */
    ;
    sign = (strInteger[i] == '-') ? -1 : 1;
    if (strInteger[i] == '+' || strInteger[i] == '-')/* skip sign */
     i++;
    for (n = 0; isdigit(strInteger[i]); i++)
    n = 10 * n + (strInteger[i] - '0');
    return sign * n;
    }
    

    इस Function में हमने ctype.h नाम की Header File को Include किया है | इस Header File में Character Manipulation से सम्बंधित कई Functions हैं , जिहें हम हमारी जरुरत के आधार पर Use कर सकते हैं | जब हमें किसी Character Array में String Format में Stored String Integer को Numerical Integer में Convert करना होता है , तब हम उस Character Array को इस function में Formal Argument के रूप में Pass करते हैं |

    ये Function Argument के रूप में Calling Function से String Integer को प्राप्त करता है और उस String Integer को Numerical Integer मान में Convert करके फिर से Calling Function में Return कर देता है |

    जब ये Function Call होता है , तब Argument के रूप में इसमें String Integer Array को भेजा जाता है , जिसमें String Format में Integer मान Stored होता है | ये Function उस मान को strInteger नाम के Array Variable में प्राप्त करता है |

    किसी Character Array में जो  Integer मान Store होता है , उस मान को Store करते समय String Integer मान से पहले Space का प्रयोग किया गया हो सकता है , जबकि एक Integer प्रकार के मान में कोई Space नहीं होता है | इसलिए सबसे पहले हमें किसी String Integer में स्थित Spaces को Remove करना होता है |

    किसी Character Array में से Space  को खोजने का काम करने के लिए हम ctype.h नाम के Header File में Define किये गए isspace() Function को Use करते हैं | ये Function उस स्थिति में True Return करता है , जब इसे किसी Character Array में Space , Tab , New Line Character या कोई अन्य Blank Space Character प्राप्त होता है | इस Function को निम्नानुसार एक for loop में Use किया गया है :

    
    for (i=0; isspace (strInteger[i]); i++) /*skip while space*/
    

    इस Loop की Body नहीं है , क्योंकि इस Loop में हमें कोई Extra काम नहीं करवाना है | चुंकि इस Function में आने वाला Argument एक One – Dimensional Character Array है और किसी 1-D Array में स्थित सभी Characters को एक Index Number द्वारा Access किया जा सकता है |

    इस Loop से हमारी Requirement भी यही है कि हम इस Character Array के हर Element पर जा कर ये Check करें , कि उस Index Number कि Position पर कोई Space Store है या नहीं | ये Loop तब तक चलता है , जब तक Computer को Character Array में Blank Space प्राप्त होता रहता है , जैसे ही isspace() Function को Blank Space के अलावा कोई Character प्राप्त होता है , ये Function False Return करता है , जिससे Loop Terminate हो जाता है |

    उदाहरण के लिए मानलो कि किसी Character Array में Integer मानों से पहले चार Space है , तो ये Loop चार बार चलता , जिससे Variable i का मान 3 हो जाता , जो इस बात का Signal है कि Actual Integer मान Character Array के Index Number 3 से शुरू हो रहा है |

    किसी Character Array में किसी मान को Store करते समय उसके साथ sign का चिन्ह भी Store किया गया हो सकता है | इस स्थिति में अब हमें ये Check करना होता है कि Character Array में ‘+’ या ‘-‘ जैसा कोई चिन्ह है या नहीं | इस बात को Check करने के लिए Program में अगले Statement के रूप में निम्नानुसार एक Ternary Operator Use किया गया है |

    
    sign = (strInteger [i] == ‘- ‘ )? 1:1;
    

    मानलो कि हमारे Character Array में चार Space थे जिसे पिछले Loop का प्रयोग करके हमने skip किया | skip करने पर I का मान 3 हो गया , जो कि Character Array के Index Number 3 को Specify करता है | चुंकि अब Space नहीं है इसका मतलब ये है कि Space के अलावा कोई Character है वह Character Minus (-) है या नहीं इस बात की जांच करने के लिए हमने इस Statement को लिखा है |

    ये Statement Character Array के Index Number 3 को Minus Sign के लिए Check करता है और यदि Computer को इस Index Number पर Minus (- ) का Character मिलता है , तो Computer Sign नाम के Variable में -1 Store कर देता है , जो इस बात का संकेत होता है , कि Character Array में एक Minus Sing वाली संख्या Stored है | चिन्ह का पता लगाने के बाद फिर से एक Loop चलाया जाता है और ये Loop अब Character Array में Stored सभी Digits को Integer में Convert करने का काम करता है |

    
    for(n=0; isdigit(strInteger[i]); i++)
         n = 10*n + (strInteger[i] – ‘0’);
    

    इस Loop में हमने एक Variable n को 0 assign किया है | फिर ctype.h नाम की Header File के isdigit() Function को Use करके Index Number i की Position पर Stored Character को इस बात के लिए Check किया है , कि वहां पर कोई Digit Stored है या नहीं |

    यदि Index Number i की Position पर कोई Digit होता है , तो ये Program True Return करता है | जब ये Program True Return करता है , तब Computer for Loop के अगले Statement को Execute करता है | इस Statement में (strInteger [i] – ‘0’ ) Code Use किया गया है | इस Code को Use करने का कारण ये है , कि Character Array में हर Position पर किसी भी Character की ASCII Value Stored होती है |

    मानलो कि Character Array में 23 Stored है , जिसे Integer में Convert करना है | इस स्थिति में वास्तव में Character Array में 2 3 Stored नहीं है बल्कि इनकी ASCII Value 50 51 Stored है | इसलिए यदि हम Directly इसे ज्यों का त्यों use करें यानी (strInteger[i] –‘0’) Code के स्थान पर (strInteger [i] ) Code को Use करें , तो 50 को गुणा n में Stored मान 0 से होने पर 0 जो कि हमारा Required Result नहीं है |

    इस स्थति में जब हम strInteger Array के Index Number I की Location पर Character Format में Stored Digit की ASCII Value में से Integer मान 0 की ASCII Value को घटाते है , तो Resultant रूप में हमें Integer मान ही प्राप्त होता है |

    उदाहरण के लिए माना यदि हम मान 23 के 2 की बात करें , तो 2 के ASCII Code 50 में से 0 के ASCII Code 48 के घटाने पर 2 ही प्राप्त होता है , लेकिन ये 2 एक Integer मान होता है , ना कि Character मान |

    Character Array में Stored String Integer मान को Numerical Integer मान में Convert करने के बाद यदि संख्या Minus वाली होती है , तो मान -1 Sign नाम के Variable में Store हो जाता है , जिसका प्रयोग Function के अन्त में Return होने वाले Integer मान के Sign को Change करने के लिए किया जाता है |

    जब atoi() Function से किसी Minus Sign के मान को Return करना होता है , तब Sign Variable में Stored माने -1 को Return किये जाने वाले मान n गुणा करके Resultant मान को Return कर दिया जाता है , जो कि एक Negative मान होता है |

    इसी तरह से यदि हमें किसी Character Array में Stored String Formatted Float , Double , Long या किसी अन्य प्रकार के मान को Numerical Form में Convert करना हो , तो हम इसी तरह के Process को Use करके ये काम कर सकते है | वैसे इस तरह के Conversion Functions को पहले से ही Develop करके Library के रूप में हमें प्रदान कर दिया गया है , जिन्हें हम Directly Use कर सकते हैं |

    किसी Character Array में Stored String को हम Reverse में Convert करने के लिए भी Function बना सकते हैं | इस Function कि जरुरत उस स्थिति में पडती है , जब हम किसी मान को किसी Character Array में Store करते है और वह मान उस Character Array में Reverse Format में Store हो जाता है |

    
    /* reverse: reverse string s in place */
     #include <string.h>
     void reverse(char str[])
     {
     int c, i, j;
     for (i = 0, j = strlen(str)-1; i < j; i++, j--)
    {
     c = str[i];
     str[i] = str[j];
     str[j] = c;
     }
     }
    
    

    जब इस Function में किसी Character Array को भेजा जाता है , तब वह Character Array str नाम के Argument में आकार Store हो जाता है | इस Function में एक for Loop चलाया गया है और इस for Loop में एक ही बार में एक Variable i को Increment किया  गया है साथ ही दूसरे Variable j के मान को Decrement किया गया है |

    Loop को इस तरह चलाया गया है कि Character Array के First  Index Number को Last Index Number से swap करता है | फिर Second Index Number के Character को Second last Character से Swap करता है और ये प्रक्रिया तब तक चलता है , जब तक कि i का मान j के मान से ज्यादा नहीं हो जाता है | ये Loop तभी Terminate होता है , जब Character Array में Stored पुरे String Reverse हो जाती है | इस Function को हम निम्नानुसार Use कर सकते हैं :

    
    
    /* reverse: reverse string s in place */
     #include <string.h&t;
     void reverse(char str[])
     {
     int c, i, j;
     for (i = 0, j = strlen(str)-1; i < j; i++, j--)
    {
     c = str[i];
     str[i] = str[j];
     str[j] = c;
     }
     }
    

    Program

    
    #include <stdio.h>
    #include <conio.h>
    main()
    {
    char name[] = "Shadab";
     reverse(name);
     puts(name);
     getch();
    }
    Output
    badahS
    

    जिस तरह से किसी Character Array में String Format में Stored Numerical मान को Calculation में उपयोग में लेने के लिए उसे Integer, Float जैसे किसी Format में बदलने की जरुरत पडती है , उसी तरह से कई बार हमें किसी Basic Data Type के Variable में Stored मान को Character Array में Store करने की भी जरुरत पडती है | इस प्रकार की जरुरत को पूरा करने किए लिए हम पिछले प्रकार के atoi() Function का Reverse Function itoa() Create कर सकते है |

    
    /*itoa: convert Numerical Integer to Characters Array Integer*/
     void itoa(int n, char str[])
     {
     int i = 0, sign;
     if ((sign = n) < 0) /* record sign */
     n = -n; /* make n positive */
    do /* generate digits in reverse order */
    {
     str[i++] = n % 10 + '0'; /* get next digit */
     }while ((n /= 10) > 0); /* delete it */
     if (sign < 0)
     str[i++] = '-';
     str[i] = '\0';
     reverse(str);
     }
    
    

    ये Function दो Arguments लेता है | पहला Argument वह Integer मान होता है , जिसे String str में Store करना है और दूसरा Argument एक Character Array होता है , जिसमें पहले Argument के Numerical Integer मान को Character Array में String के रूप में Store करना होता है |

    जब ये Function Call किया जाता है , तब सबसे पहले ये Check किया जाता है कि ये संख्या Positive है या नहीं | Sign Check करने के लिए एक if Statement में ये Check करवाया जाता है कि संख्या 0 से छोटी होती है या नहीं | यदि संख्या 0 से छोटी हो तो sign नाम के Variable में Sign को Store किया जाता है और Negative Sign वाली संख्या को निम्न Statement द्वारा Positive संख्या में Convert कर लिया जाता है |

    
    if ((sign=n)<0) /* record sign */
    n = -n;   /* make n positive */
    

    Character Array में Store किये जाने वाले मान को Positive मान में Convert करने के बाद अब उस मान से एक – एक Digit को Character में Convert करने के लिए निम्नानुसार एक do… while Loop का प्रयोग किया जाता है |

    
    do     /* generate digits in reverse order */
    {
       Str[i++] = n%10+’0’ ; /* get next digit */
    } while ((n/= 10)>0);   /* delete it */
    
    

    इस Loop में सबसे पहले 10 का भाग देकर शेषफल प्राप्त किया जाता है | ये शेषफल Store किये जाने वाले Integer का अंतिम digit होता है | चुंकि अभी भी ये मान एक Digit है , जबकि Character Array में Store करने से पहले इसे Character में Convert करना जरुरी है , इसलिए इसमें मान Zero की ASCII Value को जोड़ कर इस मान को Digit से  Character में Convert किया गया है |

    Digit से Character में Convert होने के बाद इस Character Array str के Index Number 0 पर Store कर दिया जाता है और उसके बाद i के मान को Increment किया जाता है |

    इसके बाद While Condition Brace  में Store किये जाने वाले Integer मान में 10 का भाग देकर Integer मान की अंतिम Digit को Delete किया जाता है | अंतिम Digit को Delete करने के बाद Check किया जाता है कि क्या Integer मान अभी भी 0 से बड़ा है या नहीं |

    यदि Integer का मान 0 से बड़ा है , तो इसका मतलब ये होता है कि Integer में अभी भी कोई Digit है जिसे Character में Convert करना बाकी है , इसलिए ये Loop फिर से Iterate होता है और फिर से इस Integer संख्या में 10 का भाग देकर Remainder के रूप में Integer के अंतिम Digit को प्राप्त किया जाता है | ये प्रक्रिया तब  तक चलती रहती है , जब तक कि Integer की सभी Digits Character Array में Store नहीं हो जाती है |

    एक बार Character Array str में Integer मान के Store हो जाने के बाद अब उस Integer के Sign को Character Array में Store करने की जरुरत पडती है | इसके लिए निम्न Statements का प्रयोग किया जाता है |

    
    if (sign <0)
    str[i++] =’-‘;
    ……
    str[i] = ‘\0’;
    

    ये Statement Check करता है कि Sign का मान 0 से छोटा है या नहीं | यदि जो Integer हमने Character Array str में Store किया है, वह Negative यानी 0 से छोटा होता है , तो इस Statement की if  Condition True हो जाती है और Character Array में Index Number i की Position पर Minus के Sign को Store कर दिया जाता है | अन्त में String के अन्त को Specify करने के लिए Character Array में अंतिम Character के रूप में NULL को Store किया जाता है , जो String के अन्त को Specify करता है |

    चुंकि हमने Character Array में जिस Integer को Store किया है , वह Integer Reverse Order में Store हुआ है | इसलिए Reverse Order में Stored Integer मान को Forward Order में Convert करने के लिए हमें reverse() नाम के Function को Use करना होता है | ये Function हमने इस Function से पहले Develop किया है | ये Function Character Array में Stored Integer के String Representation को Reverse Order में Convert कर देता है |

    जिस तरह से हमने एक Integer प्रकार के मान को एक Character Array में String के रूप में Store किया है , ठीक इसी तरह से अन्य प्रकार के मानों को भी एक String Representation के रूप में किसी Character Array में Store कर सकते हैं | इस Function को Practically Use करने के लिए हम निम्नानुसार एक main() Function Develop कर सकते हैं |

    
    #include <stdio.h>
    #include <conio.h>
    main()
    {
    char str[15];
     int Integer = 30555;
     itoa(Integer, str);
     reverse(str);
     puts(str);
     getch();
    }
    

    No comments

    Post Top Ad

    ad728

    Post Bottom Ad

    ad728