انواع خطا در برنامه نویسی

هنگام برنامه‌نویسی حتماً به خطا برمی‌خوریم. همیشه در پروژه‌های نرم‌افزاری خطا وجود دارد، اما با روش‌های مختلف برنامه‌نویسی و با افزایش تجربه این خطا‌ها کاهش پیدا می‌کنند.

یکی از مهم‌ترین و بزرگ‎ترین تفاوت‌ها بین برنامه‌نویس با تجربۀ زیاد و برنامه‌نویس با تجربۀ کم این است که کسانی‌که تجربۀ زیادی دارند، در صورت مواجهه با یک خطا می‌توانند راه‌حل برطرف کردن آن را پیدا کنند. پس نگران خطا داشتن در کدهای خود نباشید و همیشه در صورتی‌ که با خطایی در کد مواجه شدید، به‌دنبال برطرف کردن آن باشید. در ادامۀ مسیر با روش‌های مختلفی آشنا می‌شویم که می‌توانند این خطاها را کاهش دهند و یا برطرف کنند.

این خطاها چند نوع هستند:

خطای دستوری

بعضی از این خطاها خطای نحوی/ دستوری (Syntax Error) هستند، به این معنی که کدی که نوشته‌ایم از نظر دستوری ایراد دارد.

قطعه کد زیر را در نظر بگیرید که شامل چندین خطا است. خطاهای موجود در این قطعه کد به صورت کامنت نوشته شده‎اند:

double PlayerHealth = 12.5;

//  کلمه کلیدی را نمی توانیم به عنوان نام متغیر استفاده کنیم
int for = 2; 

//در انتهای عبارت از   ;  استفاده نکرده ایم
Console.WriteLine("Without Semicolon") 

// کلمه کلیدی  if اشتباه نوشته شده است
iff(PlayerHealth > 0) 
{
    Console.WriteLine("Plyer is Alive");
}
else
{
    Console.WriteLine("Game Over!");
}

قطعه کد بالا اجرا نمی‌شود. در این حالت کامپایلر پیغام می‌دهد و متوجه خطا می‌شویم و به‌راحتی می‌توانیم آن را برطرف کنیم که یکی از مزایای کامپایلر C# است که معمولاً با پیغام مناسب خطا را نشان می‌دهد. برای مثال، وقتی ; را در انتهای دستورها قرار نمی‌دهیم، پیغام زیر نمایش داده می‌شود.

 ; expected 

یا هنگامیکه به جای if از iff استفاده می کنیم پیغام زیر نمایش داده می شود:

The name ‘iff’ does not exist in the current context

خطای منطقی

نوع دیگری از این خطاها به خطای منطقی (Logical Error) معروف هستند. وقتی قطعه کدی که نوشته‌ایم از نظر دستوری درست است، اما نتیجۀ درستی را به ما نشان نمی‌دهد. به‌ بیان دیگر، برنامه به‌درستی اجرا می‌شود، اما عملکرد درستی ندارد. کامپایلر متوجه این نوع خطا نمی‌شود و پیدا کردن این نوع خطا هم کمی سخت است. البته با ابزارهایی که محیط برنامه‌نویسی در اختیار ما قرار می دهد، کشف، بررسی، و رفع این نوع خطا‌ها هم ساده‌تر شده است. با محیط برنامه‌نویسی اصلی زبان C# در ادامه بیشتر آشنا می‌شویم.

برای مثال، در قطعه کد زیر در صورتی‌ که مقدار جان بازیکن بیشتر از صفر باشد، بازی تمام می‌شود و در صورتی‌ که کمتر از صفر باشد بازیکن زنده در نظر گرفته می‌شود:

double playerHealth = 12.5;

if(playerHealth > 0)
{
    Console.WriteLine("Game Over!");
}
else
{
    Console.WriteLine("Player is Alive");
}

که منطقی نیست و باید برعکس باشد، مثل کد زیر:

double playerHealth = 12.5;

if(playerHealth > 0)
{
    Console.WriteLine("Player is Alive");
}
else
{
    Console.WriteLine("Game Over!");
}

خطای زمان اجرا

درنهایت یک نوع خطا هم با عنوان خطای زمان اجرا (RunTime Error) وجود دارد که اتفاقات غیرمنتظره‌ای هستند که حین اجرای برنامه رخ می‌دهند. معمولاً در شرایطی به وجود می‌آیند که برنامه‌نویس آن‌ها را پیش‌بینی نکرده است. همان‌‌طور که قبلاً گفتیم، اگر در زمان کامپایل خطایی وجود داشته باشد، کامپایلر پیغام می‌دهد و جلوی کامپایل شدن برنامه را می‌گیرد، اما اگر خطایی داشته باشیم که در زمان کامپایل نتوان آن را ارزیابی کرد و به ارزیابی در مرحلۀ اجرا نیاز داشته باشد، باعث این نوع خطا می‌شود. مثلاً هنگامی که از آرایه استفاده می‌کنیم، کد زیر خطا می‌دهد:

int[] times = { 154, 161, 183, 183, 191, 169, 176, 191, 183, 183, 169, 169 };

// این آرایه 12 عضو دارد  
// و می توانیم فقط عضوهایی با ایندکس از 0 تا 11 را بخوانیم
// و چون ایندکس  100نداریم پس برنامه خطا می دهد 
Console.WriteLine(times[100]);

باگ و دیباگ

به خطاهایی که در برنامه به وجود می‌آید خطا/ باگ (Bug) می‌گوییم و فرایند بررسی و رفع این خطا‌ها اشکال‌زدایی/ دیباگ (Debug) نام دارند.

برای کمتر شدن باگ برنامه‌ها راه‌حل‌هایی وجود دارد، یکی از آن‌ها اعمال کردن پیشنهادها و اصولی است که در کادرهایی به شکل زیر در کتاب آمده است:

 

یکی دیگر از این راه‌حل‌ها کمک گرفتن از کامپایلر است. به این معنی که بعضی کلمات کلیدی وجود دارند که وقتی از آن‌ها استفاده می‌کنیم، در صورت رفتار ناخواسته از سمت برنامه‌نویس، کامپایلر پیغام می‌دهد و جلوی بروز اشتباه را می‌گیرد. با این موارد در ادامه بیشتر آشنا می‌شویم.

تمرین زیاد، تجربه‌های متنوع، مرور کد‌های نوشته‌شده به‌دست برنامه‌نویسان باتجربه‌تر، و یادگیری اصول مربوط به کد‌نویسی تمیز از مواردی هستند که باعث می‌شوند باگ‌های کمتری در کد داشته باشیم. 

  1. قطعه کد زیر خطا دارد، آن را برطرف کنید.

    double playerHealth = 12.5;
    if(PlayerHealth > 0)
     Console.WriteLine("Plyer is Alive");
    }
    else
    Console.WriteLine("Game Over!");
    }

  2. قطعه کد زیر خطا دارد، آن را برطرف کنید.

    int[] monthCode = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    for(int i = 1; i <= monthCode.Length; i = i + 1)
    {
     Console.WriteLine("Current MonthCode is " + monthCode[i]);
    }