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

שאלה ב C


orninyo

Recommended Posts

למה אני מקבל שגיאות (formal parameter one diffrent from declaration) על הפונקציה הבאה? :

void sort(float **mat,int n)

{

if(n==0) return;

qsort(mat[n],sizeof(mat)/sizeof(mat[0]),sizeof(mat[0]),comp);

return sort(**mat,n-1);

}

היא מקבלת מטריצה וגודל המטריצה, עוברת שורה שורה במטריצה וממיינת אותה

תודה

[br]

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

1)אתה מקבל מצביע ומשתמש בSIZEOF. זה נו נו נו.

2)לא צריך return אם הפונקציה לא מחזירה כלום.

3)**mat יתן לך את הערך במקום הראשון, ולא משהו שאני לא מבין מה ניסית לעשות שם(בכל מקרה, אתה צריך לשלוח לשם מטריצה, ולא ערך ספציפי).

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

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

קודם כל, כשאתה כותב קוד תשתמש בכפתור "הכנס קוד" (הכפתור עם תמונה של סולמית).

לגבי השאלה:

א. אתה מצהיר איפשהו על הפונקציה (בנפרד מהמימוש ששמת כאן)? אם כן, כתוב כאן את שורת ההצהרה.

ב. השורה הזו בעייתית:

return sort(**mat,n-1);

הטיפוס של **mat הוא הרי float, ו-sort מצפה לקבל float**. אתה צריך להחליף את השורה ב:

return sort(mat,n-1);

אגב, למה אתה משתמש ברקורסיה ולא בלולאה פשוטה? זה חלק מהתרגיל?

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

תשובות:

ל UnsignedInteger :

בקשר לsizeof אני חייב אותו בשביל לדעת את אורך המערך לא? כי זה אמור להיות פונקציה כללית שתתאים לכל מטריצה עם גודל מערכים לא קבוע.

הורדתי את הreturn (הפונקציה המעודכנת בסוף)

הפונקציה אמורה לקבל מטריצה וגודלה בגלל זה קיבלתי את זה כמצביע למצביע הרי מטריצה מערך דו מיימדי (זה מה שאני מבין אם לא תקן אותי)

אגב גודל (מספר המערכים) של מטריצה אני מוצא עם sizeof(mat) לא?

לשניצל:

אסור לי להשתמש בלולאות זה חלק מהתרגיל (בגלל זה הסתבכתי :) )

שינתי את השורה שאמרת.

הינה הפרוטוטייפ והתכנית המלאה (החלק שנוגע לפונקציה הזאת):

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

#include <stdio.h>
#include <stdlib.h>
#define N 20
unsigned count(const float [],int n);
void comp(const void,const void);
void sort(float [][N],int);
void main()
{
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}
};
sort(mat,sizeof(mat));
}
unsigned count(const float mat[], int n)
{
if( n == 1 )
{
if( mat[n-1] == 0 )
{
return 1;
}
else
{
return 0;
}
}
else
{
if( mat[n-1] == 0 )
{
return 1 + count(mat, n-1);
}
else
{
return count(mat, n-1);

}
}
}
void sort(mat,n)
{
if(n==0) exit(0);
qsort(mat[n],sizeof(mat)/sizeof(mat[0]),sizeof(mat[0]),comp);
sort(mat,n-1);
}
void comp(const void* el1,const void* el2)
{
unsigned x,y;
x=count(*(char**)el1,(int*)sizeof(el1)/sizeof(el1[0]))
y=count(*(char**)el2,(int*)sizeof(el2)/sizeof(el2[0]))
if(x==y)return 0;
if(x>y)return -1;
return 1;
}

[br]פורסם בתאריך: 2.09.2007 בשעה 14:48:08


ככה המטריצה אמורה להראות לאחר המיון:

 7.00 2.00 3.00 5.00		//אין כלל אפסים בשורה
0.00 1.00 -1.00 -5.12 //יש רק אפס אחד בשורה
2.00 0.00 0.00 1.00 //יש שני אפסים בשורה וכך הלאה
0.00 0.00 0.00 -2.99
1.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00

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

אבל אמרת שבגלל שהפונצקיה VOID עדיף שלא יהיה RETURN לכן שיניתי לEXIT

למה עדיף RETURN ?

אלה השגיאות:

formal parameter 1 diffrent from decleration

formal parameter 2 diffrent from declaration

function : incompatible from void (_codecl*)(const void ,const void) ........

נראה לי שהבעיה בכל הקטע של הSIZEOF

לא נראה לי שאני עושה נכון את מה שאני מתכוון לעשות

הפונקציה מקבלת מטריצה וגודלה (שאותו אני מוצא בקריאה ע"י sizeof(mat))

וכל פעם שולחת את השורה הבאה במטריצה לQSORT שמקבל את מה שהוא מקבל וגם SIZEOF שאמור לתת את מספר האייברים בשורה

השאלה איך עושים את זה נכון.

אגב ניתן למיין עם QSORT מטריצות שלמות? ברמה של שורות או אייברים

או שחייב לעשות כמו שאני עשיתי (מנסה לעשות) שורה שורה?

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

למה אתה לא רושם כאן את הודעת השגיאה במלואה? זה מקשה מאוד להבין איזו שורה גורמת את הבעיה.

לגבי exit/return - הפונקציה exit יוצאת מהתכנית. הפקודה return סוגרת את הפונקציה (כן משתמשים בה אם אתה רוצה לצאת מהפונקציה באמצע הפעולה).

אחרי שהסתכלתי על התיעוד של qsort, נראה לי שהבנתי את בעיית הקומפילציה - הפונקציה comp צריכה לקבל צמד void* ולהחזיר int, ולא void (ההצהרה על הפונקציה גם לא תואמת את המימוש שלה).

להבא, כשאתה כותב פונקציה ואת ה-prototype שלה, פשוט תעשה copy-paste כדי לוודא שהם זהים. אם אתה משנה אחד, שנה גם את האחר.

לפי מה שהבנתי, אתה צריך למיין את השורות של המטריצה, ולא כל שורה בנפרד. לכן, צריכה להיות לך רק קריאה אחת ל-qsort, כשאתה מעביר את כל המטריצה כפרמטר. שים לב ש-qsort מקבלת void*, שב-C אומר "מצביע לכל דבר" - כלומר זה יכול להיות מצביע\מערך של int, או מצביע\מערך של מערכים (כמו במקרה שלך).

נראה שהפונקציה comp תקינה מבחינת הפעולה, פרט לכך שמשום מה אתה ממיר ל-char ולא ל-float.

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

לפי מה שאתה אומר אני לא צריך את הפונקציה SORT אלה ישר במיין להעביר את כל המטריצה לQSORT ככה: (?)

	qsort(mat,sizeof(mat)/sizeof(mat[0]),sizeof(mat[0]),comp);

אוסיף גם את הפונקציה COMP :
void comp(const void* el1,const void* el2)
{
unsigned x,y;
x=count(*(float**)el1,(float*)sizeof(el1)/sizeof(el1[0]))
y=count(*(float**)el2,(float*)sizeof(el2)/sizeof(el2[0]))
if(x==y)return 0;
if(x>y)return -1;
return 1;
}

כמו שאתה רואה COMP משתמשת בעוד פונקציה בשם COUNT שאוסיף גם אותה :
unsigned count(const float mat[], int n)
{
if( n == 1 )
{
if( mat[n-1] == 0 )
{
return 1;
}
else
{
return 0;
}
}
else
{
if( mat[n-1] == 0 )
{
return 1 + count(mat, n-1);
}
else
{
return count(mat, n-1);

}
}
}

בכל אופן לאחר השינויים הנ"ל עדיין אותן שגיאות :

c:\users\יעקובי אורן\documents\visual studio projects\dfdf\c44cc.c(49): warning C4028: formal parameter 1 different from declaration

c:\users\יעקובי אורן\documents\visual studio projects\dfdf\c44cc.c(49): warning C4028: formal parameter 2 different from declaration

c:\users\יעקובי אורן\documents\visual studio projects\uu\tar3.c(37): warning C4133: 'function' : incompatible types - from 'void (__cdecl *)(const void,const void)' to 'int (__cdecl *)(const void *,const void *)'

נ.ב

תודה על העזרה האדיבה עד כה.

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

א. כן, זה בדיוק מה שהתכוונתי אליו.

ב. הפונקציה comp צריכה להחזיר int, לא void. זה מה שהוא צועק עליך.

ג. למה ב-count אתה ממיר את ה-sizeof ל-float*? חוץ מזה, אתה בכלל לא חייב להשתמש שם ב-sizeof, כי אתה יודע את גודל השורה (N).

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

שיניתי את מה שאמרת , עדיין צועק.

אני משתמש בSIZEOF כי N הוא גודל מקסימלי לא הגודל המדוייק

אני מצרף את התוכנית במלואה + מטריצה נתונה (התכנית אמורה להיות מתאימה גם לכל מטירצה אחרת מאותו הטיפוס)

#include <stdio.h>
#include <stdlib.h>
#define N 20
unsigned count(const float [],int n);
void comp(const void,const void);
void sort(float [][N],int);
void main()
{
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}
};
qsort(mat,sizeof(mat)/sizeof(mat[0]),sizeof(mat[0]),comp);
}
unsigned count(const float mat[], int n)
{
if( n == 1 )
{
if( mat[n-1] == 0 )
{
return 1;
}
else
{
return 0;
}
}
else
{
if( mat[n-1] == 0 )
{
return 1 + count(mat, n-1);
}
else
{
return count(mat, n-1);

}
}
}
int comp(const void* el1,const void* el2)
{
unsigned x,y;
x=count(*(float**)el1,(int)sizeof(el1)/sizeof(el1[0]))
y=count(*(float**)el2,(int)sizeof(el2)/sizeof(el2[0]))
if(x==y)return 0;
if(x>y)return -1;
return 1;
}

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

עדיין לא תיקנת את comp.

תסתכל על שורת ה-prototype ועל הפונקציה עצמה, ותראה שהן שונות.

חוץ מזה, כשאתה מצהיר על מערך בגודל 20, אז ה-sizeof שלו יתייחס אליו כמערך בגודל 20, לא כמערך בגודל 4. אם אתה רוצה שהגודל האמיתי והגודל המקסימלי יהיו שונים, אתה חייב להעביר את הגודל ממש.

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

זה בדיוק מה שאני לא מבין איך לעשות

לפי מה שאני מבין הSIZEOF הזה :

y=count(*(float**)el2,(int)sizeof(el2)/sizeof(el2[0]))

מחזיר לי את גודל המצביע ולא גודל המערך ופה הבעיה

השאלה איך אני שולח את גודל המערך אותו אני חייב לשלוח כי הפונקציה COUNT צריכה אותו

או שיש לך רעיון אחר איך לעשות את המיון הזה ? (לפי מספר האפסים בכל שורה)

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

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

- כמו ששניצל אמר תתקן את ההצהרה של comp: למעלה הגדרת אותה כמחזירה void כשבהגדרה היא מחזירה int.

- ב comp , לא בדיוק הבנתי למה המרת את el1 ו el2 ל *(float**) . אתה בסה"כ צריך לעשות המרה ל float *.

- אתה לא יכול לעשות sizeof למשתנה (או מצביע) מסוג void. הטיפוס של המשתנה לא ידוע (מכאן השימוש ב void) אז גם הגודל שלו לא יודע. אתה צריך לבצע את ההמרה לטיפוס (במקרה שלך ל float*).

זה אמור להתקמפל:

#include <stdio.h>
#include <stdlib.h>
#define N 20
unsigned count(const float [],int n);
int comp(const void,const void);
void sort(float [][N],int);

void main()
{
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}
};
qsort(mat,sizeof(mat)/sizeof(mat[0]),sizeof(mat[0]),comp);
;
}
unsigned count(const float mat[], int n)
{
if( n == 1 )
{
if( mat[n-1] == 0 )
{
return 1;
}
else
{
return 0;
}
}
else
{
if( mat[n-1] == 0 )
{
return 1 + count(mat, n-1);
}
else
{
return count(mat, n-1);

}
}
}
int comp(const void* el1,const void* el2)
{
unsigned x,y;
x=count((float*)el1, sizeof((float*)el1) / sizeof(((float*)el1)[0]) );
y=count((float*)el2, sizeof((float*)el2) / sizeof(((float*)el2)[0]) );
if(x==y)return 0;
if(x>y)return -1;
return 1;
}

עריכה: כשאני חושב על זה, אני לא חושב שזה יעבוד, כי גם sizeof(el1) (או el2) יחזיר לך את הגודל שתופס המצביע עצמו ולא כל המערך.

דרך אחת שבה אתה יכול לפתור את הבעיה היא להוסיף בכל שורה של המטריצה איבר (ראשון) המציין את גודל השורה.

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

ארכיון

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

×
  • צור חדש...