PDA

نسخه کامل مشاهده نسخه کامل : سوال در رابطه با توابع



SH@HIN
25-12-2012, 12:39
سلام دوستان
من چند وقته که دارم زبان c++ میخونم ، الان رسیدم به مبحث ارسال به توابع از طریق اشاره گر و مراجع
تو بعضی از مثال ها وقتی که یه تابعی تعریف کرده قبل از اسم تابع علامت * قرارداده( ارسال با آدرس) و یا علامت & ( ارسال با مرجع)

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

یا


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

میخواستم بدونم این * یا & قبل از اسم تابع برای چی هست؟!!
ممنون

god of war 2
29-12-2012, 10:58
سلام.
کاراکتر * نمایانگر اشارگر ها هست و کاراکتر & نمایانگر ارجاع ها و وقتی در قسمت خروجی یک تابع می آیند یعنی خروجی این تابع یک اشارگر یا یک ارجاع میباشد.
یک مطلبی رو هم الان به ذهنم رسید میگم شاید مفید باشه!
در ظاهر این دو کاراکتر یک عمل رو انجام میدهند و اون عمل همونطور که میدونید انتقال آدرس یک شی میباشد. اما این دو تفاوت های زیاد و کارایی های متفاوتی دارند!
این دو کاراکتر از هر لحاظ قابل مقایسه با یکدیگر هستند برای مثال چند نمونه از تفاوت های این دو:

1- اشارگر ها قابلیت اختصاص پیاپی دارند اما ارجاع ها چنین قابلیتی ندارند و باید توسط مقدار دهی اولیه مقدار دهی شوند:
اشارگرها:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
ارجاع ها:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

2- شما میتوانید یک سطح تودر تو از اشارگر ها ایجاد کنید اما ارجاع ها چنین قابلیتی ندارند:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

3- یک اشارگر در اصل یک متغییر میباشد (به اندازه 4 بایت در سیستم های 32 بیتی) که مقدار آن آدرس شیئی هست که به آن اشاره میکند اما ارجاع ها با توجه به پیاده سازی ایی که دارند دقیقا برابر هستند با آدرس شی و حتی در برخی از کامپایلر ها کارکتر & یک عملگر زمان کامپایل میباشد یعنی در زمان کامپایل مقدار آن محاسبه شده و جایگزین میشود.

4- اشارگر ها میتوانند شامل مقدار 0 یا null باشند اما تخصیص مقدار 0 یا null به یک ارجا در حالت عادی امکان ندارد:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
یک نکته امنیتی در این مثال وجود دارد. وقتی که ورودی/خروجی یک تابع اشارگر باشد درصد بروز خطا در هنگام استفاده از اون تابع بسیار زیاد میباشد. سعی کنید در حد ممکن از ارجاع ها بجای اشارگر ها در بخش ورودی/خروجی تابع ها استفاده کنید.
دلیل: فرض کنید شما از تابعی در برنامه خود استفاده کرده اید که خروجی آن یک اشارگر میباشد. شما بدون هیچ گونه بررسی مستقیما از خروجی این تابع استفاده میکنید و همانطور که در مثال قبل گفتم امکان وجود مقدار 0 یا null در اشارگر ها وجود دارد. با این حساب اگر به هر دلیلی آن تابع مقدار null برگرداند و شما قصد استفاده از مقدار null به عنوان یک شی را داشته باشید , برنامه سریعا کرش شده و بسته میشود. اما در ارجاع ها امنیت بیشتری وجود دارد و میشه گفت تضمینی هست برای اینکه یک ارجاع همواره به یک شی نسبت داده شده است و در حالت معمول هیچوقت یک ارجاع مقدار null ندارد.


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

SH@HIN
04-01-2013, 16:14
دوست عزیز ممکنه که تفاوت این دو رو هم بگید؟

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

منظورم اینه که اگر علامت & یا * قبل از اسم تابع قرار بگیره یا قبل از عبارت مقابل return تفاوتی میکنه؟!

god of war 2
04-01-2013, 21:58
منظورم اینه که اگر علامت & یا * قبل از اسم تابع قرار بگیره یا قبل از عبارت مقابل return تفاوتی میکنه؟!
من منظور شمارو فهمیدم اما مثالهایی که زده اید چندان درست نیستند حتی منظوری که شما داشتید رو هم نمیروسنند یعنی چیزی که شما فکر میکنید در مثال دوم با چیزی که نوشتید تفاوت دارد.


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

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

اما تابع دوم کاملا درست میباشد ولی منظوری که شما داشتید رو نمیرساند!
عملگر * زمانی که قبل از نام یک اشارگر بیاید به معنی دسترسی به شیئی میباشد که اشارگر به آن اشاره میکند.
پس با این حساب مقدار برگشتی به شکل زیر:

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

و تابعی که در مثال دوم مد نظر شما بوده به شکل زیر میباشد:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
که این تابع هم دقیقا مانند مثال اول کامپایل نمیشود و در حین کامپایل به همان دلیلی که گفتم (عدم همخوانی با اعلان) با خطا مواجه میشوید.

SH@HIN
04-01-2013, 22:11
واقعا ممنون از توضیحاتتون دوست عزیز،:n12:
این مبحث اشاره گر و مراجع ریزه کاری زیاد داره،بعضی مواقع آدم سردرگم میشه!!
:n11: