برای روشن کردن ترمینال، کلیک کن یا هر کلیدی را بزن

پرش به محتوای اصلی
>_
درس ۶مقدماتی

کاراکتر‌ها و کدهای ASCII

از نوع char تا کدهای اسکی، تبدیل حروف بزرگ/کوچک و خواندن کلید بدون Enter با getch

معمولی
مبانی و مقدمات•صفحات ۱۳-۱۴•۲۵ دقیقه•۲٬۴۹۵ کلمهزمان مطالعه: ۰ دقیقه
فهرست این درس
// اهداف۵
  • شناخت نوع داده `char` (۱ بایت) و نحوه تعریف و مقداردهی آن با کوتیشن تکی `'A'`
  • آشنایی با جدول ASCII و به خاطر سپردن کدهای کلیدی: `'A'=65`, `'a'=97`, `'0'=48`
  • تبدیل دوطرفه بین `char` و `int` (هم implicit و هم با cast صریح `int(ch)`)
  • یادگیری ترفند تبدیل حروف بزرگ به کوچک (کم کردن ۳۲ یا جمع `'a'-'A'`) و تبدیل رقم کاراکتری به عدد (`ch - '0'`)
  • آشنایی با تابع `getch()` از `<conio.h>` و درک اینکه چرا این تابع غیراستاندارد است و جایگزین‌های آن

نوع داده char: حروف در حافظه کامپیوتر

تا اینجا با اعداد صحیح (int) و اعشاری (float/double) کار کردیم. اما برنامه‌های واقعی نیاز به ذخیره حروف هم دارند: نام کاربر، رمز عبور، متن پیام و...

در ⁦C++⁩ نوع داده‌ی char برای ذخیره یک کاراکتر استفاده می‌شود. هر char دقیقاً ۱ بایت (۸ بیت) فضا اشغال می‌کند و می‌تواند ۲۵۶ مقدار متفاوت بگیرد. دامنه دقیق به پیاده‌سازی بستگی: signed char (پیش‌فرض در x86) از ۱۲۸- تا ۱۲۷، unsigned char از ۰ تا ۲۵۵. برای متن ASCII کلاسیک (کدهای ۳۲-۱۲۶) این فرق مهم نیست.

کامپیوتر در حافظه فقط اعداد ذخیره می‌کند، نه حروف. پس چطور حروف را نمایش می‌دهیم؟

پاسخ: با استفاده از یک جدول کدگذاری که به هر حرف یک عدد مشخص اختصاص می‌دهد. معروف‌ترین این جدول‌ها ASCII است.

تعریف و مقداردهی char:

main.cppcpp

توجه: در ⁦C++⁩ کوتیشن تکی '...' برای یک کاراکتر و کوتیشن دوتایی "..." برای رشته (string) استفاده می‌شود. نوشتن char ch = "A" خطای کامپایل است!

جدول ASCII چیست؟

ASCII (American Standard Code for Information Interchange) یک جدول استاندارد است که به ۱۲۸ کاراکتر رایج، کدهای عددی ۰ تا ۱۲۷ را اختصاص داده است. هر char در حافظه، در واقع این عدد است.

بخش‌های مهم جدول ASCII که باید حفظ کنید:

محدودهکاراکتر‌هامثال
۰–۳۱کاراکتر‌های کنترلی (مثل Enter، Tab)غیرقابل چاپ
۳۲فاصله (space)' '
۴۸–۵۷ارقام 0 تا 9'0'=48، '9'=57
۶۵–۹۰حروف بزرگ انگلیسی A تا Z'A'=65، 'Z'=90
۹۷–۱۲۲حروف کوچک انگلیسی a تا z'a'=97، 'z'=122

دو نکته طلایی:

۱. فاصله بین حرف بزرگ و کوچک دقیقاً ۳۲ است. یعنی 97 - 65 = 32. این برای تبدیل بزرگ/کوچک حیاتی است.

۲. فاصله بین کاراکتر رقم '0' و عدد 0 دقیقاً ۴۸ است. یعنی '0' در حافظه به‌صورت عدد ۴۸ ذخیره می‌شود، نه ۰!

برای کشیدن جدول کامل ASCII به بخش مرجع در انتهای درس نگاه کنید.

مثال ۱: تعریف char و چاپ آن

این برنامه نشان می‌دهد که چطور یک کاراکتر را تعریف و چاپ می‌کنیم. وقتی cout << ch را می‌نویسیم، ⁦C++⁩ مقدار عددی حافظه را به‌عنوان کاراکتر نمایش می‌دهد (یعنی حرف A).

اما اگر cout << (int)ch را بنویسیم، همان مقدار عددی به‌صورت عدد چاپ می‌شود (یعنی ۶۵). این یکی از مهم‌ترین ترفند‌های ⁦C++⁩ است که در ادامه عمیق‌تر بررسی می‌کنیم.

تعریف char ch = 'A' و چاپ حرف و کد اسکی آنcpp
خروجی برنامه
Character: A
ASCII code: 65
Character: 5
ASCII code: 53
در حال باز کردن ویرایشگر…

تبدیل بین char و int

چون char در حافظه در واقع یک عدد صحیح (۸ بیتی) است، می‌توانیم آن را به int و برعکس تبدیل کنیم. این تبدیل دوطرفه و خودکار (Implicit) است:

main.cppcpp

یا برعکس:

main.cppcpp

سه روش برای تبدیل صریح:

main.cppcpp

این تبدیل‌ها آن‌قدر پرکاربردند که در بسیاری از الگوریتم‌های کاراکتری (تبدیل حروف، شمارش حروف صدادار، رمزنگاری ساده) استفاده می‌شوند.

نکته: متغیر char می‌تواند مقدار منفی هم بگیرد (اگر signed char باشد)؛ اما برای کاراکتر‌های ASCII استاندارد، مقدار همیشه مثبت است. اگر می‌خواهید مطمئن شوید مقادیر منفی نمی‌گیرد، از unsigned char استفاده کنید (محدوده ۰ تا ۲۵۵).

مثال ۲: تبدیل char به int و برعکس

این برنامه دو مثال کلاسیک از صفحه ۱۳ جزوه را پوشش می‌دهد:

۱. عدد → کاراکتر: عدد ۹۷ در حافظه‌ی یک char، حرف کوچک 'a' است. ۲. کاراکتر → عدد: حرف 'B' در حافظه‌ی یک int، عدد ۶۶ است.

نکته: در نسخه اصلی جزوه، یک اشتباه تایپی وجود داشت: نوشته بودند کد 'B' اسکی برابر ۹۸ است، اما در واقع B بزرگ کد ۶۶ دارد و b کوچک کد ۹۸. این اشتباه را در بخش comparison انتهای درس به طور کامل بررسی می‌کنیم.

مثال‌های صفحه ۱۳: چاپ کاراکتر معادل عدد و برعکسcpp
خروجی برنامه
a
66
66 66 66
در حال باز کردن ویرایشگر…

تفاوت حروف بزرگ و کوچک: اختلاف ثابت ۳۲

فاصله بین 'A' (کد ۶۵) و 'a' (کد ۹۷) دقیقاً ۳۲ است. این اختلاف برای تمام حروف انگلیسی ثابت است:

حرف بزرگکدحرف کوچککداختلاف
A65a9732
B66b9832
C67c9932
............32
Z90z12232

دو روش برای محاسبه این اختلاف:

۱. مستقیماً عدد ۳۲ را کم یا زیاد کنیم:

main.cppcpp

۲. به‌صورت قابل‌حمل با فرمول 'a' - 'A' (تمیزتر و قابل‌حمل‌تر):

main.cppcpp

روش دوم بهتر است چون در کدهایی که ممکن است بعداً به Unicode یا سیستم‌های دیگر منتقل شوند، انعطاف بیشتری دارد. همچنین خواننده کد متوجه می‌شود که «این عدد ۳۲ از کجا آمده».

مثال ۳: تبدیل حرف بزرگ به کوچک

این مثال از صفحه ۱۴ جزوه است. الگوریتم ساده است:

۱. یک متغیر d برای نگه‌داری اختلاف بین حروف بزرگ و کوچک تعریف می‌کنیم (d = 'a' - 'A' = 32). ۲. کاراکتر بزرگ را از ورودی می‌گیریم. ۳. با عملگر -= اختلاف را از کاراکتر کم می‌کنیم.

نکته: چون از getch() (غیراستاندارد) استفاده می‌کنیم، در محیط‌های مدرن GCC/Clang ممکن است خطا بدهد. در ادامه با جایگزین استاندارد cin هم نسخه می‌نویسیم.

برنامه‌ای که یک حرف بزرگ را می‌گیرد و معادل کوچک آن را چاپ می‌کندcpp
خروجی برنامه
Enter an uppercase letter: G
Lowercase: g
در حال باز کردن ویرایشگر…

تبدیل رقم کاراکتری به عدد صحیح

یکی از تله‌های کلاسیک: عدد 5 (به‌عنوان int) با کاراکتر '5' (به‌عنوان char) یکی نیستند!

  • عدد صحیح 5 در حافظه به‌صورت 00000101 ذخیره می‌شود.
  • کاراکتر '5' در حافظه به‌صورت عدد اسکی 53 (یعنی 00110101) ذخیره می‌شود.

وقتی کاربر عدد ۵ را وارد می‌کند، cin >> int_n مقدار 5 می‌گیرد، اما cin >> char_ch کاراکتر '5' (با کد اسکی ۵۳) را می‌گیرد.

تبدیل '5' (char) به 5 (int):

main.cppcpp

چرا این کار می‌کند؟ چون در جدول ASCII ارقام '0' تا '9' پشت سر هم آمده‌اند (کدهای ۴۸ تا ۵۷). پس اگر '0' (کد ۴۸) را از '5' (کد ۵۳) کم کنیم، عدد ۵ به دست می‌آید.

تبدیل برعکس (int به char):

main.cppcpp

این ترفند در پردازش ورودی کاراکتری، استخراج ارقام از رشته، و ساخت اعداد از ارقام مجزا بسیار کاربرد دارد.

مثال ۴: سه برابر یک رقم کاراکتری

این مثال از صفحه ۱۴ جزوه است. هدف: ورودی '5' (به‌عنوان کاراکتر) → خروجی 15 (یعنی ۳×۵).

الگوریتم: ۱. کاراکتر را با getch() یا cin بخوانیم. ۲. آن را به عدد صحیح تبدیل کنیم با کم کردن '0'. ۳. در عدد ۳ ضرب کنیم و چاپ کنیم.

نکته: اگر کاربر '5' را وارد کند، ch - '0' = 53 - 48 = 5 می‌شود و سپس 3 * 5 = 15.

کاراکتر رقم را می‌گیرد و سه برابر مقدار عددی آن را چاپ می‌کندcpp
خروجی برنامه
Enter a digit: 5
3 * 5 = 15
در حال باز کردن ویرایشگر…

تفاوت `'0'` و `0`: یک تله کلاسیک

یکی از منابع رایج باگ در برنامه‌های مبتدی، اشتباه گرفتن '0' (کاراکتر صفر) با 0 (عدد صحیح صفر) است.

عبارتنوعمقدار در حافظه
'0'char48 (کد اسکی کاراکتر صفر)
0int0
'\0'char0 (کاراکتر پاین‌ت‌های رشته، Null Terminator)

مثال خطای رایج:

main.cppcpp

همچنین به '\0' دقت کنید که در رشته‌های C-style (آرایه char) برای نشان‌دادن پایان رشته استفاده می‌شود. این کاراکتر مقدار عددی ۰ دارد اما به‌صورت '\0' نوشته می‌شود.

قاعده طلایی: همیشه با کوتیشن تکی '…' یک کاراکتر، و با کوتیشن دوتایی "…" یک رشته بنویسید.

تابع getch(): خواندن کلید بدون Enter

وقتی با cin >> ch یک کاراکتر را می‌خوانیم، دو ویژگی آزاردهنده دارد:

۱. کاربر باید بعد از تایپ، Enter هم بزند. ۲. کاراکتر تایپ‌شده روی صفحه نمایش دیده می‌شود (Echo).

در برنامه‌هایی مثل منوها، بازی‌ها، یا رمز عبور، این رفتار مطلوب نیست. می‌خواهیم با فشردن یک کلید، بلافاصله آن را بخوانیم بدون نیاز به Enter و بدون نمایش.

تابع getch() این کار را انجام می‌دهد:

main.cppcpp

این تابع جزو هدر <conio.h> (Console Input/Output) است.

کاربرد‌های رایج getch():

  • توقف برنامه تا فشردن یک کلید (در انتهای برنامه)
  • خواندن کلید‌های جهت‌نما (Arrow Keys) در منوها
  • گرفتن رمز عبور بدون نمایش کاراکتر‌ها
  • ساخت بازی‌های تعاملی ساده

اما این تابع غیراستاندارد است. در ادامه می‌بینیم چه جایگزین‌هایی دارد.

مثال ۵: برنامه کامل نمایش کد ASCII

این مثال از صفحه ۱۳ جزوه است و یکی از کلاسیک‌ترین برنامه‌های آموزشی ⁦C++⁩ است. هدف: خواندن یک کاراکتر از کاربر و نمایش کد اسکی آن.

اگر کاربر کلید 'A' را فشار دهد، خروجی باید این باشد:

main.cppcpp

نکته: در محیط‌های مدرن، <conio.h> ممکن است در دسترس نباشد. در آن صورت، نسخه با cin را به‌کار ببرید (که Enter می‌خواهد اما در همه‌جا کار می‌کند).

یک کاراکتر را با getch() می‌خواند و کد اسکی آن را چاپ می‌کندcpp
خروجی برنامه
Press any key...
The ASCII code of A is: 65

(اگر کلید A فشار داده شود)

getch() غیراستاندارد است

هدر <conio.h> و تابع getch() جزو استاندارد ⁦C++⁩ نیستند. این هدر مربوط به کامپایلر‌های قدیمی داس‌ ویندوز (مثل Turbo ⁦C++⁩ و Borland ⁦C++⁩) است.

مشکلات:

  • در GCC (لینوکس، مک، ویندوز مدرن) به‌صورت پیش‌فرض موجود نیست.
  • در Clang (مک) هم موجود نیست.
  • در MSVC (Visual Studio) نسخه‌ای با نام _getch() (با زیرخط اول) موجود است.
  • در محیط‌های آموزشی آنلاین (Online Judges) معمولاً در دسترس نیست.

جایگزین‌های استاندارد:

۱. cin >> ch — ساده‌ترین و قابل‌حمل‌ترین، اما نیاز به Enter دارد و space را رد می‌کند.

۲. cin.get(ch) — فضای خالی را هم می‌خواند اما هنوز Enter لازم است.

۳. کتابخانه‌های کراس‌پلتفرم مثل ncurses (POSIX) یا conioex — برای منوها و بازی‌های واقعی.

۴. API سیستم‌عامل مثل termios در لینوکس/مک یا ReadConsole در ویندوز.

برای کدهای آموزشی ساده، بهترین انتخاب cin >> ch است. هرگز در پروژه‌های قابل‌حمل به getch() تکیه نکنید.

اصلاح اشتباه جزوه: ۹۸ به جای ۶۶ برای 'B'

در صفحه ۱۳ جزوه، یک اشتباه تایپی در توضیح مثال وجود داشت. در نمودار کناری، نوشته بودند «مقدار: ۹۸» برای کاراکتر 'B'، در حالی که کد اسکی 'B' (حرف بزرگ) برابر ۶۶ است. عدد ۹۸ مربوط به 'b' (حرف کوچک) است.

این خطا نشان می‌دهد چرا حفظ چند کد اسکی کلیدی مهم است:

  • 'A' = 65 (حرف بزرگ اول)
  • 'a' = 97 (حرف کوچک اول)
  • '0' = 48 (رقم صفر)
  • 'B' = 66 (دومین حرف بزرگ)
  • 'b' = 98 (دومین حرف کوچک)

توصیه: همیشه کد را اجرا کنید و خروجی را ببینید، نه فقط روی توضیحات دست‌نویس تکیه کنید.

نسخه اشتباه جزوه
کد دارای باگcpp
نسخه اصلاح‌شده و استاندارد
کد صحیحcpp

جدول مرجع ASCII (مهم‌ترین کاراکتر‌ها)

این جدول مرجع سریع برای کاراکتر‌های پرکاربرد را به خاطر بسپارید:

کاراکترکد اسکیتوضیح
'\0'0Null terminator (پایان رشته)
' '32فاصله (space)
'0'48رقم صفر
'1'49رقم یک
'9'57رقم نه
'A'65اولین حرف بزرگ
'Z'90آخرین حرف بزرگ
'a'97اولین حرف کوچک
'z'122آخرین حرف کوچک
'\n'10کاراکتر خط جدید (Enter)
'\t'9کاراکتر Tab

فرمول‌های مفید:

  • '9' - '0' = 9 (اختلاف ارقام، همیشه برابر مقدار عددی)
  • 'z' - 'a' = 25 (تعداد حروف کوچک منهای یک)
  • 'Z' - 'A' = 25 (تعداد حروف بزرگ منهای یک)
  • 'a' - 'A' = 32 (اختلاف بزرگ/کوچک)
  • 'A' - '0' = 17 (فاصله بین ارقام و حروف بزرگ، به‌خاطر داشته باشید که ارقام قبل از حروف آمده‌اند)

فلوچارت: خواندن کاراکتر و چاپ کد اسکی آن

این الگوریتم ساده اما کلاسیک: دریافت یک کاراکتر از کاربر و چاپ کد اسکی آن. این الگو در بسیاری از برنامه‌های تبدیل و پردازش متنی استفاده می‌شود.

flow.svg

مرور سریع مطالب

۱۶ بخش در این درس

تمرین‌ها

01
تمرین•حل کامل دارد

برنامه‌ای بنویسید که یک کاراکتر از ورودی بگیرد و چاپ کند که آیا حرف بزرگ است، حرف کوچک است، یا کاراکتر دیگری.

نمایش راهنما
از شروط if (ch >= 'A' && ch <= 'Z'), else if (ch >= 'a' && ch <= 'z'), else استفاده کنید.
02
تمرین•حل کامل دارد

برنامه‌ای بنویسید که یک حرف کوچک انگلیسی را بگیرد و معادل بزرگ آن را چاپ کند. از ترفند `'a' - 'A'` استفاده کنید.

نمایش راهنما
محاسبه diff = 'a' - 'A'; سپس ch = ch - diff; چاپ ch. شرط ch >= 'a' && ch <= 'z' را بررسی کنید.
03
تمرین•حل کامل دارد

برنامه‌ای بنویسید که یک کاراکتر رقم (مثل `'7'`) را بگیرد و مربع مقدار عددی آن را چاپ کند (یعنی ۴۹).

نمایش راهنما
تبدیل کاراکتر به عدد با n = ch - '0'; سپس چاپ cout << n * n;
04
تمرین•حل کامل دارد

برنامه‌ای بنویسید که یک کاراکتر از ورودی بگیرد و کد اسکی آن را چاپ کند. اگر حرف بزرگ بود، معادل کوچک آن را هم چاپ کند.

نمایش راهنما
از (int)ch برای کد اسکی استفاده کنید. سپس if (ch >= 'A' && ch <= 'Z') چاپ ch + 32.
// نکات-کلیدی۶
  • 01نوع `char` در ⁦C++⁩ یک بایت فضا اشغال می‌کند و در حافظه در واقع یک عدد صحیح (کد اسکی) ذخیره می‌شود.
  • 02کدهای اسکی مهم: `'A'`=65, `'a'`=97, `'0'`=48, `' '`=32. اختلاف حروف بزرگ/کوچک همیشه ۳۲ است.
  • 03تبدیل `char` ↔ `int` خودکار است؛ می‌توان از `int(ch)`, `(int)ch` یا `static_cast<int>(ch)` برای تبدیل صریح استفاده کرد.
  • 04تبدیل حرف بزرگ به کوچک: `ch = ch + 32` یا تمیزتر: `ch = ch + ('a' - 'A')`. تبدیل رقم کاراکتری به عدد: `n = ch - '0'`.
  • 05`'0'` (char با کد اسکی ۴۸) با `0` (int با مقدار ۰) فرق دارد. همیشه برای کاراکتر از کوتیشن تکی `'…'` و برای رشته از `"…"` استفاده کنید.
  • 06تابع `getch()` از `<conio.h>` غیراستاندارد است و در کامپایلر‌های مدرن (GCC/Clang) موجود نیست؛ در کدهای قابل‌حمل از `cin >> ch` یا `cin.get(ch)` استفاده کنید.
گام بعدی پیشنهادی

عملگر‌های مقایسه‌ای و دستور if

از == تا if/else: اولین گام در مسیر تصمیم‌گیری در برنامه

۲۰ دقیقهمقدماتی۱۵ بخش

شروع درس

جستجوی سریع در درس‌ها

نام درس، موضوع یا کلمه کلیدی را بنویسید و با Enter به آن بروید