سه شنبه ۲۷ شهريور ۱۴۰۳
Tut24 آموزش برنامه نویسی و مجله تخصصی فناوری ورود/عضویت

آموزش سی شارپ - کدهای ناامن

C# اجازه می‌دهد که در یک تابع یا بلوک کد از متغیرهای اشاره‌گر استفاده کنید وقتی که با استفاده از کلیدواژه unsafe مشخص شده باشد. کد ناامن یا کد بدون نظارت، بلوکی از کد است که از یک متغیر اشاره‌گر استفاده می‌کند.

اشاره‌گر یک متغیر است که مقدار آن آدرس یک متغیر دیگر است، به عبارت دیگر، آدرس مستقیم مکانی در حافظه است. مشابه هر متغیر یا ثابت، باید قبل از استفاده از یک اشاره‌گر، آن را اعلام کنید تا بتوانید آدرس یک متغیر را در آن ذخیره کنید.

شکل کلی تعریف یک اشاره‌گر به شکل زیر است −

type *var-name;

در زیر اعلان های اشاره گر معتبر وجود دارد -

int    *ip;    /* pointer to an integer */
double *dp;    /* pointer to a double */
float  *fp;    /* pointer to a float */
char   *ch     /* pointer to a character */

مثال زیر استفاده از اشاره گرها در سی شارپ را با استفاده از اصلاح کننده ناامن - نشان می دهد

using System;

namespace UnsafeCodeApplication {
   class Program {
      static unsafe void Main(string[] args) {
         int var = 20;
         int* p = &var;
         
         Console.WriteLine("Data is: {0} ",  var);
         Console.WriteLine("Address is: {0}",  (int)p);
         Console.ReadKey();
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا شد، نتیجه زیر را ایجاد می کند -

Data is: 20
Address is: 99215364

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

بازیابی مقدار داده با استفاده از اشاره‌گر

شما می‌توانید با استفاده از متد ToString()، داده‌ای که در محل مشخص شده توسط متغیر اشاره‌گر ذخیره شده است، بازیابی کنید. مثال زیر این را نشان می‌دهد −

using System;

namespace UnsafeCodeApplication {
   class Program {
      public static void Main() {
         unsafe {
            int var = 20;
            int* p = &var;
            
            Console.WriteLine("Data is: {0} " , var);
            Console.WriteLine("Data is: {0} " , p->ToString());
            Console.WriteLine("Address is: {0} " , (int)p);
         }
         Console.ReadKey();
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا شد، نتیجه زیر را ایجاد می کند -

Data is: 20
Data is: 20
Address is: 77128984

گذاشتن اشاره‌گرها به عنوان پارامترها در متدها

شما می‌توانید یک متغیر اشاره‌گر را به عنوان پارامتری به یک متد گذاشته شود. مثال زیر این را نشان می‌دهد −

using System;

namespace UnsafeCodeApplication {
   class TestPointer {
      public unsafe void swap(int* p, int *q) {
         int temp = *p;
         *p = *q;
         *q = temp;
      }
      public unsafe static void Main() {
         TestPointer p = new TestPointer();
         int var1 = 10;
         int var2 = 20;
         int* x = &var1;
         int* y = &var2;
         
         Console.WriteLine("Before Swap: var1:{0}, var2: {1}", var1, var2);
         p.swap(x, y);

         Console.WriteLine("After Swap: var1:{0}, var2: {1}", var1, var2);
         Console.ReadKey();
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا می شود، نتیجه زیر را ایجاد می کند -

Before Swap: var1: 10, var2: 20
After Swap: var1: 20, var2: 10

دسترسی به عناصر آرایه با استفاده از اشاره‌گر

در C#، نام یک آرایه و یک اشاره‌گر به یک نوع داده همانند داده‌های آرایه، نوع متغیری یکسان نیستند. به عنوان مثال، int *p و int[] p، نوع یکسانی ندارند. می‌توانید متغیر اشاره‌گر p را افزایش دهید زیرا در حافظه ثابت نیست، اما آدرس یک آرایه در حافظه ثابت است و نمی‌توانید آن را افزایش دهید.

بنابراین، اگر نیاز دارید با استفاده از یک متغیر اشاره‌گر به داده‌های یک آرایه دسترسی پیدا کنید، همانند روش سنتی در C یا C++ ، باید اشاره‌گر را با استفاده از کلمه کلیدی fixed ثابت کنید.

مثال زیر این را نشان می‌دهد −

using System;

namespace UnsafeCodeApplication {
   class TestPointer {
      public unsafe static void Main() {
         int[]  list = {10, 100, 200};
         fixed(int *ptr = list)
         
         /* let us have array address in pointer */
         for ( int i = 0; i < 3; i++) {
            Console.WriteLine("Address of list[{0}]={1}",i,(int)(ptr + i));
            Console.WriteLine("Value of list[{0}]={1}", i, *(ptr + i));
         }
         
         Console.ReadKey();
      }
   }
}

هنگامی که کد بالا کامپایل و اجرا شد، نتیجه زیر را ایجاد می کند -

Address of list[0] = 31627168
Value of list[0] = 10
Address of list[1] = 31627172
Value of list[1] = 100
Address of list[2] = 31627176
Value of list[2] = 200

کامپایل کد ناامن

برای کامپایل کد ناامن، باید سوئیچ خط فرمان /unsafe را با کامپایلر خط فرمان مشخص کنید.

به عنوان مثال، برای کامپایل برنامه‌ای به نام prog1.cs که شامل کد ناامن است، از خط فرمان، دستور زیر را وارد کنید −

csc /unsafe prog1.cs

اگر از محیط توسعه Visual Studio استفاده می‌کنید، باید استفاده از کد ناامن را در تنظیمات پروژه فعال کنید.

برای انجام این کار −

  • با دو بار کلیک روی گره‌ی ویژگی‌ها در Explorer راه‌حل، تنظیمات پروژه را باز کنید.

  • روی برگه‌ی build کلیک کنید.

  • گزینه "اجازه استفاده از کد ناامن" را انتخاب کنید.