Null چیست ؟تهی در برنامه نویسی به زبان ساده

  Null چیست ؟تهی در برنامه نویسی به زبان ساده
فهرست مقاله [نمایش]

    null در برنامه‌نویسی به مفهومی اشاره دارد که نشان‌دهنده نبود یک مقدار معتبر یا اشاره‌گر به هیچ چیزی است. به عبارت دیگر، null به معنای خالی بودن یا عدم مقداردهی یک متغیر است. در بسیاری از زبان‌های برنامه‌نویسی، زمانی که یک متغیر null است، یعنی آن متغیر به هیچ شیء یا مقداری اشاره نمی‌کند.

    مثلاً در زبان‌های برنامه‌نویسی مانند C# یا Java، از null برای اشاره‌گرهای خالی استفاده می‌شود:

     

    string name = null; // نام به هیچ مقداری اشاره نمی‌کند
    

    این متغیر name در حال حاضر null است، یعنی هیچ رشته‌ای به آن اختصاص داده نشده است.

    مفهوم null در برنامه‌نویسی اهمیت زیادی دارد، زیرا به توسعه‌دهندگان این امکان را می‌دهد که به سادگی وضعیت‌های خاصی مانند نبود داده را مدیریت کنند. با این حال، استفاده از null می‌تواند باعث بروز مشکلاتی نظیر خطای NullReferenceException شود، یعنی زمانی که سعی می‌کنید به متغیری که null است دسترسی پیدا کنید.

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

    در کل، null نشان‌دهنده‌ی این است که متغیر به هیچ داده‌ای اشاره نمی‌کند و به نوعی یک وضعیت خالی یا نامعتبر بودن را بیان می‌کند.

    null یک مفهوم بسیار مهم واساسی در بسیاری از زبان‌های برنامه‌نویسی است. این مفهوم در تمامی انواع کد منبع نوشته‌شده در این زبان‌ها یافت می‌شود. بنابراین، ضروری است که به طور کامل مفهوم null را درک کنیم. باید معنای آن را بدانیم، پیاده‌سازی آن را درک کنیم و یاد بگیریم چگونه null را در کد خود به کار ببریم.

    پیاده سازی null در زمان اجرا


    پیاده‌سازی null در حافظه در زمان اجرا به نوع سیستم و زبان برنامه‌نویسی بستگی دارد، اما اصول کلی مشابهی برای آن وجود دارد که در بسیاری از زبان‌ها قابل مشاهده است. در ادامه به چگونگی پیاده‌سازی null در سطح حافظه و زمان اجرا اشاره می‌کنم:

    1. اشاره‌گر به آدرس خاص (معمولاً صفر)

    در زبان‌هایی مانند C و++c، مفهوم null  به عنوان اشاره‌گری تعریف می‌شود که به آدرس حافظه‌ی صفر (0) اشاره می‌کند. این یعنی زمانی که یک اشاره‌گر null است، در حقیقت به هیچ مکانی در حافظه اشاره نمی‌کند. به عبارت دیگر، مقدار اشاره‌گر null برابر با آدرس صفر است.

     

    int *ptr = NULL;  // ptr به آدرس 0 اشاره می‌کند
    

    در پردازنده‌های مدرن، آدرس صفر معمولاً به عنوان آدرسی غیرقابل دسترس و محافظت‌شده در نظر گرفته می‌شود، بنابراین تلاش برای دسترسی به آدرس 0 منجر به بروز یک استثناء یا خطای اجرایی (مانند Segmentation Fault) خواهد شد.

    2. نماینده تهی بودن

    در زبان‌های سطح بالا مانند Java، سی شارپ ، و Python، null (یا None در Python) یک مقدار خاص است که نشان می‌دهد متغیر به هیچ شیء‌ای اشاره نمی‌کند. این مقدار در حقیقت توسط زمان اجرای (Runtime) زبان مدیریت می‌شود و یک مقدار ویژه است که با مقادیر دیگر تفاوت دارد.

    در Java و سی شارپ، زمانی که یک شیء به null اشاره می‌کند، نشان می‌دهد که هیچ فضای حافظه‌ای برای آن شیء تخصیص داده نشده است یا آدرس شیء نامعتبر است. این موضوع معمولاً به این معنی است که کامپایلر یک مقدار "تهی" به عنوان یک اشاره‌گر خالی در نظر می‌گیرد، اما مقدار آن به جای آنکه لزوماً صفر باشد، توسط VM به عنوان یک مقدار خاص مدیریت می‌شود.

    3. مدیریت حافظه و Garbage Collection

    در زبان‌های مدیریت‌شده‌ای مانند Java و سی شارپ، زمانی که یک متغیر null می‌شود و هیچ ارجاع دیگری به شیء مربوطه باقی نمی‌ماند، آن شیء به طور خودکار توسط سیستم Garbage Collector آزاد می‌شود. بنابراین null می‌تواند به کاهش استفاده از حافظه کمک کند، زیرا با آن به زبان اجرا می‌فهمانید که دیگر نیازی به استفاده از شیء مذکور نیست.

    4. ساختار داده و مقداردهی null

    در زمان اجرا، بسیاری از ماشین‌های مجازی یا محیط‌های زمان اجرا از یک مقدار ثابت برای نمایش null استفاده می‌کنند. این مقدار ثابت، معمولاً به عنوان "عدم ارجاع به حافظه" تعبیر می‌شود. مثلاً در ماشین مجازی Java (JVM)، null به عنوان مقداری خاص تعریف شده که توسط زمان اجرای JVM قابل تشخیص است و وقتی سعی می‌شود به یک شیء null دسترسی پیدا شود، باعث بروز خطای NullPointerException می‌شود.

    5. تفاوت‌های معماری و مدیریت سیستم‌عامل

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

    مثال‌هایی از زبان‌های مختلف

    • C++/C: در این زبان‌ها، NULL به سادگی به مقدار 0 اشاره می‌کند. یعنی اشاره‌گر null به آدرس حافظه‌ی 0 اشاره دارد که معمولاً دسترسی به آن غیرمجاز است.
    • سی شارپ و جاوا : در این زبان‌ها، null به معنای عدم ارجاع به هر شیء است و زمانی که برنامه سعی در دسترسی به شیء‌ای با مقدار null داشته باشد، استثناء ایجاد می‌شود.

     

    بان‌های برنامه‌نویسی مختلف از جمله C#، کلمه کلیدی null نشان‌دهنده‌ی این است که یک متغیر به هیچ مقدار یا به هیچ آبجکتی اشاره نمی‌کند. این حالت معمولاً برای مقادیر مرجع (reference types) استفاده می‌شود تا مشخص شود که متغیر به هیچ شیء خاصی اشاره ندارد. به بیان ساده‌تر، null به معنی نبودن هیچ مقداری است.

    عملکرد null در زبان#C به طور خلاصه:

    مقدار پیش‌فرض: مقدار پیش‌فرض برای انواع مرجع در C#، null است. این بدان معناست که اگر شما یک متغیر مرجع را بدون مقدار اولیه تعریف کنید، مقدار آن null خواهد بود.

    string text; // مقدار اولیه این متغیر null است
    

    اشاره به نبود شیء: null نشان می‌دهد که متغیر به هیچ شیئی در حافظه اشاره نمی‌کند. مثلاً اگر شما یک آبجکت Person ایجاد کنید و مقدار آن را null قرار دهید، این بدان معناست که هیچ شیء Person در حافظه به این متغیر اختصاص داده نشده است.

    Person person = null; // متغیر person به هیچ شیئی اشاره نمی‌کند
    

    بررسی null: برای جلوگیری از بروز خطاهای NullReferenceException، معمولاً باید قبل از دسترسی به اعضای یک شیء بررسی کنید که آیا آن شیء null است یا خیر.

    if (person != null)
    {
        Console.WriteLine(person.Name);
    }
    

    عملگر ?? (Null Coalescing Operator): از این عملگر می‌توانید برای اختصاص مقدار پیش‌فرض به متغیرهای null استفاده کنید.

    string name = person?.Name ?? "نام مشخص نیست";
    

    در این مثال، اگر person یا person.Name مقدار null داشته باشند، رشته "نام مشخص نیست" به name اختصاص داده می‌شود.

    عملگر ?. (Null Conditional Operator): این عملگر برای جلوگیری از خطای NullReferenceException هنگام دسترسی به اعضای یک شیء که ممکن است null باشد، استفاده می‌شود.

    Console.WriteLine(person?.Name);
    

    اگر person مقدار null داشته باشد، نتیجه این دستور نیز null خواهد بود و به جای وقوع خطا، هیچ خروجی چاپ نمی‌شود.

    نمونه خطای معمول با null

    در صورتی که سعی کنید به عضوی از یک شیء که مقدار null دارد دسترسی پیدا کنید، خطای NullReferenceException رخ می‌دهد. مثلاً:

     

    Person person = null;
    Console.WriteLine(person.Name); // این خطا می‌دهد زیرا person برابر null است.
    

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

    مواقعی که نباید از null استفاده کرد:

     

    طراحی API و واسط‌های عمومی:

    • زمانی که یک API عمومی یا واسطی را برای استفاده دیگران طراحی می‌کنید، بازگرداندن null می‌تواند کاربر را با خطای NullReferenceException مواجه کند. به جای آن می‌توانید از الگوهای طراحی دیگر مانند Optional (در زبان‌های Java) یا استفاده از کلاس‌های خاصی مانند Maybe در سی شارپ استفاده کنید تا نشان دهید که یک مقدار ممکن است خالی باشد، اما با روشی امن و کنترل‌شده.

     

    کاهش قابلیت اطمینان برنامه:

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

     

    برای جلوگیری از خطاهای NullReferenceException:

    • خطاهای NullReferenceException یکی از رایج‌ترین مشکلات استفاده از null هستند که می‌توانند باعث شکست برنامه شوند. برای جلوگیری از این مشکلات، بهتر است همیشه قبل از استفاده از متغیر مطمئن شوید که مقدار آن null نیست یا از عملگرهای ایمن مانند ?. (در #C) یا عملگرهای شرطی پیشرفته استفاده کنید.

     

    بجای مقادیر اختیاری یا پارامترهای پیش‌فرض:

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

     

    کلاس‌های مجموعه‌ای (Collection):

    • در کلاس‌های مجموعه‌ای مانند لیست‌ها (List)، بهتر است از افزودن null به مجموعه اجتناب کنید. وجود null در مجموعه می‌تواند باعث مشکلاتی در زمان دسترسی به عناصر و ایجاد خطاها شود.

    مواقعی که باید یا استفاده از null خطری ندارد:

     

    نشان دادن نبود شیء:

    • زمانی که واقعاً نیازی به وجود یک شیء خاص ندارید، مانند یک متغیر از نوع Person که ممکن است تعریف نشده باشد یا هنوز تخصیص داده نشده، استفاده از null مجاز است. این به شما کمک می‌کند که نشان دهید متغیر هنوز به هیچ شیء یا مقداری اشاره نمی‌کند.

     

    برای تعامل با پایگاه داده:

    • زمانی که با پایگاه داده کار می‌کنید، ممکن است بخواهید نشان دهید که یک مقدار خاص تعریف نشده یا ناشناخته است. در این مواقع استفاده از null به طور مستقیم در پرس‌وجوها (SQL) یا در کد برنامه برای نشان دادن فیلدهای اختیاری یا مقدارهای ناموجود رایج است.

     

    زمانی که مقدار پیش‌فرض مناسب نیست:

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

     

    استفاده از null در Dictionary ها برای نشان دادن نبود کلید:

    • در زمان کار با ساختارهای داده مانند Dictionaryها، null می‌تواند نشان‌دهنده این باشد که کلیدی وجود ندارد یا مقداری برای آن کلید تعریف نشده است.

     

    در کاربردهای مشخص در #C با nullable types:

    • در زبان #C، می‌توان از نوع‌های nullable (به صورت int?، bool? و ...) برای انواع مقداری استفاده کرد تا امکان مقدار null وجود داشته باشد. این ویژگی به شما اجازه می‌دهد که از null برای نشان دادن حالتی که مقدار هنوز تعیین نشده استفاده کنید.
    int? age = null; // age می‌تواند یا عددی باشد یا null
    

    راهکارهای ایمن برای استفاده از null:

    • استفاده از عملگر ?.: در#C می‌توانید از عملگر شرطی ?. استفاده کنید تا در صورتی که یک شیء null بود، از وقوع خطا جلوگیری شود
    string name = person?.Name; // اگر person برابر null باشد، مقدار name نیز null خواهد بود.
    
    • عملگر ?? (Null Coalescing Operator): می‌توانید از این عملگر برای تخصیص مقدار پیش‌فرض در صورتی که متغیر null باشد، استفاده کنید.

     

    string name = person?.Name ?? "نام مشخص نشده";
    

      خلاصه

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

    1. اگر یک ارجاع به null اشاره کند، همیشه به این معنی است که هیچ مقداری به آن مرتبط نشده است.
    2. در بیشتر موارد، null معنای خاص‌تری دارد که به زمینه وابسته است.
    3. اگر نیاز داریم بدانیم چرا هیچ مقداری به یک ارجاع مرتبط نیست، باید داده‌های اضافی برای تمایز بین حالات مختلف فراهم کنیم.
    4. null تنها زمانی باید مجاز باشد که منطقی باشد که یک ارجاع شیء "هیچ مقداری به آن مرتبط نشده باشد".
    5. از null برای نشان دادن شرایط خطا استفاده نکنید.
    6. مفهوم null فقط برای انواع مرجع وجود دارد و برای انواع مقداری وجود ندارد.
    7. در برخی از زبان‌ها، null مقدار پیش‌فرض برای انواع مرجع است.
    8. عملیات‌های مربوط به null بسیار سریع و کم‌هزینه هستند.
    9. تا حد امکان از زبانی استفاده کنید که ایمنی null را در زمان کامپایل پشتیبانی می‌کند.

     

    اطلاعات نویسنده
    • نویسنده: روشن احمدی

    ارسال دیدگاه

    برای افزودن دیدگاه خود، نیاز است ابتدا وارد حساب کاربری‌تان شوید


    دیدگاه کاربران