המדריך השלם
 

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

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

תבנית של מערך:

type array_name [length];

מערך בגודל n:
תא 0
תא 1
... ...
תא n-1
תא n


הערה:
האינדקס של המערך מתחיל מ 0 עד ל (lenth -1) כך שאם הצהרנו על מערך עם 10 מקומות אז האינדקס של המקום הראשון הוא 0 והאחרון 9.
כל פניה לתא מחוץ לתחום יכולה לגרום לקריסת התוכנית, שגיאה זו אינה מתגלה על ידי המהדר.

דוגמאות:
char arrayc[10]; - מערך של תווים (מחרוזת) בעל 10 מקומות
int arrayi[20]; -מערך של מספרים שלמים בעל 20 מקומות.
float arrayf[30]; - מערך של מספרים ממשיים בעל 30 מקומות.

הערה:
מערך של 10 מקומות מסוג int תופס 20 בתים בזיכרון משום ש- int תופס 2 בתים. מקומו של האיבר השלישי במערך, למשל, הוא בכתובת התחלתית של המערך + 3*2 .
מקום האיבר ה- i בזיכרון הוא: כתובת התחלתית + (גודל הטיפוס בבתים)*i.
כלומר, כאשר מוגדר מערך אין אנו יודעים את כתובתו ההתחלתית אך ידוע לנו כי כל איבריו נמצאים ברצף זה לאחר זה. לדוגמא, אם התא הראשון במערך נמצא בכתובת 2000 וזהו מערך של שלמים (שגודלם 2 בתים) אזי האיבר השני ימצא בכתובת ה 2002 השלישי בכתובת 2004 וכך הלאה עד האיבר האחרון.

דרכים לאתחול מערך
ניתן לאתחל כל תא בנפרד:

int grades[5];
grades[0] = 90;
grades[1] = 80;
...


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

int grades[5] = {90, 80, ..};
גם כאן יש להקפיד לא לרשום מספר איברים החורג מהגודל שהגדרנו.

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

דוגמא 1:

#include <stdio.h>
#define LENG 5

void main()
{
    int grades [LENG];
    int i, passed = 0;
    int sum = 0;
    float avg = 0;

   for (i = 0; i < LENG; i++)
   {
       printf("Enter your grade: \n\r");
       scanf("%d", &grades[i]);
       if (grades[i] > 60)
          passed++;
          sum += grades[i];
    }
    avg = sum/LENG;
    printf("The average is: %f", avg);
    printf("\n\r%d student passed the test",passed);
}


הערה:
ניתן לאתחל את כל ערכי משתני המערך ב- 0 באופן הבא:
type arr [length] = {0}; אך בעבור כל ערך אחר הדבר בלתי אפשרי באופן הנ"ל אלא יש צורך בלולאה שתעבור ותאתחל את כל עברי המערך בערך הדרוש.

מערך מחרוזת

מחרוזת היא מערך של משתנים מסוג char כאשר כל מחרוזת ב- c מסתיימת בקוד '0\' - זהו null terminator המציין כי כאן מסתיימת המחרוזת ולכן המקום שיוקצה למחרוזת בעלת n תווים היא n+1 .

דוגמאות לאתחול מערך ולהצגתו:

דוגמא 2:

#include <stdio.h>

void main()
{
    char name[6];
    name[0] = 'H';
    name[1] = 'e';
    name[2] = 'l';
    name[3] = 'l';
    name[4] = 'o';
    name[5] = '\0';
    puts(name);
    printf ("%s\n\r", name);

    char name1[] = {'W', 'o', 'r', 'l', 'd', '\0'};
    putchar(name1[0]);
    putchar(name1[1]);
    putchar(name1[2]);
    putchar(name1[3]);
    putchar(name1[4]);
    putchar('\n');

    char name2[] ={"Goodbye"};
    puts(name2);
}
העבר את העכבר מעל הדוגמא כדי לראות הסבר מפורט


הערה: 'n\' הינו תו מעבר לשורה חדשה.

puts(string) - זוהי פונקצית פלט של מחרוזת שמקבלת כארגומנט מחרוזת, מדפיסה אותה ועוברת לשורה חדשה. זהה בביצוע לפונקצית הפלט printf כאשר בסיומה אנו מוסיפים \n\r. (הפונקציה מדפיסה תו-תו עד אשר היא פוגשת '\0').

gets(string) - זוהי פונקצית קלט של מחרוזת שמקבלת משתנה מחרוזתי ומעדכנת את ערכו (קולטת עד אשר היא פוגשת '\0').

דוגמא 3:

#include <stdio.h>
#include <conio.h>

void main()
{
    char name[10];
    char l_name[10];
    printf ("Enter your name: ");
    gets (name);
    printf ("Enter your last name: ");
    gets (l_name);
    printf("Your full name is: ");
    puts (name);
    puts (l_name)
}


הערה:
בשימוש ב- gets(string) יש לשים לב לא לקלוט שם החורג מגבולות המערך שכן כבר הזכרנו שהדבר עלול לגרום לשגיאות חמורות. כמו כן לפני שימוש חוזר בפונקציה זו יש לנקות את החוצץ ע"י קריאה לפונקציה flushall() (כאשר יש שאריות בחוצץ).

הערה חשובה:
אין השמה של מחרוזת מכיוון שמחרוזת היא מערך של תווים. יש צורך בהשמה של כל איבר במערך .

הספרייה string.h

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

strlen (string) - פונקציה המחזירה את מספר התווים במחרוזת string (לא כולל התו '\0').

strcpy (string1, string2) - הפונקציה מקבלת 2 מחרוזת ומעתיקה את תוכנה של המחרוזת השנייה לראשונה (כלומר תוכנה של המחרוזתstring1 אחרי פקודה זו יהיה התוכן של string2).

לדוגמא:

char first[ ] = "ab";
char second[ ] = "cd";
strcpy(first, second);

first יכיל את המחרוזת "cd". strcat (string1, string2) - הפונקציה מקבלת 2 מחרוזות ומשרשרת את תוכנה של המחרוזת השנייה לראשונה (תוכנה של המחרוזת string1 אחרי פקודה זו יהיה תוכנה המקורי והמשכה יהיה המחרוזת string2).
לדוגמא :
char first[5] = "ab"
char second[ ] = "cd"
strcat (first, second)

כעת first יכיל "abcd".

- strcmp (string1, string1) הפונקציה מקבלת 2 מחרוזות ומחזירה 0 אם המחרוזות זהות, ערך חיובי אםstring1 > string2 וערך שלילי אם string1 < string2 .
לדוגמא: strcmp("abc", "abc") מחזירה 0.

atoi (string) - הפונקציה מקבלת מחרוזת string ומחזירה את ערכה המספרי.
לדוגמא:
atoi("12") תחזיר את המספר השלם 12. itoa (num, string, baes) - הפונקציה מקבלת מספר, מחרוזת ומספר המייצג בסיס ספירה ומחזירה מחרוזת מספרית שהיא ההצגה בבסיס הספירה של המספר הנתון.
לדוגמא:
itoa (15, str, 2) תחזיר את המחרוזת "111".

הערה:
שתי הפונקציות האחרונות הן מתוך הספרייה stdlib.h.

דוגמא 4:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void main()
{
       char name[20];
       char l_name[10];
       printf ("Enter your name: ");
       gets (name);
       printf ("Enter your last name: ");
       gets (l_name);
       printf("Your full name is: ");
       strcat (name, " ");
       strcat (name, l_name);
       puts(name);
       printf ("The length of your name is: %d\n\r", strlen(name));
       if (!strcmp (name, "will smith"))
          puts("Hi");
       else
          puts("Bye");
}
העבר את העכבר מעל הדוגמא כדי לראות הסבר מפורט


דוגמא 5:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>

void main()
{
    char name[20];
    int leng, i;
    clrscr();
    printf ("Enter your name: ");
    gets (name);
    leng = strlen(name);

    printf ("Your reverse name is:");
    for (i = leng; i >= 0; i--)
    putchar(name[i]);
}
העבר את העכבר מעל הדוגמא כדי לראות הסבר מפורט


ניתן גם להשתמש במערכים דו מימדים - לדוגמא int matrix[5][5] הינו מערך דו מימדי בעל 25 תאים מסוג שלם המכיל 5 שורות ו- 5 עמודות.
כל הכללים למערך חד מימדי תקפים גם בעבור מערך דו מימדי.

דוגמא 6:

#include <stdio.h>

void main()
{
    int matrix[10][10];
    int i,j;

    for (i = 1; i <= 10; i++)
       for (j = 1; j <= 10; j++)
          matrix[i-1][j-1] = i*j;

    for (i = 0; i < 10; i++)
    {
       putchar('\n');
          for (j = 0; j < 10; j++)
             printf ("%2d ", matrix [i][j]);
    }
}
העבר את העכבר מעל הדוגמא כדי לראות הסבר מפורט


דוגמא 7:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void main()
{
    int arr[5][5];
    int temp[5][5];
    int i,j;

    clrscr();
    randomize();

    for (i = 0; i < 5; i++)
       for (j = 0; j < 5; j++)
          arr[i][j] = random(100);//creating a random array

    printf ("Printing the array: \n");
    for (i = 0; i < 5; i++)
    {
       putchar('\n');
       for (j = 0; j < 5; j++)
          printf ("%2d ", arr[i][j]);
    }

    printf ("\n Printing the array backword: \n");
    for (i = 4; i >= 0; i--)
    {
       putchar('\n');
       for (j = 4; j >= 0; j--)
          printf ("%2d ", arr[i][j]);
    }

    printf ("\nChanging the array by using a temporary array:\n");
    for (i = 0; i < 5; i++)
       for (j = 0; j < 5; j++)
          temp[i][j] = arr[i][j];

    for (i = 0; i < 5; i++)
       for (j = 0; j < 5; j++)
          arr[i][j] = temp[4-i][4-j];

    printf ("\nThe new array is: \n");
    for (i = 0; i < 5; i++)
    {
       putchar('\n');
       for (j = 0; j < 5; j++)
          printf ("%2d ", arr[i][j]);
    }
}
העבר את העכבר מעל הדוגמא כדי לראות הסבר מפורט



מבחן
© איתן 2003. כל הזכויות שמורות למערכת המידע איתן.