HELP בC - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

HELP בC


orninyo

Recommended Posts

שלום לכולם.

למה הפלט של התוכנית הזאת לא נכון?

הסבר על התכנית: מקבל מהמשתמש מספר , ומדפיס את האינדקס של השורה במטריצה בה יש את מספר האפסים שתואם את המספר שנקלט

אסור להשתמש בלולאות.

#include <stdio.h>
#include <stdlib.h>
#define N 4
unsigned count(const float [],int n); //מקבלת מערך ומחזירה את מספר האפסים בו
unsigned ZeroElements(int ,const float *AP[],int ); //
int check(const void* ,const void* );
void main()
{
int x=0,n,i;
float mat[][N]=
{
{7,2,3,5},
{1,0,0,0},
{2,0,0,1},
{0,0,0,-2.99F},
{0,1,-1,-5.123F},
{0,0,0,0}
};
float* AP[sizeof(mat)/sizeof(mat[0])];
puts("Mat after qsort:");
for(i=0;i<sizeof(mat)/sizeof(mat[0]);i++)
AP[i]=mat[i];
puts("Pleae enter the number of zero elements, in the array to search for:");
fflush(stdin);
scanf("%d",&n);
i=ZeroElements(n,AP,sizeof(AP)/sizeof(AP[0]));
if(i!=99)
{
printf("\n%u times of zero elements, found at row index:%u\n", n, i );
}
else
puts("Not found!");

}
unsigned count(const float arr[], int n)
{
if( n == 1 )
{
if( arr[n-1] == 0 )
{
return 1;
}
else
{
return 0;
}
}
else
{
if( arr[n-1] == 0 )
{
return 1 + count(arr, n-1);
}
else
{
return count(arr, n-1);

}
}
}
int check(const void *el1,const void *el2)
{
if(*(int*)el1==count((float*)el2, N ))
return 0;
else
return 1;
}
unsigned ZeroElements(int n,const float *AP[],int i)
{
int* ans;
if(i<0) return 99;
ans=bsearch(&n,*AP,sizeof(AP)/sizeof(AP[0]),sizeof(AP[0]),check);
if(ans) return i;
return ZeroElements(n,++AP,i-1);
}

תודה מראש.

קישור לתוכן
שתף באתרים אחרים

רפרפתי קצת על התוכנית, ומצאתי שתי בעיות:

1. קודם כל, bsearch עושה חיפוש בינארי, ולכן היא דורשת שהקלט יהיה ממוין (אצלך הוא לא).

2. אתה קורא ל-bsearch על כל שורה בנפרד, במקום על המטריצה עצמה.

קישור לתוכן
שתף באתרים אחרים

למה עדיין זה נותן פלט בלתי צפוי?

#include <stdio.h>
#include <stdlib.h>
#define N 4
unsigned count(const float [],int n); //מקבלת מערך ומחזירה את מספר האפסים בו
int check(const void* ,const void* );
void main()
{
int x=0,n,i;
float** ans;
float mat[][N]=
{
{7,2,3,5},
{0,1,-1,-5.123F},
{2,0,0,1},
{1,0,0,0},
{0,0,0,-2.99F},
{0,0,0,0}
};
float* AP[sizeof(mat)/sizeof(mat[0])];
puts("Mat after qsort:");
for(i=0;i<sizeof(mat)/sizeof(mat[0]);i++)
AP[i]=mat[i];
puts("Pleae enter the number of zero elements, in the array to search for:");
fflush(stdin);
scanf("%d",&n);
ans=bsearch(&n,AP,sizeof(AP)/sizeof(AP[0]),sizeof(AP[0]),check);
printf("Found at index: %d ",ans-AP);
}
unsigned count(const float arr[], int n)
{
if( n == 1 )
{
if( arr[n-1] == 0 )
{
return 1;
}
else
{
return 0;
}
}
else
{
if( arr[n-1] == 0 )
{
return 1 + count(arr, n-1);
}
else
{
return count(arr, n-1);

}
}
}
int check(const void *el1,const void *el2)
{
return *(int*)el1-count((float*)el2, N );
}

קישור לתוכן
שתף באתרים אחרים

א. הקלט לדוגמא : 1 הפלט : -311170

ב. הם אותו טיפוס AP[] **ans* זה אותו דבר לא ? האופרטור * שקול ל[]

ג.מה שמשונה שהbsearch מחזיר לי תמיד כתובת מאופסת, זה NULL ?

אולי אני לא שולח טוב את הפרמטרים לbsearch כי בcheck

el2 תמיד שווה לאפס

קישור לתוכן
שתף באתרים אחרים

(גרר, עד שהספקתי לענות על השאלות שלך אתה מודיע שפתרת את התרגיל?? טוב נו, קח בכל מקרה)

א. זה כנראה נובע מ-ג'.

ב. בגדול זה אותו טיפוס, אבל כשאתה עושה חישובים נומריים עליהם (+ או -) אז הקומפיילר לא ממש יודע להתמודד אם זה.

אני אתן לך דוגמה. נניח יש לך את קטע הקוד הבא:

int arr[2];
printf("%d", &arr[1] - &arr[0]);

ההפרש בין שני המצביעים הוא 4 (שזה גודל של int), אבל הקומפיילר יודע שהתכוונת למצביעים ל-int ולכן מחזיר 1 (הוא מחלק ב-sizeof).

במקרה הזה:

short arr[2];
printf("%d", &arr[1] - &arr[0]);

ההפרש בין שני המצביעים הוא 2 (גודל של float), אבל הקומפיילר ידאג להדפיס גם כן 1.

אבל אם תנסה לחשב את ההפרש בין שני מצביעים מטיפוס שונה (נניח שאחד הוא int והאחר הוא short), הקומפיילר לא בדיוק יידע מה לעשות (הוא כנראה ימיר אחד מהם לטיפוס של האחר) והתוצאה תהיה לא צפויה.

במקרה שלך, ans הוא מערך של מצביעים (ה-sizeof של כל אחד הוא 4), ו-AP הוא מערך של float[N] (ה-sizeof של כל אחד מהם הוא 4*N). לכן, חישוב ההפרש ביניהם ייתן תוצאה לא צפויה.

ג. כן, NULL == 0. התכנית שלך צריכה להודיע שהשורה לא נמצאה במקרה ש-ans==NULL.

קישור לתוכן
שתף באתרים אחרים

מצטער שטרטרתי אותך סתם :-X

בכל אופן לא נראה לי שהבעיה הייתה בקטע של החיסור

הבעיה שאני עליתי עליה היא שבהתחלה עשיתי קאסטינג למצביע לfloat שבעצם bsearch קיבלה מערך מצביעים

לכן הטעות הייתה בקאסטינג שבעצם צריך להיות מצביע למצביע לfloat

אולי זה מה שהתכוונת , בכל אופן הינה התכנית הסופית

#include <stdio.h>
#include <stdlib.h>
#define N 4
#define NotFound 999
typedef void (*pfunc)(float);
unsigned count(const float [],int n); //פונקציה מקבלת מערך וכמות האברים שלו, מחזירה כמה אפסים יש בו
int comp(const void*,const void*); //countבודקת את מספר האפסים בעזרת qsort פונקציה פנימית של
void printFormat1(float ); //פונקציה שמדפיסה מספר עם דיוק של ספרה אחת
void printFormat2(float ); //פונקציה שמדפיסה מספר עם דיוק של שתי ספרות
//פונקציה שמדפיסה אברי מערך:
void printArray(const float [],int ,void(*)(float)); //פונקציה מקבלת מערך וכמות האברים שלו ומצביע לפונקצית ההדפסה
//פונקציה שמדפיסה מטריצה:
void printMat(const float mat[][N],int , void(*)(float));//פונקציה מקבלת מטריצה וכמות השורות, ומצביע לפונקצית ההדפסה
int check(const void* ,const void* ); //בודקת עם האלמנט הראשון שווה למספר האפסים באלמנט השניbsearch פונקציה פנימית של
void main()
{
int x=0,n,i;
float** ans;
pfunc print;
float mat[][N]= //float מטריצה של מספרי
{
{7,2,3,5},
{1,0,0,0},
{2,0,0,1},
{0,0,0,-2.99F},
{0,1,-1,-5.123F},
{0,0,0,0}

};
float* AP[sizeof(mat)/sizeof(mat[0])]; //מערך של מצביעים בגודל כמות השורות של המטריצה
qsort(mat,sizeof(mat)/sizeof(mat[0]),sizeof(mat[0]),comp);//ממיינת את המטריצה בסדר עולה לפי מספר האפסים בכל שורה
puts("Press 1 if you want to print with only 1 digit precision.");
puts("Press any other number for 2 digits precision:");
//לפי זה נקבע האם כל התוצאות מעכשיו יוצגו לפי דיוק של ספרה אחת אחרי הנקודה או שתיים
scanf("%d",&x);
print=x==1?&printFormat1:&printFormat2; //מתאימה את מצביע לפונקצית פורמט ההדפסה המתאימה לקלט של המשתמש
puts("Mat after qsort:");
printMat(mat,sizeof(mat)/sizeof(mat[0]),print); //מדפיסה את המטריצה הממויינת
for(i=0;i<sizeof(mat)/sizeof(mat[0]);i++) //כל איבר במערך המצביעים מצביע לשורה במטריצה
AP[i]=mat[i];
puts("Pleae enter the number of zero elements, in the array to search for:");
fflush(stdin);
scanf("%d",&n);
if(ans=bsearch(&n,AP,sizeof(AP)/sizeof(AP[0]),sizeof(AP[0]),check)) //אם נמצא מערך עם מספר אפסים השווה למספר שנקלט מהמשתמש המשך
{
printf("\n%u times of zero elements, found at row index: %u\n", n, ans-AP);
puts("The row is:");
printArray(AP[ans-AP],N,print);
puts("");
}
else
puts("Not found!");
}
unsigned count(const float arr[], int n)
{
if( n == 1 )
{
if( arr[n-1] == 0 )
{
return 1;
}
else
{
return 0;
}
}
else
{
if( arr[n-1] == 0 )
{
return 1 + count(arr, n-1);
}
else
{
return count(arr, n-1);

}
}
}
int comp(const void* el1,const void* el2)
{
int x=count((float*)el1, N );
int y=count((float*)el2, N );
return x-y;
}
void printFormat1(float n)
{
printf("%.1f ",n);
}
void printFormat2(float n)
{
printf("%.2f ",n);
}
void printArray(const float arr[],int n,void (*print)(float))
{
if(n!=1)
{
printArray(arr,n-1,print);
}
print(arr[n-1]);
}
void printMat(const float mat[][N],int n,void (*print)(float))
{
if(n!=1)
printMat(mat,n-1,print);
printArray(mat[n-1],N,print);
puts("");
}
int check(const void *el1,const void *el2)
{
return *(const int*)el1-count(*((float**)el2), N );
}

קרדיט לשניצל ;)

קישור לתוכן
שתף באתרים אחרים

הו, C היא שפה כל כך מופלאה! היא משלבת את הכוח והמהירות של אסמבלי יחד עם קלות הכתיבה ותחזוקה של אסמבלי.

בכל מקרה לי ברור שהבעיה העיקרית שלך היא שכתבת הערות בעברית בקוד שלך. זו תועבה.

קישור לתוכן
שתף באתרים אחרים

הבעיה שאני עליתי עליה היא שבהתחלה עשיתי קאסטינג למצביע לfloat שבעצם bsearch קיבלה מערך מצביעים

לכן הטעות הייתה בקאסטינג שבעצם צריך להיות מצביע למצביע לfloat

למעשה, k-o-b-y התייחס לזה בהודעה שכאן:

http://hwzone.co.il/community/index.php?topic=285829.msg2513128#msg2513128

ידעתי שמשהו שם לא בסדר, I just couldn't quite put my finger on it.

ואכן, תכנות כזה ב-C (בעיקר התעסקות עם מצביעים לפונקציות) זה זוועה.

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

×
  • צור חדש...