Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Studies

מערכים סטאטיים

מערך סטאטי הוא מערך בו מספר האיברים ידוע לפני ריצת התוכנית - בזמן קומפילציה. הסינטקס להגדרת מערך של N איברים מטיפוס type בשם array היא:

type array[N];

כאשר N הוא קבוע כלשהו הידוע בזמן קומפילציה.

לדוגמא, נגדיר מערך של 100 איברי int בשם grades עבור הציונים של 100 סטודנטים:

int grades[100];

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

int grades[100];
grades[64] = 75;

ננתח:

  1. המשתנה grades הוא מערך באורך 100 של משתני int. בהמשך ננתח בפירוט את הטיפוס שלו.
  2. המשתנה grades[64] לעומתו הוא משתנה int רגיל לחלוטין.
  3. המספר 64 בהקשר זה נקרא האינדקס של האיבר.
  4. האיבר הראשון במערך הוא grade[0] ולא grades[1] כפי שאולי ניתן לצפות. האיבר האחרון במערך הוא grades[99], או grades[N - 1] עבור N גודל המערך.

גבולות מערכים

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

#define N 30
int main() {
    int array[N];
    array[-1] = 0;
    array[N + 1] = -3;
}

תוכנית זו אינה חוקית וככל הנראה תקרוס בזמן ריצתה. גישה לאיבר מחוץ לגבולות מערך הוא נקרא out of bounds error, והוא מקור נפוץ לבאגים, ורצוי להמנע ממנו.

אתחול מערכים

ניתן לתת ערכים התחלתיים למערך סטאטי ע״י שימוש בסינטקס הבא:

#include <stdio.h>
int main(void) {
    // With length
    int numbers1[4] = {1, -3, 10, 5};

    // Inferred length
    int numbers2[] = {1, -3, 10, 5};

    // Given and inferred length mismatch
    int numbers3[2] = {1, -3, 10, 5};

    int numbers4[6] = {1, -3, 10, 5};

    // Initializer all elements
    int numbers5[4] = {0};
}

לרשימת האיברים שבתוך הסוגריים המסולסלים המופרדים בפסיקים נקרא רשימת אתחול, או initializer list. נבחין בין 4 אופציות:

  1. עבור numbers1 הגדרנו גם אורך וגם ערך התחלתי לכל הערכים.
  2. עבור numbers2 נתתו לקומפיילר להסיק מהו האורך של המערך ע״י קריאת רשימת האתחול.
  3. עבור numbers3 אורך המערך שנתנו קצר מאורך רשימת התאחול. במקרה זה רשימת האתחול ילקחו שני האיברים הראשונים מרשימת האתחול והשאר לא יכנסו למערך, שאורכו קבוע.
  4. עבור numbers4 אורך רשימת האתחול קצר מאורך המערך. במקרה זה רשימת האתחול כולה תאכלס את תחילת המערך, ושאר האיברים יאותחלו ל-0.
  5. עבור numbers5 כל האיברים מאותחלים לאיבר 0.

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

דוגמא

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

#include <stdio.h>
#define N 100
#define NO_GRADE -1
int main() {
    int grades[N] = {NO_GRADE};
    while (1) {
        int id;
        int grade;
        scanf("%d %d", &id, &grade);
        if (id < 0) {
            break;
        }
        grades[id] = grade;
    }
    int grades_sum = 0;
    int nstudents = 0;
    for (int id = 0; id < N; id++) {
        int grade = grades[id];
        if (grade == NO_GRADE) {
            printf("%d\n", id);
        } else {
            grades_sum += grade;
            nstudents++;
        }
    }
    printf("Average: %d\n", grades_sum / nstudents);
}