Menu
Coddy logo textTech

איטרטורים

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

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

כל מכולה של STL מספקת את המתודות begin() ו-end(). האיטרטור begin() מצביע על האיבר הראשון, ואילו end() מצביע על מיקום אחד אחרי האיבר האחרון — זקיף שמסמן היכן לעצור:

#include <vector>
#include <iostream>

int main() {
    std::vector<int> nums = {10, 20, 30};
    
    for (std::vector<int>::iterator it = nums.begin(); it != nums.end(); ++it) {
        std::cout << *it << " ";  // בצע דה־רפרנס כדי לקבל את הערך
    }
    // פלט: 10 20 30
}

מילת המפתח auto מפשטת באופן משמעותי הצהרות של איטרטורים:

for (auto it = nums.begin(); it != nums.end(); ++it) {
    *it *= 2;  // שנה את האיברים באמצעות האיטרטור
}
// nums מכיל כעת {20, 40, 60}

איטרטורים נחלקים לקטגוריות שונות לפי היכולות שלהם. איטרטורים לגישה אקראית (כמו אלה של vector) תומכים בפעולות חשבון כגון it + 3 או it1 - it2.

איטרטורים דו־כיווניים (של list, map) יכולים לנוע קדימה ואחורה באמצעות ++ ו־--. איטרטורים קדימה יכולים לנוע בכיוון אחד בלבד.

למעבר בסדר הפוך, השתמשו ב־rbegin() וב־rend():

for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
    std::cout << *rit << " ";  // מדפיס בסדר הפוך
}
challenge icon

אתגר

קל

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

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

  • Inventory.h: הגדירו מחלקה בשם Inventory שמנהלת אוסף של כמויות פריטים המאוחסנות ב-std::vector<int>.

    על המחלקה לספק את המתודות הבאות:

    • addItem(int quantity): מוסיפה למלאי כמות של פריט
    • printForward(): משתמשת באיטרטורים עם begin() ו-end() כדי להדפיס את כל הכמויות כשהן מופרדות ברווחים, ואחריהן תו שורה חדשה
    • printReverse(): משתמשת באיטרטורים הפוכים עם rbegin() ו-rend() כדי להדפיס את כל הכמויות בסדר הפוך, כשהן מופרדות ברווחים, ואחריהן תו שורה חדשה
    • doubleAll(): משתמשת באיטרטורים כדי לעבור על המערך ולהכפיל כל כמות במקומה
    • getTotal(): משתמשת באיטרטורים כדי לחשב ולהחזיר את סכום כל הכמויות

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

  • main.cpp: קראו ארבעה ערכי קלט של מספרים שלמים (כל אחד בשורה נפרדת) שמייצגים כמויות של פריטים.

    צרו אובייקט Inventory והוסיפו אליו את כל ארבע הכמויות. לאחר מכן הדגימו שימוש באיטרטורים באמצעות:

    1. הדפסת Forward: ולאחריה קריאה ל-printForward()
    2. הדפסת Reverse: ולאחריה קריאה ל-printReverse()
    3. הדפסת Total: <sum> באמצעות getTotal()
    4. קריאה ל-doubleAll() כדי לשנות את הכמויות
    5. הדפסת After doubling: ולאחריה קריאה ל-printForward()
    6. הדפסת New total: <sum> באמצעות getTotal()

לדוגמה, עבור הקלטים 10, 25, 15 ו-30:

Forward: 10 25 15 30 
Reverse: 30 15 25 10 
Total: 80
After doubling: 20 50 30 60 
New total: 160

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

נסו בעצמכם

#include <iostream>
#include "Inventory.h"

using namespace std;

int main() {
    // קראו ארבעה מספרים שלמים מהקלט
    int q1, q2, q3, q4;
    cin >> q1;
    cin >> q2;
    cin >> q3;
    cin >> q4;

    // TODO: צרו אובייקט מסוג Inventory

    // TODO: הוסיפו את כל ארבע הכמויות למלאי

    // TODO: הדפיסו "Forward: " ואז קראו ל־printForward()

    // TODO: הדפיסו "Reverse: " ואז קראו ל־printReverse()

    // TODO: הדפיסו "Total: " ואחריו את התוצאה של getTotal()

    // TODO: קראו ל־doubleAll() כדי לשנות את הכמויות

    // TODO: הדפיסו "After doubling: " ואז קראו ל־printForward()

    // TODO: הדפיסו "New total: " ואחריו את התוצאה של getTotal()

    return 0;
}
quiz iconבחנו את עצמכם

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

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

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