Menu
Coddy logo textTech

קישור מובנה

חלק מהיחידה תכנות מונחה עצמים במסלול ה-C++ של Coddy. שיעור 88 מתוך 104.

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

התחביר משתמש ב־auto עם סוגריים מרובעים המכילים את שמות המשתנים החדשים:

#include <iostream>
#include <map>
#include <tuple>

int main() {
    // פירוק זוג
    std::pair<std::string, int> person{"Alice", 25};
    auto [name, age] = person;
    std::cout << name << " is " << age << "\n";
    
    // פירוק tuple
    std::tuple<int, double, char> data{42, 3.14, 'X'};
    auto [num, pi, letter] = data;
    
    // פירוק בלולאות for מבוססות טווח
    std::map<std::string, int> scores{{"Bob", 90}, {"Carol", 85}};
    for (const auto& [student, score] : scores) {
        std::cout << student << ": " << score << "\n";
    }
}

קישורים מובְנים עובדים גם עם מערכים ועם מבנים מותאמים אישית שיש להם איברים ציבוריים:

struct Point {
    double x;
    double y;
};

Point getOrigin() { return {0.0, 0.0}; }

int main() {
    auto [x, y] = getOrigin();
    
    int arr[3] = {1, 2, 3};
    auto [a, b, c] = arr;
}

אפשר להשתמש ב-auto& או ב-const auto& כדי לקשור באמצעות הפניה, וכך להימנע מהעתקות ולאפשר לשנות את הערכים המקוריים כשצריך. התכונה הזו שימושית במיוחד בעת איטרציה על מכלים של STL או טיפול בפונקציות שמחזירות כמה ערכים.

challenge icon

אתגר

קל

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

תארגנו את הקוד שלכם בשלושה קבצים:

  • Student.h: הגדירו מבנה Student עם איברים ציבוריים עבור שם התלמיד (std::string), מספר מזהה (int) וממוצע ציונים (double). צרו גם פונקציה בשם createStudent שמקבלת שם, מספר מזהה וממוצע ציונים, ומחזירה מבנה Student.
  • GradeUtils.h: צרו פונקציות שירות לעיבוד ציונים.

    הגדירו פונקציה getGradeInfo שמקבלת ציון מספרי (מספר שלם) ומחזירה std::tuple שמכיל שלושה ערכים: ציון באות (std::string), נקודות הציון (double) והאם הציון עובר (bool). השתמשו בסולם הציונים הבא:

    • 90 ומעלה: "A", 4.0, true
    • 80-89: "B", 3.0, true
    • 70-79: "C", 2.0, true
    • 60-69: "D", 1.0, true
    • מתחת ל-60: "F", 0.0, false

    הגדירו גם פונקציה makeScorePair שמקבלת שם קורס (std::string) וציון (int), ומחזירה std::pair של הערכים האלה.

  • main.cpp: קראו ארבעה קלטים:
    1. שם התלמיד (מחרוזת)
    2. מספר מזהה של התלמיד (מספר שלם)
    3. שם הקורס (מחרוזת)
    4. ציון (מספר שלם)

    השתמשו בקישור מובנה לאורך הפונקציה הראשית שלכם:

    1. קראו ל-createStudent עם השם, מספר המזהה וערך ממוצע ציונים זמני של 0.0. השתמשו בקישור מובנה כדי לפרק את המבנה שהוחזר למשתנים נפרדים, ואז הדפיסו: Student: [name] (ID: [id])
    2. קראו ל-makeScorePair עם שם הקורס והציון. השתמשו בקישור מובנה כדי לפרק את הזוג, ואז הדפיסו: Course: [course], Score: [score]
    3. קראו ל-getGradeInfo עם הציון. השתמשו בקישור מובנה כדי לפרק את שלושת איברי ה-tuple, ואז הדפיסו:
      Grade: [letter]
      Points: [points]
      Passing: [yes/no]
      (הדפיסו "yes" אם הציון עובר הוא true, ו-"no" אם הוא false)

לדוגמה, עבור הקלטים Alice, 1001, Math ו-85:

Student: Alice (ID: 1001)
Course: Math, Score: 85
Grade: B
Points: 3
Passing: yes

עבור הקלטים Bob, 2002, Physics ו-55:

Student: Bob (ID: 2002)
Course: Physics, Score: 55
Grade: F
Points: 0
Passing: no

זכרו לכלול את <tuple> ואת <utility> במקומות הנדרשים. התובנה המרכזית היא שקישור מובנה מאפשר לפרק טיפוסים מורכבים, זוגות, tuples ומבנים למשתנים בעלי שמות בהצהרה יחידה וקריאה.

נסו בעצמכם

#include <iostream>
#include <string>
#include "Student.h"
#include "GradeUtils.h"

int main() {
    // קראו את הקלטים
    std::string studentName;
    int studentId;
    std::string courseName;
    int score;
    
    std::cin >> studentName;
    std::cin >> studentId;
    std::cin >> courseName;
    std::cin >> score;
    
    // TODO: קראו ל־createStudent עם השם, המזהה ו־GPA זמני של 0.0
    // השתמשו בקשירות מובנות כדי לפרק את ה־struct: auto [name, id, gpa] = ...
    // הדפיסו: Student: [name] (ID: [id])
    
    
    // TODO: קראו ל־makeScorePair עם שם הקורס והציון
    // השתמשו בקשירות מובנות כדי לפרק את הזוג: auto [course, sc] = ...
    // הדפיסו: Course: [course], Score: [score]
    
    
    // TODO: קראו ל־getGradeInfo עם הציון
    // השתמשו בקשירות מובנות כדי לפרק את ה־tuple: auto [letter, points, passing] = ...
    // הדפיסו:
    // Grade: [letter]
    // Points: [points]
    // עובר: [yes/no] (הדפס "yes" אם passing הוא true, ו-"no" אם הוא false)
    
    
    return 0;
}
quiz iconבחנו את עצמכם

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

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר C++ אונליין