اخطار‌های زیر رخ داد:
Warning [2] Cannot modify header information - headers already sent by (output started at /home/delta/public_html/forum/inc/languages/persian/fitonpage.lang.php:1) - Line: 1689 - File: inc/functions.php PHP 5.2.17 (Linux)
File Line Function
[PHP]   errorHandler->error
/inc/functions.php 1689 header
/inc/functions.php 1757 my_setcookie
/inc/functions_indicators.php 42 my_set_array_cookie
/showthread.php 589 mark_thread_read
Warning [2] Cannot modify header information - headers already sent by (output started at /home/delta/public_html/forum/inc/languages/persian/fitonpage.lang.php:1) - Line: 1689 - File: inc/functions.php PHP 5.2.17 (Linux)
File Line Function
[PHP]   errorHandler->error
/inc/functions.php 1689 header
/inc/functions.php 1757 my_setcookie
/inc/functions_indicators.php 217 my_set_array_cookie
/inc/functions_indicators.php 48 mark_forum_read
/showthread.php 589 mark_thread_read





آخرین اخبار: --- *** همیاران دلتا *** --- عناوین کاربری --- طرح رای گیری تایید و تمدید عنوان های آزمایشی دلتا --- تغییرات نام های کاربری در دلتا --- اتفاقات و فعالیت های اخیر و امکانات جدید ---

ارسال پاسخ 
آموزش اشاره گرها و ارجاعها در ++ C
نویسنده پیام
SAEED

هوبخت
*****
مدیر کل سایت

ارسال‌ها: 5,711
تاریخ عضویت: ۱۳۸۸ بهم
اعتبار: 146
نشان سوم مسابقه هانشان تشکر
نشان سوم مسابقه هانشان تشکر
سپاس ها 19033
سپاس شده 15286 بار در 5401 ارسال
ارسال: #1
New2 آموزش اشاره گرها و ارجاعها در ++ C
0
0
اشاره گر چیست؟
اشاره گرها از مهمترین قابلیتهای ++C هستند.
اشاره گر که معادل فارسی لغت pointer(پوینتر)است همان طور که از نامش پیداست قرار است که اشاره کند!
به کجا؟ به یک آدرس حافظه.کدام حافظه؟ حافظه ی RAM

اشاره گر به چه درد می خورد؟
متغیرها چیزی نیستند جز خانه هایی از حافظه. RAM مثلا وقتی یک متغیر از نوع عدد صحیح یا int تعریف می کنیم، در زمان اجرای برنامه بخشی از حافظه ی RAM که متعلق به برنامه ی دیگر و متغیر دیگری نیست (آزاد است) به این عدد تخصیص می یابد. در این حالت که متغیر ما int است، 4 بایت از حافظه به این متغیر تخصیص داده می شود (چرا؟)
هر خانه ی حافظه، آدرس منحصر به فردی دارد که در سیستم های 32 بیتی یک مقدار 32بیتی یا 4بایتی مثل 0x003245100 است(در مبنای هگز هر دو رقم بیانگر یک بایت است). در سیستمهای 64 بیتی آدرسها 64 بیتی اند یعنی چیزی شبیه به 0x0000000003245100. خوب حالا اشاره گر، چیزی! است که می تواند آدرس یک متغیر از هر نوعی را در خود نگه دارد.

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

علامتهای & و * :
علامت & : این علامت آدرس یک متغیر در حافظه RAM را بر می گرداند که همواره یک عدد شانزده دهیست.
int main()
{
int n=12;
cout<<&n<<endl;
{

علامت* :این علامت بر ضد علامت & عمل می کند یعنی اگر آدرس حافظه را به ان بدهیم خود مقدار موجود در ان نقطه از حافظه را بر می گرداند.

int main()
{
int n=12;
cout<<*&n<<endl;
}


ارجاع و آدرس متغیر:

ارجاع :ارجاع در واقع یک نام مستعار برای یک متغیر است و خود یک متغیر جداگانه نیست به عبارت دیگر با تغییر متغیر اصلی ارجاع نیز تغییر می کند و همچنین با تغییر ارجاع متغیر اصلی هم تغییر می کند.
برای تعریف ارجاع بصورت زیر عمل می کنیم :
int n=44;
int &pn=n;

که در ان pn یک ارجاع است
تذکر مهم:علامت & که برای نشان دادن آدرس متغیر استفاده می شود با علامت & که در تعریف متغیراز نوع ارجاع استفاده می شود هیچ رابطه ای ندارد.

ذخیره آدرس متغیر:
بعضی مواقع لازم می شود که آدرس متغیر را در جایی ذخیره کنیم ولی آدرس متغیر یک عدد معمولی نیست و بصورت اعداد شانزده دهی نوشته می شود برای تعریف این نوع متغیر که آدرس را در خود نگه دارد بصورت زیر عمل می کنیم
int n=44;
int *pn=&n;

تذکر مهم: علامت * که برای نشان دادن محتویات آدرسهاو همچنین قرار دادن مقدار در ان آدرسها (بعدا توضیح داده می شود) استفاده می شود با علامت * که در تعریف بالا استفاده شد هیچ رابطه ای ندارد.

اشاره به اشارگر دیگر:
برای اشاره از یک اشاره گر به اشاره گر دیگر در هر مرحله یک * اضافه می کنیم مثلا اگر داشته باشیم :
int n=44;
int* pn=&n;

انگاه برای اشاره به pn& یک * زیاد می کنیم مثلا:

int **ppn=&pn;

یعنی نمی توانیم بنویسیم :

int *ppn=&pn;


بازگشت از نوع ارجاع:

برای فهمیدن این موضوع ابتدا باید در مورد راست مقدارها و چپ مقدارها کمی توضیح بدم

n=5;

در این کد مقدار 5 به n تخصیص داده شده پس با این حساب n می شود چپ مقدار و 5 می شود راست مقدار کلا به هر چیزی که بتواند در طرف چپ معادله قرار بگیرد و مقدارش قابل تغییر باشد را چپ مقدار نامیده و بعقیه را راست مقدار می نامیم مثلا ما نمی توانیم بنویسیم 5=n چون مقدار پنج قابل تغییر نیست و راست مقدار است.
تذکر:متغیرها و بطور کلی اشیاء چپ مقدار هستند و و لیترالها مثل (”abc”, 15) ثابتها و ارایه ها راست مقدارند البته به ارایه ها و ثابتها چپ مقدارهای تغییرناپذیر نیز گفته می شود.
حالا میرسیم به اصل مطلب یعنی اینکه ایا توابع چپ مقدار هستند یا راست مقدار به عبارت ساده تر ایا می شود مقدار برگشتی از یک تابع را به یک عدد تخصیص داد مثل max(m,n) = 50 ؟
در واقع توابع معمولی راست مقدارند ولی اگر ما یک علامت ارجاع یعنی & به اول تابع بصورت زیر اضافه کنیم این تابع چپ مقدار خواهد شد!

int& max(int& m,int& n)

مثال زیر موضوع را روشن می کند:
#include<iostream>
int& max(int& m,int& n)
{
if(m>n)
{
cout<<"max=m \n";
return m;
}
else
{
cout<<"max=n \n";
return n;
}
}
int main()
{
int m=6,n=4;
max(m,n)=3;
max (m,n);
return 0;
}


خروجی برنامه بالا بصورت زیر است:
max=m
max=n

در برنامه بالا ابتدا در تابع max دو مقدار m,n با هم مقایسه می شوند و چون مقدار m بزرگتر از n است عبارت max=m چاپ شده و سپس مقدار m برگردانده می شود در کد اصلی برنامه تابع max که از نوع ارجاع است برابر عبارت 3 قرار می گیرد پس m که اکنون مقدار برگشتی تابع است برابر 3 شده و دوباره تابع max فراخوانده می شود اما اینبار m به 3 تغییر کرده است و در نتیجه عبارت دوم چاپ می شود.
تذکر:توجه داشته باشید که m,n نیز بصورت ارجاع تعریف شده اند زیرا متغیرهای محلی تابع با نابود شدن تابع نابود می شوند و ممکن است برنامه دچار مشکل شود(که 100% این اتفاق خواهد افتاد) به همین دلیل m,n بصورت ارجاع تعریف شده اند به عبارت ساده تر چون وقتی ما متغیری را بصورت ارجاع به تابعی می فرستیم در واقع متغیر جدیدی تولید نشده و تنها ارجاعیست به متغیر برنامه اصلی پس با از بین رفتن تابع متغیر اصلی که درون کد اصلی برنامه است باقی مانده و برنامه دچار مشکل نمی شود .

من برای متنفر بودن از کسانی که از من متنفرند وقتی ندارم؛

زیرا درگیر دوست داشتن کسانی هستم که مرا دوست دارند ...4lqqtqv

[تصویر:  dust.gif]
۹-۴-۱۳۸۹ ۰۵:۴۲ عصر
یافتن تمامی ارسال‌های این کاربر نقل قول این ارسال در یک پاسخ
 سپاس شده توسط S.MoOoEiN.H ، ghasedak
SAEED

هوبخت
*****
مدیر کل سایت

ارسال‌ها: 5,711
تاریخ عضویت: ۱۳۸۸ بهم
اعتبار: 146
نشان سوم مسابقه هانشان تشکر
نشان سوم مسابقه هانشان تشکر
سپاس ها 19033
سپاس شده 15286 بار در 5401 ارسال
ارسال: #2
RE: آموزش اشاره گرها و ارجاعها در ++ C
0
0
قرار دادن مقدارهای واقعی (و نه آدرس) در اشاره گرها:

ما می توانیم به دو صورت یک متغیر را مقدار دهی کنیم بصورت عادی مثل X=5 و با استفاده از اشاره گرها.
برای دادن یک مقدار و( نه یک آدرس) به اشاره گر باید بصورت زیر عمل کنیم در نظر داشته باشید که این مقدار در آدرسی که قبلا در اشاره گر ذخیره شده بود قرار می گیرد.
int n=44;
int *pn;
pn=&n;
*pn=50
یا
int n=44;
int *pn=&n
*pn=50;
پس در مثال بالا در آخر برنامه مقدار n از 44 به 50 تغییر می کند.

ممکن است کمی جا خورده باشد که چگونه در خط دوم *pn یک آدرس را پذیرفته و در خط سوم *pn یک عدد را این مسئله بر می گردد به نکته ای که قبلا هم اشاره کردم یعنی علامت * در هنگام تعریف یک اشاره گر با علامت * که در خط سوم نوشته شد فرق دارد علامت * در خط دوم یک متغیر ایجاد میکند که فقط آدرس می پذیرد اما علامت * در خط سوم یک اشاره گر به یک آدرس است که مقدار می پذیرد .

مثال زیر را در کامپیوتر خود اجرا کنید و نتیجه را ببینید :
#include <iostream>
int main ()
{
int n=44;
int* pn=&n;
cout<<"pn="<<pn<<endl;
cout<<"*pn="<<*pn<<endl;
return 0;
}

ما هرگز نمی توانیم اشاره گری را که آدرسی در ان ذخیر نشده است را مقدار دهی کنیم پس کد زیر اشتباه است.
int *pn;
*pn=50;
نکته:به اشاره گری که هیچ آدرسی در ان ذخیره نشده (مثل اشاره گر بالا) اشاره گر سرگردان می گویند.

عملگر new :
برای مقدار دهی اشاره گرهای سرگردان از عملگر new استفاده می کنیم .
به این صورت که این عملگر یک مقدار فضا برای اشاره گر در حافظه ایجاد می نماید که می توانید مقدار مورد نظر(و نه آدرس) را در ان ذخیره کنید.
int* p;
p=new int;
*p=2;
و همچنین می توان سه خط فوق را با هم ترکیب کرد:

int* p=new int(2);

توجه:حتما متوجه شدید که اگه بخواهیم p را بدون علامت * چاپ کنیم آدرس حافظه ای که new ایجاد کرده را چاپ می کند.

عمل گر delete :
کار این عملگر آزاد کردن حافظه ایست که با استفاده از new درست شده است و بصورت زیر عمل می کند
int* p;
p=new int;
*p=2;
delete p;

کاربرد عملگرهای new و delete
یکی از مهم ترین دلایلی که شما باید این کار را انجام بدهید این است که می توان متغییرها را در زمان اجرای برنامه و نه هنگام کامپایل ان تولید نمود این کار انعطاف پذیری زیادی به شما می دهد. با این دو عملگر حتی می توان پا رو فراتر گذاشت بعنی بعد از اینکه کار با متغیر تمام شد می توانیم با عملگر delete حافظه را ازاد کنیم و ان مقدار فضا رو برای کارهای دیگر بکار ببریم.

من برای متنفر بودن از کسانی که از من متنفرند وقتی ندارم؛

زیرا درگیر دوست داشتن کسانی هستم که مرا دوست دارند ...4lqqtqv

[تصویر:  dust.gif]
۹-۴-۱۳۸۹ ۰۵:۴۴ عصر
یافتن تمامی ارسال‌های این کاربر نقل قول این ارسال در یک پاسخ
 سپاس شده توسط S.MoOoEiN.H ، ghasedak
ارسال پاسخ 


پرش به انجمن: