PDA

View Full Version : اجبار در قرار دادن متغیر در فراخوانی یک تابع



alireza es
شنبه 25 مرداد 1393, 23:50 عصر
با عرض سلام. یه سوال ذهنمو مشغول کرده.آیا تو C++‎‎‎ همچین امکانی هست که مثلا ما تابعی داریم با نام DoSomeThing که یه آرگومان از نوع int داره ما میخوایم که کاربر اگه بخواد تابع رو به شکل زیر فراخونی کنه با ارور مواجه بشه
DoSomeThing(5);
و باید به صورت زیر اول یه متغیر از نوع int بسازه و بعد اون متغیر رو به عنوان پارامتر به تابع بده
int i=5;
DoSomeThing(i);
ایا راهی هست؟

hosseinam1370
یک شنبه 26 مرداد 1393, 00:00 صبح
با سلام.
تو برنامه نویسی کاربری وجود نداره که ، به کسی که برنامه مینویسه میگن برنامه نویس،دیگه کاربر نیست، پس یه برنامه نویس این قواعد رو میدونه،
فک نکنم بشه این کار رو کرد، چون این قواعد یا به قوله خودمون گرامر زبان سی هست، اونم برای بازتر کردن و انعطاف پذیرتر کردن برنامه نویسی، حالا هرکی خاست ، هر طور دوست داشته باشه مینویسه ، مهم مفهومه برنامه نویسیه..

باز دوستان هستند ، این نظر من بود.


موفق باشید.

alireza es
یک شنبه 26 مرداد 1393, 00:11 صبح
با سلام.
تو برنامه نویسی کاربری وجود نداره که ، به کسی که برنامه مینویسه میگن برنامه نویس،دیگه کاربر نیست، پس یه برنامه نویس این قواعد رو میدونه،
فک نکنم بشه این کار رو کرد، چون این قواعد یا به قوله خودمون گرامر زبان سی هست، اونم برای بازتر کردن و انعطاف پذیرتر کردن برنامه نویسی، حالا هرکی خاست ، هر طور دوست داشته باشه مینویسه ، مهم مفهومه برنامه نویسیه..

باز دوستان هستند ، این نظر من بود.


موفق باشید.

الان فریم ورک ها کاربر ندارند؟و نمیشه بهشون گفت کاربر؟
من قبلا دلفی کار کردم و توش همچین امکانی بود و کافی بود تو ارگومان ها قبل از هر آرگومان کلمه Var رو اضافه میکردین تا در حین استفاده از تابع مجبور میشدین از متغیر استفاده کنین
تو کتابخانه vcl دلفی هم همچین توابعی بودند دقیق یادم نیست

حالا تو سینتکس C راهی برای این کار در نظر گرفته شد شده؟

Ananas
یک شنبه 26 مرداد 1393, 01:15 صبح
سلام.
پارامتر تابع رو باید به شکل مرجع تعریف کنید. مثال :
int MyFunction(int & i)
{
//...
};

hosseinam1370
یک شنبه 26 مرداد 1393, 07:20 صبح
الان فریم ورک ها کاربر ندارند؟و نمیشه بهشون گفت کاربر؟
من قبلا دلفی کار کردم و توش همچین امکانی بود و کافی بود تو ارگومان ها قبل از هر آرگومان کلمه Var رو اضافه میکردین تا در حین استفاده از تابع مجبور میشدین از متغیر استفاده کنین
تو کتابخانه vcl دلفی هم همچین توابعی بودند دقیق یادم نیست

حالا تو سینتکس C راهی برای این کار در نظر گرفته شد شده؟


راستش اطلاعات زیادی ندارم.دوستان برای راهنمایی هستند.

موفق باشید.

sa1378
یک شنبه 26 مرداد 1393, 07:46 صبح
دوست عزیز این دستور زبان c نیست و هر کامپایلری برا خودش یه چیزی الکی زده
الان مثلا توی Dev C++ که من کار میکنم این کد راحت اجرا میشه :

#include <iostream>
using namespace std;
void p(int a)
{
cout<<a<<endl;
}

int main()
{

p(1);
return 0;
}

omid_kma
یک شنبه 26 مرداد 1393, 11:40 صبح
با عرض سلام. یه سوال ذهنمو مشغول کرده.آیا تو C++‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎‎‎‎ همچین امکانی هست که مثلا ما تابعی داریم با نام DoSomeThing که یه آرگومان از نوع int داره ما میخوایم که کاربر اگه بخواد تابع رو به شکل زیر فراخونی کنه با ارور مواجه بشه
DoSomeThing(5);
و باید به صورت زیر اول یه متغیر از نوع int بسازه و بعد اون متغیر رو به عنوان پارامتر به تابع بده
int i=5;
DoSomeThing(i);
ایا راهی هست؟
آره راه هست نوع اول متغیر rvalue هست نوع دوم lvalue (http://www.7khatcode.com/796/%D9%85%D8%B9%D9%86%DB%8C-lvalue-%D9%88-rvalue-%DA%86%DB%8C%D9%87-%D8%9F?show=796#q796) از C++‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎11 (http://www.7khatcode.com/3180/%D9%88%DB%8C%DA%98%DA%AF%DB%8C-%D9%87%D8%A7%DB%8C-c-11?show=3189#a3189)به بعد میشه این 2 رو با استفاده از universal refrence (http://www.7khatcode.com/43/%D9%85%D9%86%D8%B8%D9%88%D8%B1-%D8%A7%D8%B2-move-semantics-%D8%AF%D8%B1-c-11-%DA%86%DB%8C%D9%87-%D8%9F) , static_assert از هم تشخیص داد
به این شکل تابع رو بنویسید :

#include <iostream>
#include <type_traits>


template <class T>
void DoSomeThing(T&&/*universal refrence */ i){
static_assert(std::is_lvalue_reference<T&&>::value, "Error ");
}


int main()
{
int i = 5;
DoSomeThing(i);
//DoSomeThing(5); error
}




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

لطفا اسپم نکن الان این پست شما چه ربطی به سوال داره ؟



دوست عزیز این دستور زبان c نیست و هر کامپایلری برا خودش یه چیزی الکی زده

الان دقیقا کدوم کامپایلر چه چیز الکی ای زده !!!!؟ چی دستوز زبان C نیست !؟

sa1378
یک شنبه 26 مرداد 1393, 12:18 عصر
الان دقیقا کدوم کامپایلر چه چیز الکی ای زده !!!!؟ چی دستوز زبان C نیست !؟

دوست عزیز کامپایلر ها در بعضی قوائد با هم متفاوت هستن
الان همینطور که من گفتم اون کد توی dev جواب میده
مثال دیگه ای یادم نیست که براتون بزنم و من هم بجز dev و visual تا حالا چیز دیگه ای استفاده نکردم
ولی توی فیلم های آقای بازرگان که دیده بودم هم گفته بود که بعضی ترفند ها تو بعضی کامپایلر ها و ide ها غیرقابل قبول هستن ولی در بعضی های دیگه میشه اونا رو نوشت

omid_kma
یک شنبه 26 مرداد 1393, 12:23 عصر
دوست عزیز کامپایلر ها در بعضی قوائد با هم متفاوت هستن
الان همینطور که من گفتم اون کد توی dev جواب میده
مثال دیگه ای یادم نیست که براتون بزنم و من هم بجز dev و visual تا حالا چیز دیگه ای استفاده نکردم
ولی توی فیلم های آقای بازرگان که دیده بودم هم گفته بود که بعضی ترفند ها تو بعضی کامپایلر ها و ide ها غیرقابل قبول هستن ولی در بعضی های دیگه میشه اونا رو نوشت
اون کدی که نوشتید توی همه کامپایلر ها اجرا میشه مگه قرار بود کامپایل نشه ؟!
دوست عزیز نمشه که روی هوا حرف زد بعضی قوائد که با هم فرق می کنن مربوط میشه به نسخه های متفاوت از استاندارد که پیاده سازی کردن وگرنه کامپایلر ها چیز الکی برای خودشون نمیزنن
شما که تاحالا امتحان نکردین بهتره نظر کلی هم ندین !

sa1378
یک شنبه 26 مرداد 1393, 12:27 عصر
اون کدی که نوشتید توی همه کامپایلر ها اجرا میشه مگه قرار بود اجرا نشه ؟!
دوست عزیز نمشه که روی هوا حرف زد بعضی قوائد که با هم فرق می کنن مربوط میشه به نسخه های متفاوت از استاندارد که پیاده سازی کردن وگرنه کامپایلر ها چیز الکی برای خودشون نمیزنن
شما که تاحالا امتحان نکردین بهتره نظر کلی هم ندین !

اصلا موضوع تاپیک فهمیدین چیه؟؟؟
ایشون گفتن چرا عدد به تابع بدیم اجرا نمیشه؟
من گفتم تو کامپایلر من اجرا میشه
شما چی دارین میگید؟؟؟؟؟!!!!

dasssnj
یک شنبه 26 مرداد 1393, 12:32 عصر
نه مثل این که ایشون گفتن میشه و دنبال راهی بودن که نشه.

کامبیز اسدزاده
یک شنبه 26 مرداد 1393, 13:33 عصر
فکر میکنم قوانین انجمن ها کشکه نه؟
تا چند پست دیگه هیمنطوری اسپم زدن رو ادامه بدین تاپیک رو حذف خواهم کرد.

ciavosh
جمعه 31 مرداد 1393, 16:41 عصر
سلام.
پارامتر تابع رو باید به شکل مرجع تعریف کنید. مثال :
int MyFunction(int & i)
{
//...
};

کسی این رو امتحان کرده؟ تا آنجایی که من خوندم این کد خواسته استارتر رو برآورده نمیکنه چون ++C یک متغیر موقت میسازه و رفرنسش رو به تابع میده.

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

motherboard
جمعه 31 مرداد 1393, 21:27 عصر
حتما نیاز نیست که11++c داشته باشی .کد زیر هم کار راه بنداز هست.

#include <iostream>
using namespace std;
void a(int &);
int main()
{ int i=5;
a(i);
}
void a(int& x)
{cout<<"a";}

ciavosh
جمعه 31 مرداد 1393, 23:19 عصر
حتما نیاز نیست که11++c داشته باشی .کد زیر هم کار راه بنداز هست.

#include <iostream>
using namespace std;
void a(int &);
int main()
{ int i=5;
a(i);
}
void a(int& x)
{cout<<"a";}


خروجی این کد قراره چی باشه؟

motherboard
جمعه 31 مرداد 1393, 23:29 عصر
خروجی این کد قراره چی باشه؟
خروجیش که مشخص هست!!! میشه کاراکتر a.اون طور که من از خواسته استارتر فهمیدم اینه که ایشون می خواهد کاری کند که تابع با گرفتن یک عدد صحیح اون هم به صورت کاملا مستقیم در برنامه باعث ایجاد ارور شود.ولی اگر توسط یک متغیری مانند i این اتفاق افتاد برنامه به درستی و بدون هیچ اروری اجرا شود.

ciavosh
جمعه 31 مرداد 1393, 23:49 عصر
خروجیش که مشخص هست!!! میشه کاراکتر a.اون طور که من از خواسته استارتر فهمیدم اینه که ایشون می خواهد کاری کند که تابع با گرفتن یک عدد صحیح اون هم به صورت کاملا مستقیم در برنامه باعث ایجاد ارور شود.ولی اگر توسط یک متغیری مانند i این اتفاق افتاد برنامه به درستی و بدون هیچ اروری اجرا شود.

خب این درست. ولی این کد باعث میشه که درون تابع، i قابل تغییر بشه.

motherboard
جمعه 31 مرداد 1393, 23:58 عصر
خب این درست. ولی این کد باعث میشه که درون تابع، i قابل تغییر بشه.
اگر از const استفاده کنید.دیگه هیچ چیز تغییر نمی کنه.

#include <iostream>
using namespace std;
void a(const int &);
int main()
{ int i=5;
a(i);
}
void a(const int& x)
{cout<<"a";}

omid_kma
شنبه 01 شهریور 1393, 01:17 صبح
اگر به شکل const& تعریف بشه به این شکل هم قابل صدا زدن میشه مثلا a(6)l

ciavosh
شنبه 01 شهریور 1393, 09:19 صبح
اگر const کنیم، اعداد ثابت را هم قبول خواهد کرد. همانطور که گفتم کامپایلر مقدار ثابت عددی را در یک متغیر موقت قرار داده و رفرنس آن را به تابع ارسال خواهد کرد.

motherboard
شنبه 01 شهریور 1393, 10:48 صبح
اگر به شکل const& تعریف بشه به این شکل هم قابل صدا زدن میشه مثلا a(6)l

اگر const کنیم، اعداد ثابت را هم قبول خواهد کرد. همانطور که گفتم کامپایلر مقدار ثابت عددی را در یک متغیر موقت قرار داده و رفرنس آن را به تابع ارسال خواهد کرد.
اره.بچه ها راست میگید اگه از const استفاده کنیم با (6) a هم فراخوانی میشه.تستش نکرده بودم.فکر می کردم اگه const بذاریم حل میشه.:تشویق:
اما از بچه ها کی کد بلاکس داره؟؟ الان نسخه کد بلاکس من 13.12 هست.اما وقتی اون کد 11 ++ c رو وارد کردم.شناسایی نکرد.

omid_kma
شنبه 01 شهریور 1393, 12:28 عصر
سلام.پارامتر تابع رو باید به شکل مرجع تعریف کنید. مثال :



1
2
3
4

int MyFunction(int & i)
{
//...
};









کسی این رو امتحان کرده؟ تا آنجایی که من خوندم این کد خواسته استارتر رو برآورده نمیکنه چون ++C یک متغیر موقت میسازه و رفرنسش رو به تابع میده.


این کد بستگی به کامپایلر داره بعضی از کامپایلر ها زمان کامپایل اگر مقدار موقت به این تابع فرستاده بشه ارور میدن هر چند که این جور تعریف راه درستی نیست . اگر هم ارور ندن کد undefine behavior هست چون اون متغیر موقت به محض ارسال به تابع از بین میره .
ضمنا ++c متغیر موقت رو میسازه ولی این که بگیم آدرسش رو میفرسته به تابع زیاد صحیح نیست به شکل دیگه ای کار میکنه .


خواسته استارتر اینه که کامپایلر اجازه نده یه ثابت به تابع ارسال بشه که منطقی نداره. اگر استارتر محترم دلیل انجام این کارو بگن...
.
چرا منطق نداره ؟ درباره move semantic مطالعه کنید کاربردش رو پیدا می کنید
(فرض کنید یک تابع برای مساوی گذاشتن 2 تا وکتور دارید که ورودیش 2تا وکتور هست اگر بتونید تشخیص بدید ورودی دوم وکتور موقت هست میشه بجای کپی کردن اطلاعات فقط محل اشاره گر data وکتور رو عوض کرد که بهش move میگن)

omid_kma
شنبه 01 شهریور 1393, 12:36 عصر
اره.بچه ها راست میگید اگه از const استفاده کنیم با (6) a هم فراخوانی میشه.تستش نکرده بودم.فکر می کردم اگه const بذاریم حل میشه.:تشویق:
اما از بچه ها کی کد بلاکس داره؟؟ الان نسخه کد بلاکس من 13.12 هست.اما وقتی اون کد 11 ++ c رو وارد کردم.شناسایی نکرد.
از قسمتsetting --> compiler تیک have g++ follow C++‎11 ... رو بزن
البته شاید با این کار هم کامپایل نشه چون codeblocks نسخه پیش فرض gcc که استفاده می کنه قدیمی هست(4.6 استفاده می کنه آخرین ورژن gcc نسخه 4.9 هست )
اگر Qt creator با mingw روی سیستمت نصبه میتونی آدرس کامپایلر اون رو بدی (از قسمت setting -->Compiler -->Toolchain executables )
اگر هم نیست میتونی آخرین نسخه mingw رو با cygwin بگیری

ciavosh
شنبه 01 شهریور 1393, 12:57 عصر
آره راه هست نوع اول متغیر rvalue هست نوع دوم lvalue (http://www.7khatcode.com/796/%D9%85%D8%B9%D9%86%DB%8C-lvalue-%D9%88-rvalue-%DA%86%DB%8C%D9%87-%D8%9F?show=796#q796) از C++‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ ‎‎11 (http://www.7khatcode.com/3180/%D9%88%DB%8C%DA%98%DA%AF%DB%8C-%D9%87%D8%A7%DB%8C-c-11?show=3189#a3189)به بعد میشه این 2 رو با استفاده از universal refrence (http://www.7khatcode.com/43/%D9%85%D9%86%D8%B8%D9%88%D8%B1-%D8%A7%D8%B2-move-semantics-%D8%AF%D8%B1-c-11-%DA%86%DB%8C%D9%87-%D8%9F) , static_assert از هم تشخیص داد
به این شکل تابع رو بنویسید :

#include <iostream>
#include <type_traits>


template <class T>
void DoSomeThing(T&&/*universal refrence */ i){
static_assert(std::is_lvalue_reference<T&&>::value, "Error ");
}


int main()
{
int i = 5;
DoSomeThing(i);
//DoSomeThing(5); error
}




الآن std::is_lvalue_reference تشخیص میده lvalue هست یا نه. ولی چه 5 رو به تابع بفرستیم چه i قاعدتاً در هر دو مورد false بر میگردونه. نه؟:متفکر:

omid_kma
شنبه 01 شهریور 1393, 13:33 عصر
الآن std::is_lvalue_reference تشخیص میده lvalue هست یا نه. ولی چه 5 رو به تابع بفرستیم چه i قاعدتاً در هر دو مورد false بر میگردونه. نه؟:متفکر:
تشخیص میده که lvalue refrence هست نه lvalue
ما نوع &&T رو چک می کنیم که با توجه به مقدار ورودی متفاوته
نتیجه اجرای آنلاین کد رو ببینید حالت دوم ارور داده میشه
https://ideone.com/ucqlaL
این که چرا این طور میشه مربوط میشه به قاعده refrence collapsing