PDA

View Full Version : استفاده از qsort



sa1378
پنج شنبه 02 مرداد 1393, 09:47 صبح
سلام
اشکال ایک کد چیه که اصلا روی آرایه تغییر ایجاد نمیکنه و همون رو بدون مرتب کردن برمیگردونه؟
double b[100];
int num;

cout<<"How Many Numbers Do You Want To Be Sorted?(FLOAT)"<<endl;
cin>>num;
for(int x2=0 ; x2<=num-1;x2++)
{
cout<<"Write Number"<<x2+1<<" :"<<endl;
cin>>b[x2];
}
qsort((void*)b,num,sizeof(double),mycompare);//avali : araye ke mikhahim moratab konim az no@ void * //dovomi : tedad azaie araye
//sevomi : andaze har ozve(meghdar khoone eshghalh shode) //chaahaaromi : Tabei ke bayad besazim ke be soorat zir bashad:
//do moteghayer CONST VOID * daryaft konad
//agar avali bozorgtar bood adad mosbat , agar mosavi boodand 0 , va agar dovomi bozorgtar bood adad manfi bargardanad

cout<<endl<<endl;

cout<<"Your Numbers Are Ready:"<<endl;
for(int x3=0 ; x3<=num-1;x3++)
{
cout<<b[x3]<<endl;
}

rahnema1
پنج شنبه 02 مرداد 1393, 10:50 صبح
سلام، شما تابع مقایسه را که تعریف نکردید

int mycompare(const void* a,const void* b)
{
if ( *(double*)a > *(double*)b ) return 1;
if ( *(double*)a < *(double*)b ) return -1;
return 0;
}
//...
qsort(b,num,sizeof(double),mycompare);
از تابع sort موجود در هدر <algorithm> هم میتونید استفاده کنید

sa1378
پنج شنبه 02 مرداد 1393, 11:37 صبح
تعریف کردم اینجا ننوشتم
int mycompare(const void *ar1,const void *ar2)// qsort az ma mikhahad ke yek tabe baraie moghayese besazim
{

//do moteghayer void hastand va no@ nadarand pas do moteghayer komaki misazim
double *a,*b;
a=(double *)ar1;
b=(double *)ar2;

if(a>b)
return 1;

else if(a==b)
return 0;

return -1;


//bejye in hame dardesar mitavan nevesht :
return (*((double *)ar1)) - (*((double *)ar2));

}

rahnema1
پنج شنبه 02 مرداد 1393, 12:09 عصر
تعریف کردم اینجا ننوشتم
int mycompare(const void *ar1,const void *ar2)// qsort az ma mikhahad ke yek tabe baraie moghayese besazim
{

//do moteghayer void hastand va no@ nadarand pas do moteghayer komaki misazim
double *a,*b;
a=(double *)ar1;
b=(double *)ar2;

if(a>b)
return 1;

else if(a==b)
return 0;

return -1;


//bejye in hame dardesar mitavan nevesht :
return (*((double *)ar1)) - (*((double *)ar2));

}

اون مورد اولی اشکالش اینج.ر باید رفع بشه

double a,b;
a=*(double *)ar1;
b=*(double *)ar2;


صورت دومی که نوشتین یه اشکالی پیش میاد
اون مقدار double یعنی نتیجه تفریق می خواهد به صورت ضمنی به int تبدیل بشه می دونیم که دامنه مقادیری که double میتونه در بر بگیره بیشتر از int هست در نتیجه اگه نتیجه تفریق بیش از دامنه مقادیر قابل قبول int شد بر طبق استاندارد c++11 منجر به undefined behavior خواهد شد

sa1378
پنج شنبه 02 مرداد 1393, 14:10 عصر
اون مورد اولی اشکالش اینج.ر باید رفع بشه

double a,b;
a=*(double *)ar1;
b=*(double *)ar2;


صورت دومی که نوشتین یه اشکالی پیش میاد
اون مقدار double یعنی نتیجه تفریق می خواهد به صورت ضمنی به int تبدیل بشه می دونیم که دامنه مقادیری که double میتونه در بر بگیره بیشتر از int هست در نتیجه اگه نتیجه تفریق بیش از دامنه مقادیر قابل قبول int شد بر طبق استاندارد C++‎11 منجر به undefined behavior خواهد شد

ممنون
درست شد
ولی من کلا این پوینترهارو درست نمیفهمم
ولی برای مشکل دوم چیکار کنم؟(هرچند که که اون کد اصلا اجرا نمیشه و قبلش return میکنه)
تابع qsort یه تابع مقایسه میخواد که int برگردونه

rahnema1
پنج شنبه 02 مرداد 1393, 14:48 عصر
ببینید این تابع را جوری طراحی کرده اند که هر نوع ورودی را بتونه بگیره به خاطر همین پارامترهای ورودی اون از نوع اشاره گر void هست . چون اشاره گر void قابل تبدیل به انواع اشاره گر هست
نکته دیگه اینه که تابع sort نمیاد مقدار های داخل آرایه را به تابع compare بده بلکه آدرس اونها را به compare میده
فرض کنید مثلا تابع sort می خواد شروع به کار کنه و مثلا دو خانه اول آرایه را می خواد با هم مقایسه کنه. میاد آدرس اون دو خونه را می گیره و به compare میده. اشاره گر از نوع double خود به خود تبدیل به اشاره گر از نوع void میشه
داخل تابع compare ما دو تا اشاره گر داریم از نوع void .برای اینکه بتونید از اونها استفاده کنیم باید اونها را ابتدا به اشاره گر از نوع double تبدیل کنیم که از طریق (* double) صورت می گیره
حالا که اشاره گر از نوع double داریم باید محتوای آدرسی که اون اشاره گر بهش اشاره می کنه را بکشیم بیرون که از طریق (* double)* عملی میشه. بنابراین محتوای آدرس از نوع double خواهد بود نه از نوع اشاره گر به double

در مورد حل مشکل دوم مطمئن نیستم بشه حلش کرد حتی اگه به صورت صریح cast انجام بشه