עבור לתוכן

שאלה, תכנות ב C++

Featured Replies

פורסם

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

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

משום מה, אני מקבל שגיאת הידור בשם unknown size, שאין לי מושג מה המקור שלה...


int biggerInt(void *num1, void *num2)
{
if((int*)num1>(int*)num2)
return 1;
return 0;
}

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

מישהו יכול להסביר לי מה הבעיה של הקוד?

פורסם

בתור התחלה, אתה זכרת להמיר את המצביעים אבל לא עשית derefence:


int biggerInt(void *num1, void *num2)
{
if( (*(int*)num1) > (*(int*)num2) )
return 1;
return 0;
}

/* cleaner, better version, with bugs fixed: */
int biggerInt2(const void *a, const void *b)
{
int ia = *(const int*)a;
int ib = *(const int*)b;

return ia - ib;
}

פורסם
  • מחבר

תודה על הרעיון :hi:

אני לא מאמין שהוא יפתור לי את הבעיה של הקוד, אבל הוא בהחלט יעשה לי חיים קלים יותר ואני מתכוון ליישם אותו.

פורסם

לא עברתי על שאר הקוד אבל אני ממליץ שבכל מקום שצריך להמיר VOID* למצביע אחר, תגדי משתנים ותמיר את המצביע דבר ראשון, ותעבוד רק עם משתנים מהסוג המתאים.

פורסם
  • מחבר

תשתמש בפונקציה MEMCMP.

http://www.cplusplus.com/reference/clibrary/cstring/memcmp.html

תמיין לך את כל סוגי המשתנים.

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

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

פורסם

אתה נותן לה שני מצביעים, והיא מתחילה להשוות בין הערכים שבכתובות.

יש דוגמא בלינק שנתתי לך עם BUILDING וBOOK, נראה לי שהיא מסבירה טוב מאוד.

פורסם
  • מחבר

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

עכשיו נשארה לי רק הבעיה של ה Unknown Size, ואחריה אני כבר יכול להיות רגוע...

מישהו יכול לעזור לי עם זה בבקשה? :'(

פורסם

אם יש לך שגיאת הידור, כדאי לציין איפה היא, בכל מקרה, בפונקציה sort אתה מנסה לעשות pointer +j, כאשר pointer הוא מסוג void *, יכול להיות שזה הבעיה, תמיר אותו למצביע מגודל ידוע (אני מניח שאתה מתכוון פה ל char *).

פורסם
  • מחבר

השגיאה היא בשורה:

if( (*bigger) ((void*)(pointer+j) , (void*)(pointer+j+bytes)) > 1);

היא בעצמה טעות שרק עכשיו שמתי לב אליה, אבל זה כבר משהו אחר...

הבעיה שלי היא שאני לא יכול לקבוע את הסוג של המצביע pointer, כי אני לא יודע על איזה משתנה הוא מצביע, זה הרעיון של התוכנה- אני בונה קוד שיכול למיין את כל סוגי המשתנים, כאשר כל מה שאני צריך לשנות הוא את הmain (להוסיף בו את סוג המשתנה) ולהופיץ את הפונקציה biggerX, כאשר X הוא סוג המשתנה.

פורסם

שים לב שהפונקציה sort מקבלת *const void, אבל ממירה אותו ל-*void. יכול להיות שזה מה שגורם לבעיה שלך.

במקום זה, או שתשתמש רק ב-*void או שתשתמש רק ב-*const void.

אגב, עוד הערה - הביטוי הזה:

a>b?1:0

הוא מיותר, ושקול לחלוטין לביטוי

a>b

פורסם
  • מחבר

תודה על ההערה לגבי a>b?1:0, אני אשנה את זה.

אני לא חושב שהבעיה היא void* לעומת const void*, הבעיה היתה קיימת עוד לפני כן...

פורסם

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

בנימין, אם ה size הוא הגודל של המשתנה בבייטים, אז כמו שאמרתי, תעשה cast ל unsigned char * ל pointer ואז תעשה את שאר הפעולות.

פורסם

ודאי שיש, *void הוא בגודל byte.

(מצד שני, יש מצב שאני טועה)

פורסם

אולי בקומפיילר כזה או אחר אבל לא נראה לי בתקן של השפה:

http://en.wikipedia.org/wiki/Pointer

Pointer arithmetic, that is, the ability to modify a pointer's target address with arithmetic operations (as well as magnitude comparisons), is restricted by the language standard to remain within the bounds of a single array object (or just after it), though many non-segmented architectures will allow for more lenient arithmetic. Adding or subtracting from a pointer moves it by a multiple of the size of the datatype it points to. For example, adding 1 to a pointer to 4-byte integer values will increment the pointer by 4. This has the effect of incrementing the pointer to point at the next element in a contiguous array of integers -- which is often the intended result. Pointer arithmetic cannot be performed on void pointers because the void type has no size, and thus the pointed address can not be added to, although gcc and other compilers will perform byte arithmetic on void* as a non-standard extension. For working 'directly' with bytes they usually cast pointers to BYTE*, or unsigned char* if BYTE isn't defined in the standard library used.

ארכיון

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

דיונים חדשים