תרגול 7.3 - פונקציות המקבלות ומחזירות ערך


תרגול בכתיבת פונקציות המקבלות פרמטרים, ומחזירות ערך

7.3.1 כתיבת הגדרות של פונקציות

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

החישוב הדרוש כותרת הפעולה
א. חישוב ההפרש בין שני גבהים your function declaration here
ב. חישוב מספר הספרות שיש למספר נתון  
ג. בדיקה האם המספר a מתחלק ב-b באופן שלם  
ד. בדיקה האם המספר השלישי הוא ממוצע של שני הראשונים  
ה. מחרוזת המכילה תוכן של קובץ מסוים במחשב  

פתרון
החישוב הדרוש כותרת הפעולה
א. חישוב ההפרש בין שני גבהים static int HeightDifference(int height1, int height2)
ב. חישוב מספר הספרות שיש למספר נתון static int CountDigits(int number)
ג. בדיקה האם המספר a מתחלק ב-b באופן שלם static bool IsDivisible(int a, int b)
ד. בדיקה האם המספר השלישי הוא ממוצע של שני הראשונים static bool IsAverageOf(int first, int second, int third)
ה. מחרוזת המכילה תוכן של קובץ מסוים במחשב static string ReadFileContent(string filePath)

7.3.2 7 BOOM

א. יש לכתבו פעולה static string SevenBoom(int num) המקבלת מספר ומחזירה boom אם המספר מתחלק ב-7 או מופיעה בו הספרה 7 אחרת הפעולת מחזירה את המספר עצמו (כמחרוזת).

ב. יש לכתבו תכנית ראשית המשתמשת בפונקציה כדי לשחק במשחק ‘7 בום’ בתחום המספרים 1 עד (כולל) 99

פלט התכנית:

1 2 3 4 5 6 boom 8 9 10 11 12 13 boom 15 16 boom 18...

7.3.3 עצרת

כתבו פעולה Factorial(int n) המקבלת מספר שלם ומחזירה עצרת שלו

7.3.4 תכונות חלוקה

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

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

using System;
using System.Diagnostics;

class Program
{
    
    // לכאן יש להעתיק את מימוש הפונקציה שכתבתם בסעיף א'
    static bool CheckPair(int number1, int number2)
    {
        // מימוש הפונקציה שלכם...

    }
    static void Main()
    {
        // אוסף הזוגות לבדיקה: (מספר ראשון, מספר שני, התוצאה הצפויה)
        var testPairs = new (int First, int Second, bool Expected)[]
        {
            (3, 5, false),
            (5, 15, true),
            (2, 5, false),
            (3, 6, true),
            (10, 5, true)
        };

        foreach (var (first, second, expected) in testPairs)
        {
            bool actual = CheckPair(first, second);    // קריאה לפונקציה מסעיף א׳
            Debug.Assert(actual == expected,
                $"test failed for ({first}, {second}): expected {expected}, actual {actual}");
            Console.WriteLine($"({first}, {second}) -> expected: {expected}, actual: {actual}");
        }
    }

}

7.3.5 סכום סדרת טבעיים

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

לדוגמה (קלט → פלט):

2 → 3 (1 + 2)
8 → 36 (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8)

7.3.6 מספר מושלם

יש לכתבו פעולה המקבלת מספר שלם, ומחזירה true אם הוא מושלם. אחרת false. את השאלה הבאה יש לפתור באתר codeWars Perfect Number Verifier בקישור זה לאחר שתצרו לעצמכם משתמש

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

7.3.7 מרחק בין עמודים

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

  1. מספר העמודים (≥ 1)
  2. המרחק בין העמודים (10–30 מטר)
  3. רוחב העמוד (10–50 סנטימטר) הפונקציה תחזיר את המרחק בין העמוד הראשון לעמוד האחרון בסנטימטרים, מבלי לכלול את רוחב העמוד הראשון והעמוד האחרון.

7.3.8 מעקב וטענות כניסה ויציאה

נתונה הפעולה הבאה:

1
2
3
4
5
6
7
8
9
static bool Equal1(int n1, int n2)
{
    while (n1!=0 && n2!=0)
    {
        n1 = n1 / 10;
        n2 = n2 / 10;
    }
    return n1==0 && n2==0;
}

א. עירכו טבלת מעקב עבור הערכים 578, 35 וציינו מה הערך אותו תחזיר הפעולה.

ב. תנו דוגמת קלט עבורה תחזיר הפעולה true ודוגמת קלט עבורה תחזיר הפעולה false.

ג. השלימו את טענת הכניסה והיציאה של הפעולה.

```csharp
// טענת כניסה: הפעולה מקבלת שני מספרים חיוביים שלמים
// טענת יציאה: ...
```
פתרון ל-ג': הרחבה על המושגים טענת כניסה ויציאה

בטכניקות של Design by Contract במדעי המחשב מגדירים עבור כל פונקציה שני סוגי דרישות מרכזיות:

טענת כניסה (Precondition)

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

בדוגמה שניתנה:

// טענת כניסה: הפעולה מקבלת שני מספרים חיוביים שלמים

כלומר, הפונקציה מניחה שקיבלה x>0 ו־y>0 ושלמים, ואין צורך לבדוק זאת בפנים כל עוד הקריאה תעמוד בתנאי.

טענת יציאה (Postcondition)

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

בדוגמה הנתונה:

// טענת יציאה: הפעולה מוודאת שמספר הספרות בשני המספרים זהה

כלומר, לאחר סיום הפונקציה, נחזיר true אם ומכיל־כל־ואי את התנאי, ו־false אחרת.

למה זה חשוב?

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

סיכום קצר

Precondition: התנאים שעל הסביבה (הקריאה) למלא לפני קריאה לפונקציה.

Postcondition: התנאים שהפונקציה מבטיחה לצרכן שלה לאחר סיום ההרצה.

בכתיבה מסוג summary אנחנו מכסים בעצם את טענת הכניסה והיציאה:

/// <summary>
/// This function checks if two integers are equal by comparing their digits.
/// </summary>
/// <param name="n1">an integer</param>
/// <param name="n2">an integer</param>
/// <returns>true if both lengths are equal</returns>

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

ד. כתבו פעולה Equal2 השקולה לפעולה Equal1, אך מבצעת את האלגוריתם באופן שונה - הפעולה Equal2 תשתמש בפעולה הנתונה הבאה: CountDigits.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    /// <summary>
    /// טענת כניסה: הפונקציה מקבלת מספר שלם חיובי
    /// ממש לא מקובל לתעד בעברית
    /// </summary>
    /// <param name="num">integer</param>
    /// <returns>טענת יציאה: הפעולה מחזירה את מספר ספרותיו</returns>
    static int CountDigits(int num)
    {
        int counter = 0;
        while (num > 0)
        {
            num = num / 10;
            counter++;
        }
        return counter;
    }
    

7.3.9 משלוח מוניות

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

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

ב. כתבו תכנית ראשית שתדפיס כמה מוניות צריך לשלוח ביום ד’ (עבור 49 נוסעים), כמה ביום ה’ (עבור 52 נוסעים), וכמה ביום ו’ (עבור 60 נוסעים). התכנית הראשית תקרא לפעולה 3 פעמים - קריאה אחת עבור כל יום, וכך תוכל להדפיס את מספר המוניות הדרושות.

7.3.10 ספרות חוזרות במספר

א. כתבו פעולה המקבלת כפרמטר מספר שלם חיובי num וספרה digit. הפעולה תחזיר כמה פעמים הספרה digit מופיעה במספר. דוגמא: עבור המספר 123532 והספרה 3 יוחזר הערך 2, מאחר שהספרה 3 מופיעה פעמיים.

ב. כתבו פעולה ראשית המגרילה 5 זוגות מספרים: - number - מספר בעל 4 ספרות (1000-9999), - digit - מספר בין 1 ל-9, ומדפיסה לכל זוג מספרים את המספרים שהוגרלו (number ו- digit) ואת מספר הפעמים שהספרה digit חוזרת במספר number.

7.3.11

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

ב. כתבו פעולה בשם IsDiffDigits המקבלת מספר חיובי ומחזירה true אם כל ספרותיו שונות זו מזו, אחרת מחזירה false.

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

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

דוגמאות:

  • עבור הקלט: 924,846,866,642,0

    יינתן הפלט: 846.

  • ועבור הקלט: 3000 ,241,483,982,888,198

    יינתן הפלט: 0.

7.3.12 החלפת ספרות

א. כתבו פעולה SwitchDigits המקבלת כפרמטר מספר שלם וחיובי ומחזירה: את המספר במידה וכמות הספרות במספר אי-זוגית את המספר בהיפוך ספרות של כל זוג ספרות סמוך. לדוגמה: אם המספר הוא 1234, הפעולה תחזיר מספר חדש 2143 (כלומר כל זוג ספרות סמוך החליף סדר).

ב. כתבו פעולה ראשית (Main) המגרילה 4 מספרים שלמים בין 1111 לבין 6868 (כולל). הפעולה תדפיס בשורה נפרדת לכל מספר שהוגרל את המספר עצמו ולידו (עם רווח) את המספר בהיפוך ספרות (יש להשתמש בפעולה מסעיף א).

7.3.13 מספר עולה יורד

כתבו פונקציה המקבלת מספר שלם חיובי בן 3 ספרות לפחות מחשבת אם הוא עולה יורד ומחזירה בהתאם true/false מספר הוא עולה יורד, אם הספרות (מימין לשמאל, עולות ממש, בעקביות ומנקודה מסויימת יורדות ממש בעקביות).

לדוגמא:

  • 12320 עולה יורד
  • 43620 אינו עולה יורד
  • 133420 אינו עולה יורד

7.3.14

מועמד לרישום לאוניברסיטה מגיש את ציוני תעודת הבגרות שלו. האוניברסיטה עורכת לציוניו ממוצע משוקלל על פי הקריטריונים הבאים: בכל מקצוע בו נבחן התלמיד בהיקף של 5 יח’ הוא מקבל 20 נק’ תוספת, ובכל מקצוע בו נבחן בהיקף של 4 יח’ הוא מקבל תוספת של 10 נק’.

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

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

קישורים

⬅ השוו פתרונות ל- 7.3 - פונקציות, כולל פתרונות

⬅ עברו לתרגול 7.1 - פונקציות void: פעולות ללא פרמטרים

⬅ עברו לתרגול 7.2 - פונקציות המקבלות פרמטרים

⬅ עברו לתרגול 7.4 - קאטות CodeWars לא מסווגות

⬅ עברו לתרגול 7.3 כולל פתרונות - פונקציות המקבלות פרמטרים

⬅ חזרה לפרק 7 מורחב

⬅ חזרה לפרק 7 המשך

⬅ עברו לפרק 7 מקוצר