رشته‌ها در #C

داده‌ها درهم تنیده می‌شوند

قبل از این‌که شروع به بحث در مورد رشته‌ها در دات‌نت بکنیم، بگذارید قدری در مورد انواع داده در # C بحث کنیم.
کد خبر: ۴۱۹۶۸۶

در کل #C شما با دو نوع داده روبه‌رو هستید: یکی Value Type یکی هم Reference Type. در شماره‌های پیشین بیشتر در مورد این نوع داده‌ها صحبت کرده‌ایم و در حال حاضر فقط تفاوت آنها را بررسی می‌کنیم. نوع اول یک نوع بر حسب مقدار است و زمانی که به یک تابع فرستاده می‌شود اگر درون تابع تغییری روی آن صورت بگیرد درون خود تابع اعتبار دارد و زمانی که از تابع خارج شویم مقدار متغیر فرستاده شده به تابع بدون تغییر می‌ماند (دقیقا مانند متغیرهای معمولی در C و ++C)، اما Reference Type چطور؟ همان طور که از نام آنها بر می‌آید از نوع ارجاع هستند یعنی وقتی به یک تابع فرستاده شوند هر تغییری در آنها بیرون از تابع نیز اعمال می‌شود، بگذارید مطلبی را که گفته شد از دیدگاه زبان C بررسی کنیم.

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

در دات‌نت کلاس‌ها یک نوع داده ارجاعی هستند یعنی Reference Type و Structure یک نوع داده مقداری یعنی Value Type. String در #C یک کلاس هست پس از نوع Reference Type است. حال مثال زیر را اجرا کنید:

static void Main(string[] args){

int x = 20;

double y = 30;

string name = “Jamejam”;

Test(x, y, name);

Console.WriteLine(x.ToString());

Console.WriteLine(y.ToString());

Console.WriteLine(name);}

public static void Test(int x,double y,string name){

x = 10;

y = 20;

name = “Click!”;}

خروجی که مشاهده می‌کنید به صورت زیر است

20

30

Jamejam

اما چه اتفاقی افتاده؟ چرا متغیر name مقدار اولیه خود را دارد؟ در صورتی که مقدار آن در تابع برابر Click! قرار داده شده است.

ما انتظار داریم که چون string یک کلاس است، پس وقتی به تابع Test داده می‌شود، مقدار آن تغییر کند. اما چرا تغییر نکرد؟

بله این غیر عادی است؛ اما بر می‌گردیم به تعریف کلاس string، کلاس string یک کلاس Immutable است.

کلاس Immutable به کلاسی اطلاق می‌شود که بعد از ساخته شدن نمی‌تواند مقدار خود را تغییر دهد. یعنی وقتی شما یک شئ از این کلاس ساختید و مقدار آن را تغییر دادید در واقع یک کپی جدید از آن شئ تحویل می‌گیرید نه همان شئ تغییر داده شده را. در مثال بالا وقتی شما به متغیر name مقداری را می‌دهید، این مقدار تغییر نمی‌کند، بلکه یک شئ جدید تحویل می‌دهد که در همان Scope اعتبار دارد. پس توجه داشته باشید وقتی از string استفاده می‌کنید، انتظار تغییر آن را نداشته باشید و برای این‌که تغییرات را مشاهده کنید، از کلمات کلیدی ref و out (در شماره‌های پیشین توضیح داده شده است) استفاده کنید.

اما کلاس string یک مشکل دیگر نیز دارد. به کد زیر دقت کنید.

string name = “Jamejam”;

name += “Click!”;

Console.WriteLine(name);

همه چیز درست است. اما طبق گفته‌های بالا مقدار متغیر name سه رشته را دارد، یکی Jamejam و دیگری Jamejam Click، چون هر بار که تغییر می‌کند یک شئ جدید تحویل می‌دهد؛ پس متغیر name می‌ماند و یک name دیگر تحویل می‌دهد. پس شما 2 رشته دارید و اگر به کرات از این روش استفاده کنید، شما مقدار زیادی رشته تولید شده دارید که همیشه از یکی از آنها که آخری است، استفاده می‌کنید. این موضوع در زمان‌های زیادی که برنامه شما کار می‌کند ممکن است مشکل ایجاد کند و برنامه با کمبود حافظه روبه‌رو شود. البته این اتفاق برای متغیر‌های رشته‌ای بزرگ می‌افتد، اما بهتر است از روش‌های بهتری استفاده کنیم تا هیچ وقت با مشکل روبه‌رو نشویم.

برنامه‌نویسان دات‌نت برای این مشکل نیز راه‌حلی دارند آن هم استفاده از کلاس StringBuilder است. این کلاس در فضای نام System.Text قرار دارد. شما توسط متد Append این کلاس می‌توانید یک رشته را به یک رشته دیگر تبدیل کنید بدون این‌که مشکلاتی که در بالا ذکر شده، رخ دهد (این‌که چگونه این کار انجام می‌شود به عهده خواننده است)، سپس با استفاده از متد ToString مقدار رشته حاصل را بازیابی کنید. به مثال زیر دقت کنید:

StringBuilder sb = new StringBuilder();

sb.Append(“Jamejam”);

sb.Append(“Click!”);

Console.WriteLine(sb.ToString());

امیربهاءالدین سبط‌الشیخ

newsQrCode
ارسال نظرات در انتظار بررسی: ۰ انتشار یافته: ۰

نیازمندی ها