שאלה ב adt שפת c

ronib25

New member
שאלה ב adt שפת c

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















 

BravoMan

Active member
שמע, אם בכל תרגיל שנותנים לך אתה מתחיל מזה

שאתה לא מבין לחלוטין את התרגיל, זה הזמן לקחת מורה פרטי.
אני חושב שהשאלה שלך קצת ארוכה, וקצת מורכבת להסבר ע"ג הפורום הזה.
&nbsp
נסביר בקצרה:
"נוטציה פולנית" היא צורה לרשום נוסחה מתמטית שנראית מוזרה ומסובכת, אבל בפועל ממש ממש פשוטה לחישוב ע"י תוכנת מחשב.
&nbsp
ניקח את הדוגמה הבסיסית:
כשאתה כאדם קורא 2 + 1 ברור לך שצריך לקחת 1, ולחבר לו 2.
כשתוכנת מחשב קוראת זאת, היא צריכה לקחת 1, לאחסן אותו איפשהו, לקחת +, ולזכור שזה האופרטור, ואז לקחת 2, להיזכר מה היה המספר הראשון, ללכת לשלוף את האופרטור הרלוונטי.
&nbsp
בקיצור - בלגן!
&nbsp
אז אמרו לך: בוא נעשה משהו פשוט. פולני, אבל פשוט (עיין ערך "בדיחות על פולנים"):
נרשום את הנוסחה ככה:
+ 2 1
עכשיו למחשב יהיה קל לעבוד.
למה?
כי יש פה לוגיקה מאוד פשוטה: כל עוד אתה קורא מספר, דחוף אותו למחסנית.
ברגע שנתקלת באופרטור, שלוף שני מספרים, בצע עליהם את הפעולה, ואז דחוף את התוצאה חזרה.
&nbsp
וזה הכל.
נכון שזה נראה פשוט?
&nbsp
בתרגיל, חסכו לך לממש לבד מחסנית, ונתנו לך מחסנית מוכנה.
כעת, עליך להשתמש בה ובכלים אחרים שאתה מכיר, כדי לממש את שתי הפונקציות שביקשו ממך.
&nbsp
בהצלחה!
 

ronib25

New member
שאלה טכנית

ראשית, מה לעשות שפעם ראשונה שאני פוגש ״נוטציה פולנית״, עברתי בכמה מוסדות כמו הטכניון ועוד 2 ובחיים לא נתקלתי בשם הזה...שנית אני חושב שהעניין של להבין את העניין המתמטתי כאן הוא האתגר של התרגיל, כל השאר ממש 90% מוכן, אם הבנתי נכון אני מחוייב להשתמש בפונ׳ שכבר נתונות לי ובאמת כל שיש לי זה לאחסן מספרים במחסנית ולהוציא כפי שציינת...
ולשאלה, בגלל הסוגריים שנוספות כל פעם, את הפעולות של הכפל אני מבצע אחרון, נכון ?
 

BravoMan

Active member
זו בדיוק הנקודה:

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

ronib25

New member
שאלה

אני לא כל כך בטוח שהבנתי את הפונ׳ CreateStack, היא לא מקבלת כלום ומחזיר מבנה ??
כלומר עליי להשתמש בה באופן חד פעמי כדי ליצור מבנה שבו אני אכניס את כל המחסנית ?
משמע אני צריך פשוט לקחת איזה משתנה שהוא מצביע למבנה (נניח *p) ולעשות p=CreateStack ??
&nbsp
 

BravoMan

Active member
ככה משתמשים ב-API חיצוני

מבחינתך, "המחסנית" היא מבנה אטום - קופסה שחורה שאתה רק משתמש בה בלי להבין מה הולך בפנים.

בפועל, יש לך את הקוד, ואתה יכול לראות שהיא ממומשת, כפי שנהוג לממש מחסנית ע"י רשימה מקושרת.
רשימה כזו, החל מהאיבר הראשון, מקצים בצורה דינמית.
שים לב גם, שהטיפוס Stack כבר מוגדר לך כמצביע, אז כשאתה יוצר משתנה מהסוג שלו, אתה לא צריך לכתוב עוד כוכבית.
אתה פשוט עושה ככה:
Stack s = CreateStack();

וזה שקול להגדרת מצביע לראש רשימה, קריאה ל-malloc, ומילוי ראשוני של שדות של ראש הרשימה.

אבל זה לא מעניין אותך!
כל שעליך לדעת הוא שלפני תחילת שימוש במחסנית אתה מקצה משתנה מסוג Stack ושם בו ערך חוזר מ-CreateStack.
אתה מעביר ערך זה לשאר הפונקציות שמטפלות במחסנית, ולבסוף כשסיימת אתה מעביר אותו ל-DeleteStack לצורך ניקיון.
 

ronib25

New member
לא הבנתי אותך כל כך

הקלדתי בפונ׳ ToPlish את מה שרשמת Stack s = CreateStack(); , אבל אם אני מבין נכון טכנית זה בלתי אפשרי כי מה ש CreateStack מחזיר זה void ואני נותן למשתנה מסוג stack להיות שווה ל void לכן זה בלתי אפשרי...(יש מצב שלא הבנתי את ההודעה הקודמת שלך פשוט), אבל אם כן הבנתי אז בשביל להשתמש במחסנית אני חייב לאתחל אותה וזו הדרך כביכול לאתחל אותה...
 

BravoMan

Active member
איפה ראית ש-CreateStack מחזירה void???

בתמונה שצירפת של הקובץ ADT.h כתוב במפורש ש-CreateStack מחזירה Stack שזה למעשה מצביע ל-struct Stack_ zz (שים לב לקו תחתון בסוף השם!)
&nbsp
היא מחזירה מצביע למבנה שהיא מקצה דינמצית, זה הכל.
 

ronib25

New member
סליחה, בדיוק רשמתי תיקון והגבת

אני מצרף תמונת מסך שאומרת שיש שגיאה...
גם בשגיאה עצמה יש ״קשקושיאדה״, שאני לא מבין מה לא בסדר כי בסה״כ רשמתי שורה וכבר יש 2 שגיאות...
כמו כן האם נהוג בשאלות מהסוג של התרגיל ליצור סוג של תפריט בעזרת switch ופשוט לנתח במקרה שלי 3 מקרים של חיבור חיסור וכפל ??

 

BravoMan

Active member
זה מה שקורה כשמלמדים אנשים עם הכלים של MS...

מוזר לי שלא טרחו ליצור את הקובץ ADT.cpp בתור ADT.c זה היה כנראה פותר את הבעיה.
ה-"קשקוש" שאתה רואה בהודעת השגיאה הוא הקומפיילר משנה את שם בפונקציה כדי לכלול בו את טיפוס הערך החוזר, וטיפוסי פרמטרים (שאין), ובכך ליצור שם ייחודי.
&nbsp
זה משהו שקורה ב-++C אבל לא ב-C. לא ניכנס לזה כרגע.
&nbsp
מה שמוזר כאן, זה שהסטודיו לא מוצא את המימוש של הפונקציה CreateStack למרות שאני רואה בצד ימין שהקובץ הרלוונטי נכלל בפרויקט.
&nbsp
כאן לא אוכל לעזור לך כי מזמן לא עבדתי עם סביבת הזבל הזו...
&nbsp
בעצם, שאלה קטנה: איפה מוגדר Data_Type?
אני לא רואה הגדרה שלו בשום מקום, ואם היא לא קיימת, ADT.cpp לא אמור להתקמפל בכלל.
&nbsp
לשאלתך השנייה:
כן - משפט switch הוא שיטה די נוחה לברור אופרטורים ולפעול בהתאם.
 

ronib25

New member
בוא נלך בבקשה שלב שלב...

אם אני אשנה את הסיומות של cpp ל c יש סיכוי שהתקלה הזו תיפתר ?(כלומר זה לא יידרוש ממני לשנות עוד דברים ?? תראה לא למדתי בחיים ++c לכן כנראה שהמרצאה טיפש ועושה העתק הדבר מקורסים יותר מתקדמים...
שנית, לא הבנתי אותך כאן -- > בעצם, שאלה קטנה: איפה מוגדר Data_Type?
אני לא רואה הגדרה שלו בשום מקום, ואם היא לא קיימת, ADT.cpp לא אמור להתקמפל בכלל.?? אתה רואה משהו לא בסדר בשלד של מה שקיבלתי ?? תודה רבה על העזרה שלך, אני לא רואה את זה כמובן מאליו... :)
עריכה: כאשר שיניתי את כל הסיומות התקלה הזו אכן נפתרה, השאלה היא האם בהמשך זה לא יחזור אליי, ואז זה יהיה יותר כואב.. :/
 

BravoMan

Active member
באמת שאין לי מושג מה המרצה שלך עושה.

יש לך תרגיל ב-C.
כל קבצי הקוד אמורים להיות בלעי סיומת C, אחרת Visual Studio יחשוב שזו ++C, שפה דומה אבל נפרדת לגמרי, ויתרגם את הקוד בצורה שונה במקרים רבים.
&nbsp
אם המרצה מעולם לא הסביר לכם את זה, זו תקלה רצינית מאוד!
&nbsp
עכשיו, תסתכל על פונקציה PopStack למשל: היא מחזירה טיפוס שנקרא "Data_Type".
זה לא טיפוס נתונים סטנדרטי ב-C וגם לא ב-++C, לכן צריכה להיות הגדרה שלו אפשהו, כמו שיש הגדרה של Stack.
&nbsp
זה לא מופיע בצילומי מסך שצירפת, אז אני לא יודע למה דברים עובדים לך...
היית אמור לקבל שגיאות על זה.
&nbsp
דרך אגב, אל תצרף קוד בצורת צילום מסך!
זה ממש לא נוח.
תשתמש באתר כמו pastebin.com או צרף קבצי טקסט פשוטים.
&nbsp
&nbsp
 

ronib25

New member
אני חושב שמצאתי את ה data_type

אם תסתכל בצילום מסך של ADT.h יש שם ישר אחרי ה includes
define# Data_Type int כלומר ה Data_Type הוא בסה״כ int מסכן
 

BravoMan

Active member
בגלל זה אמרתי לך לא לצרף צילומי מסך!

בתמונה בהודעה המקורית גללת את החלון כך שלא רואים את החלק של ה-include וגם לא את ה-define, אבל לא שמתי לב לזה קודם.
&nbsp
כמובן, שאם זה שם, לא צריכה להיות שום בעיה, והכל אמור לעבוד לך תקין.
&nbsp
בהצלחה עם שאר התרגיל!
 

BravoMan

Active member
עדיף עם C

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

EyesToSee

New member
RPN , תוספת אינפורמציה

https://en.wikipedia.org/wiki/Reverse_Polish_notation

https://rosettacode.org/wiki/Parsing/RPN_calculator_algorithm

סתם כדי להשוויץ, מימוש מחשבון אשר עובד ב בשיטת RPN , בשפת HASKELL

קוד:
calcRPN :: String -> [Double]
calcRPN = foldl interprete [] . words
 
interprete s x
  | x `elem` ["+","-","*","/","^"] = operate x s
  | otherwise = read x:s
  where
    operate op (x:y:s) = case op of
      "+" -> x + y:s
      "-" -> y - x:s
      "*" -> x * y:s
      "/" -> y / x:s
      "^" -> y ** x:s
From link #2
 
למעלה