עזרה בהבנת קוד

brokenn

New member
עזרה בהבנת קוד

אני אשמח מאוד אם תעזרו לי להבין את הקוד הבא,מה הוא עושה..
תודה מראש.(הפלט של הקוד: what(6795234)return: 71114)


#include <stdio.h>
#include <conio.h>
unsigned what(unsigned k);

void main(){
unsigned t=6795234;
printf("what(%u) return %u\n", t, what(t));
_getch();
}

unsigned what(unsigned k){
if (!k) return 0;
switch (k%10%3){
case 0: return 10*what(k/10)+k%10%3+1;
case 1: return 10 * what(k/100) + k%10;
case 2: return what(k+1);
}
}

ץ
 

Netanel w

New member
מנסה לעזור -

דבר ראשון - הswitch נעשה על ספרת האחדות מודולו3, כלומר - השארית של חלוקת ספרת האחדות ב3.

ישנן 3 אופציות לשארית הזו - 0, 1 ו2. נסמן את השארית הזאת בX לצורך התשובה.
אם X = 0 (כלומר ספרת האחדות היא 0/3/6/9) קוראים לפונקציה רקורסיבית ללא ספרת האחדות, ומוסיפים 1, כלומר כאשר X=0 בפלט מופיעה הספרה "1".
אם X = 1 (כלומר ספרת האחדות היא 1/4/7) קוראים לפונקציה רקורסיבית ללא ספרת האחדות והעשרות, ומוסיפים את ספרת האחדות, כלומר כאשר X=1 בפלט מופיעה ספרת האחדות.
אם X = 2 (כלומר ספרת האחדות היא 2/5/8) קוראים לפונקציה עם המספר המקורי+1, מה שהופך את X ל 0 ומגדיל את K ב1.

מכאן אפשר להתחיל לחבר את התוצאה:
א. בגלל תנאי X=1, כל ספרה d במספר עבורה d mod3 = 1 מוחקים את הספרה משמאל.
ב. לאחר מכן - כל ספרה d במספר שהתקבל עבורה d mod3 = 0 או d mod3 = 2 הספרה מוחלפת ב1, ועבור d mod3 = 1 הספרה נשארת כמו שהיא.
(זה קורה בסדר הזה כי הרקורסיביות גורמת לפונקציה כביכול לעבור על ספרות המספר מימין לשמאל).
מתנאי ב' ניתן לראות כי הספרות היחידות האפשריות בפלט הן 1, 4, 7.

לכן עבור 2345598 קודם כל מתבצע שלב א:
2345598 --> 245598
ולאחר מכן שלב ב':
245598 --> 141111

או לדוג': 98764023 --> 974023 --> 174111.
או: 3102005467 --> 1020047 --> 1111147

ולכן עבור המספר שנתת: 6795234 --> 79524 --> 71114
 

Netanel w

New member
וכמה הערות

הטיפוסים לכל אורך הקוד - unsigned. לצורך הבהירות (ואחרים כבר יעירו לגבי הסטנדרט) יש להגדיר unsigned int.

conio.h --> קיים בבורלנד, לא קיים ברוב הקומפיילרים (דוגמת gcc), ובמילא אין בו שימוש מהותי בקוד ולכן מיותר לחלוטין להשתמש בספרייה זו.
ניתן להחליף את _getch בgetchar() שנמצאת בstdio.h, למרות שגם זה מיותר.

לגבי הmain - יש להגדיר אותו כמחזיר int באופן הבא:

int main(int argc, char *argv[])
OR
int main(void)

ולהחזיר ערך כלשהו בסוף הmain (אפס ע"מ לסמן הצלחה).
 

פרסאוס

New member
conio תופס גם בvisual C

לגבי GNU עד כמה שאני זוכר, באמת לא קיים בהפצה סטנדרטית
(אולי מישהו הרחיב).
getch עוד בא מימי ה DOS העליזים...
getchar עובד גם שם, אבל יש הבדל מהותי בינהם (בדוס...)
 

Netanel w

New member
אכן,

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

נראה שהרבה מהבעיות האלה נובעות מספרים לא מעודכנים של C, בדר"כ בעברית, שעדיין מכניסים conio.h לכל מקום, מגדירים void main וכו'...
 
למעלה