# Native Code > برنامه نویسی با C > برنامه نویسی با زبان C و ++C > مبتدی: لطفا در مورد برنامه شمارش حروف یک کلمه راهنمایی کنید

## Cplus77

سلام، برنامه ای که یک کلمه را با استفاده از حلقه میگیره و تعداد حروف رو مشخص میکنه، چون در انتهای حلقه ; این علامت قرار داره و بعد از دستور حلقه دستور cout. رو داده که شمارنده چاپ بشه، و داخل حلقه شرط گذاشته که تا وقتیکه کاراکتر نقطه نشده باشه به شمردن و اضافه کردن به شمارشگر ادامه بده و قبلش استاد میگه وقتی آخر حلقه علامت ; میاد وبعد دستور cout میاد اون آیی در cout چاپ میشه که به ازای اون آی شرط حلقه دیگه برقرار نیست، وبعد مثال .abcde   رو زده خوب تو این مثال شمارنده وقتی اولش یک هست کاراکتر a رو میگیره چون نقطه نبود یکواحد زیادش میکنه و آی برابر 2میشه وبازهم نقطه نیست تا آخر، حالا وقتی به آی برابر 5میرسه کاراکتر e  رو میخونه و چون نقطه نبود یکواحد به آی زیاد میشه و آی 6  میشه ونقطه رو میگیره اینجا دیگه شرط حلقه بهم میخوره و از حلقه خارج میشه،  پس باید تو دستور cout  عدد 6 چاپ بشه ولی چرا 5 چاپ میشه؟؟؟؟؟؟؟
و یه سوال دیگه هم داشتم اینکه     ;a=2  
;++b=a*a چرا حاصل این عبارت 6 میشه

----------


## the king

> سلام، برنامه ای که یک کلمه را با استفاده از حلقه میگیره و تعداد حروف رو مشخص میکنه، چون در انتهای حلقه ; این علامت قرار داره و بعد از دستور حلقه دستور cout. رو داده که شمارنده چاپ بشه، و داخل حلقه شرط گذاشته که تا وقتیکه کاراکتر نقطه نشده باشه به شمردن و اضافه کردن به شمارشگر ادامه بده و قبلش استاد میگه وقتی آخر حلقه علامت ; میاد وبعد دستور cout میاد اون آیی در cout چاپ میشه که به ازای اون آی شرط حلقه دیگه برقرار نیست، وبعد مثال .abcde   رو زده خوب تو این مثال شمارنده وقتی اولش یک هست کاراکتر a رو میگیره چون نقطه نبود یکواحد زیادش میکنه و آی برابر 2میشه وبازهم نقطه نیست تا آخر، حالا وقتی به آی برابر 5میرسه کاراکتر e  رو میخونه و چون نقطه نبود یکواحد به آی زیاد میشه و آی 6  میشه ونقطه رو میگیره اینجا دیگه شرط حلقه بهم میخوره و از حلقه خارج میشه،  پس باید تو دستور cout  عدد 6 چاپ بشه ولی چرا 5 چاپ میشه؟؟؟؟؟؟؟
> و یه سوال دیگه هم داشتم اینکه     ;a=2  
> ;++b=a*a چرا حاصل این عبارت 6 میشه


اینکه خود کد رو درج می کردید خیلی بهتر موضوع رو شرح میداد تا اینکه روال کد رو توصیف کنید. اندیس ها با مقدار 0 شروع میشه، نه یک، به همین جهت اگر رشته 6 کاراکتر طول داشته باشه، اون کاراکتر ششم در خانه شماره 5 قرار داره، نه شماره 6
جدول اولویت عملگر ها رو اینجا ببینید، هر چقدر عملگر بالاتر باشه اولویت بیشتری داره و زودتر محاسبه میشه :
https://en.cppreference.com/w/cpp/la...tor_precedence
عملگر ++ نسبت به عملگر * اولویت داره، پس اول باید ++a محاسبه بشه و بعد نتیجه اش در a ضرب بشه. ++a که نباید با a++ اشتباه گرفته بشه، مقدار a رو یک واحد افزایش میده ولی مقداری که برمیگردونه قبل از افزایش ئه، یعنی a رو 3 می کنه ولی مقدار 2 رو بر میگردونه. بنابر این نتیجه محاسبه ++a عدد 2 میشه، ولی مقدار a رو به 3 تغییر میده. 
در ادامه اون 2 حاصل از ++a در مقدار a (که 3 شده) ضرب میشه، یعنی 2 * 3 
اگر بجای ++b = a * a کد b = a * ++a اجرا میشد، حاصل 9 بود، چون a++ مقدار a رو افزایش میده و همون مقدار افزایش یافته رو هم برمیگردونه، نه مقدار قبل از افزایش.

----------


## Cplus77

> اینکه خود کد رو درج می کردید خیلی بهتر موضوع رو شرح میداد تا اینکه روال کد رو توصیف کنید. اندیس ها با مقدار 0 شروع میشه، نه یک، به همین جهت اگر رشته 6 کاراکتر طول داشته باشه، اون کاراکتر ششم در خانه شماره 5 قرار داره، نه شماره 6
> جدول اولویت عملگر ها رو اینجا ببینید، هر چقدر عملگر بالاتر باشه اولویت بیشتری داره و زودتر محاسبه میشه :
> https://en.cppreference.com/w/cpp/la...tor_precedence
> عملگر ++ نسبت به عملگر * اولویت داره، پس اول باید ++a محاسبه بشه و بعد نتیجه اش در a ضرب بشه. ++a که نباید با a++ اشتباه گرفته بشه، مقدار a رو یک واحد افزایش میده ولی مقداری که برمیگردونه قبل از افزایش ئه، یعنی a رو 3 می کنه ولی مقدار 2 رو بر میگردونه. بنابر این نتیجه محاسبه ++a عدد 2 میشه، ولی مقدار a رو به 3 تغییر میده. 
> در ادامه اون 2 حاصل از ++a در مقدار a (که 3 شده) ضرب میشه، یعنی 2 * 3 
> اگر بجای ++b = a * a کد b = a * ++a اجرا میشد، حاصل 9 بود، چون a++ مقدار a رو افزایش میده و همون مقدار افزایش یافته رو هم برمیگردونه، نه مقدار قبل از افزایش.


خیلی ممنون از راهنماییتون;
11.pngطبق درسی که به ما داده اند، بعد از حلقۀ for اگز ; باشد، و پایین آن دستور cout داده باشند که i را چاپ بکند، آن i چاپ میشه که به ازای آن i شرط داخل حلقه نقض میشه. با همین برنامه، استاد ما یک .abcde داد که i برابر 5 چاپ شد. حالا پرسش من اینه که وقتی به ازای i=1 حرف a داخل ch میرود، چون می بیند نقطه نیست، یک واحد به i اضافه میشه و کلمۀ بعدی را می خواند و ... تا وقتی که i=5 میشه، حرف e داخل ch میرود و چون حرف e نقطه نبوده، یک واحد بدان اضافه میشه، i=6 میشه، وچون به نقطه میرسه، شرط داخل حلقه نقض میشه. پس داخل حلقه i از 1 تا 5 هست و به ازای i=6 حلقه نقض میشود. پس cout باید 6 را چاپ کند. 
با توجه به توضیحاتی که به ما داده اند، باید i=6 بشود، اما چرا برنامه، i را مساوی 5 چاپ میکند.

----------


## the king

> خیلی ممنون از راهنماییتون;
> 11.pngطبق درسی که به ما داده اند، بعد از حلقۀ for اگز ; باشد، و پایین آن دستور cout داده باشند که i را چاپ بکند، آن i چاپ میشه که به ازای آن i شرط داخل حلقه نقض میشه. با همین برنامه، استاد ما یک .abcde داد که i برابر 5 چاپ شد. حالا پرسش من اینه که وقتی به ازای i=1 حرف a داخل ch میرود، چون می بیند نقطه نیست، یک واحد به i اضافه میشه و کلمۀ بعدی را می خواند و ... تا وقتی که i=5 میشه، حرف e داخل ch میرود و چون حرف e نقطه نبوده، یک واحد بدان اضافه میشه، i=6 میشه، وچون به نقطه میرسه، شرط داخل حلقه نقض میشه. پس داخل حلقه i از 1 تا 5 هست و به ازای i=6 حلقه نقض میشود. پس cout باید 6 را چاپ کند. 
> با توجه به توضیحاتی که به ما داده اند، باید i=6 بشود، اما چرا برنامه، i را مساوی 5 چاپ میکند.


به یک نکته توجه نکرده اید، دریافت کاراکتر ها رو داخل حلقه شروع نمی کنید، اولین کاراکتر رو قبل از حلقه دریافت کرده اید.
اولین کاراکتر که همان a است قبل از شروع شدن حلقه در سطر دوم کد دریافت شده، بنابر این اون i = 1 بخاطر شمردن اون کاراکتر ئه که قبل از شروع حلقه دریافت شده، نه بخاطر کاراکتر های بعدی که قرار است داخل حلقه خوانده شود. 
البته منطق کد فرض کرده که حتما اولین کاراکتر دریافتی . نیست، چون اگر همون اولین کاراکتر . باشه این کد درست کار نخواهد کرد.
در داخل حلقه شما کاراکتر های b و c و d و e و . رو دریافت می کنید، مادامی که کاراکتر دریافتی . نباشه مقدار i افزایش خواهد یافت، برای همین چون b و c و d و e (چهار کاراکتر) برابر . نیستند، مقدار i چهار بار افزایش می یابد و 5 خواهد شد.
sample2.png

----------


## Cplus77

خیلی خیلی ممنون از پاسخ شما، فقط یه سوال دیگه 
تا زمانیکه شرط داخل حلقه برقرار باشد i افزایش پیدا می‌کند یعنی تا i برابر 5 میشه که شرط داخل حلقه برقرار هست، حالا چون انتهای حلقه سیمیکلون وجود داره بعد از اینکه شرط داخل حلقه نقض شد مگه نباید i ای که  بعد از حلقه سیمیکلون دار در دستور cout چاپ میشه همون i ای باشه که حلقه به ازای اون i شرطش نقض میشه، آخه تو توضیحات حلقه for گفتن وقتی انتهای حلقه سیمیکلون داره و بعد دستور cout i چاپ i رو میخواهد،  اون i ای باید چاپ بشه که به ازای اون i شرط داخل حلقه نقض میشود 
خیلی ببخشید بخاطر سوالایه زیادی که پرسیدم

----------


## the king

> خیلی خیلی ممنون از پاسخ شما، فقط یه سوال دیگه 
> تا زمانیکه شرط داخل حلقه برقرار باشد i افزایش پیدا می‌کند یعنی تا i برابر 5 میشه که شرط داخل حلقه برقرار هست، حالا چون انتهای حلقه سیمیکلون وجود داره بعد از اینکه شرط داخل حلقه نقض شد مگه نباید i ای که  بعد از حلقه سیمیکلون دار در دستور cout چاپ میشه همون i ای باشه که حلقه به ازای اون i شرطش نقض میشه، آخه تو توضیحات حلقه for گفتن وقتی انتهای حلقه سیمیکلون داره و بعد دستور cout i چاپ i رو میخواهد،  اون i ای باید چاپ بشه که به ازای اون i شرط داخل حلقه نقض میشود 
> خیلی ببخشید بخاطر سوالایه زیادی که پرسیدم


توضیحاتی که می دهید درسته، صرفا سعی می کنم با یک بیان دیگه ابهام رو برطرف کنم.
اول به حالت کلی for بپردازیم، قالب کلی for به صورت for (...) code ئه که (...) بخش تعریف کردن مقادیر اولیه، شرط حلقه و تغییر مقادیر ئه و code کدی است که باید داخل حلقه اجرا بشه. 
code میتونه فقط یک ; باشه یعنی هیچ کاری داخل حلقه انجام نده :

for (...) ;

یا میتونه فقط یک عبارت باشه، مثلا ;++x که چون فقط یک دستور ئه نیازی به مشخص کردن بلوک کد با { } نداره :

for (...) x++; 

یا میتونه چندین عبارت باشه که بصورت یک بلوک کد داخل { } نوشته بشه :

for (...) 
{
    x++;
    y++;
    z++;
}

در مثال شما هم بخش code خالیه و کاری برای اجرا شدن داخل حلقه وجود نداره.

حالا بیاییم اجرای کد رو از ابتدا بررسی کنیم، ورودی هم .abcde خواهد بود.
ابتدا ch با ;char ch تعریف میشه.
سپس کاراکتر a با ;cin >> ch داخل ch قرار میگیره.
سپس i با ;int i تعریف میشه.
حالا به حلقه for رسیده ایم، در ادامه مقدار اولیه i با ;i = 1 برابر 1 میشه.
سپس کاراکتر b با ()cin.get دریافت میشه.
و با '.'=! بررسی میشه که آیا کاراکتر دریافتی کاراکتر . نیست؟ که چون برابر نیست شرط حلقه برقرار ئه و اجرای حلقه ادامه پیدا می کنه.
و چون اجرای حلقه باید تکرار بشه با ++i مقدار i به 2 تغییر می کنه.
سپس کاراکتر c با ()cin.get دریافت میشه.
و با '.'=! بررسی میشه که آیا کاراکتر دریافتی کاراکتر . نیست؟ که چون  برابر نیست شرط حلقه برقرار ئه و اجرای حلقه ادامه پیدا می کنه.
و چون اجرای حلقه باید تکرار بشه با ++i مقدار i به 3 تغییر می کنه.
سپس کاراکتر d با ()cin.get دریافت میشه.
و با '.'=! بررسی میشه که آیا کاراکتر دریافتی کاراکتر . نیست؟ که چون  برابر نیست شرط حلقه برقرار ئه و اجرای حلقه ادامه پیدا می کنه.
و چون اجرای حلقه باید تکرار بشه با ++i مقدار i به 4 تغییر می کنه.
سپس کاراکتر e با ()cin.get دریافت میشه.
و با '.'=! بررسی میشه که آیا کاراکتر دریافتی کاراکتر . نیست؟ که چون  برابر نیست شرط حلقه برقرار ئه و اجرای حلقه ادامه پیدا می کنه.
و چون اجرای حلقه باید تکرار بشه با ++i مقدار i به 5 تغییر می کنه.
سپس کاراکتر . با ()cin.get دریافت میشه.
و با '.'=! بررسی میشه که آیا کاراکتر دریافتی کاراکتر . نیست؟ که چون برابر هست شرط حلقه برقرار نیست و اجرای حلقه خاتمه پیدا می کنه.
مقدار فعلی i از آخرین افزایش 5 مونده، نقض شرط حلقه هم زمانی رخ داده که i مقدار 5 داشته، پس در ادامه با ;cout << i مقدار 5 نمایش داده میشه.

و البته اون = ch داخل حلقه هم اضافی است و هم مطمئن نیستم که استادتون خودش به این نکته توجه کرده باشه که  '.'=!()ch = cin.get کاراکتر های دریافتی رو داخل ch قرار نمیده، مقدار حاصل از شرط (که 0 یا 1 ئه) رو داخل ch قرار میده. یعنی اول '.'=!()cin.get رو محاسبه می کنه که یا 0 ئه (false) یا 1 ئه (true) و بعد اون 0 یا 1 رو داخل ch قرار میده.
که اگر اینکار رو نمی کرد هم تاثیری نداشت، چون در ادامه استفاده ای از مقدار ch نمیشه.

    char ch;
    cin >> ch;
    int i;
    for (i=1; cin.get()!='.'; i++);
    cout << i;

----------


## Cplus77

خیلی خیلی ممنون از راهنماییتون، خیلی لطف کردید

----------

