Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Studies

שפת C

בקורס זה נלמד את שפת C, אחת משפות התכנות המוכרות והנפוצות בעולם. השפה יצאה לאור ב-1972 ומאז נמצאת בשימוש נרחב בעולם התכנות ומתאפיינת בפשטות וגמישות, תוך כדי שליטה מדויקת מאוד על המכונה עליה היא רצה. תוכנות מהחשובות בהיסטוריה נכתבו בשפת C - מערכות ההפעלה Windows, Linux ו-MacOS/iOS הן הידועות מביניהן.

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

Note

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

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

Hello World

אחד הדברים הבסיסיים ביותר שתוכנית מחשב יוכלה לעשות היא לכתוב על המסך הודעה שהמשתמש יכול לקרוא. כשלומדים שפת תכנות לראשונה, נהוג להציג תוכנית שמדפיסה על המסך את התווים “!Hello world” – בשפת C, זה יראה כך:

#include <stdio.h>
int main() {
    printf("Hello world!\n");
}

פירוק לרכיבים

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

printf("Hello world!\n");
  1. printf – זוהי דוגמא לפונקציה (function), אובייקט שנעבוד איתו המון בקורס ונגדיר בהמשך בצורה מסודרת. בקצרה עכשיו – פונקציה היא קטע קוד שאפשר “לקרוא” לו מכל מיני מקומות ובכך להפעיל אותו. לפונקציות קוד, כמו פונקציות מתמטיות, יש ארגומנטים שהן מקבלות וערך שהן מחזירות. בדוגמא הזו, הארגומנט הוא "Hello world", ואנו לא משתמשים בערך שהיא מחזירה. הפונקציה printf (קיצור של print formatted) מדפיסה למסך את הארגומנטים שהיא מקבלת. נשים לב שהדרך לקרוא לפונקציה היא עם סוגריים () וביניהם הארגומנטים שלה, בדוגמא לכך שבמתמטיקה כותבים \(sin(x)\) עבור קריאה לפונקציה \(sin\) עם הארגומנט \(x\). בהמשך נפרט בהרחבה על איך משתמשים בפונקציות ואיך לכתוב פונקציות בעצמנו.
  2. "Hello world!\n" – זוהי דוגמא למחרוזת (string) - אוסף של תווים, שגם עליהם נרחיב מאוד בהמשך הקורס. ב-C מחרוזות מוקפות בגרשיים כפולים " " , והרבה פעמים משמשות ליצוג מייצגות טקסט כלשהו. במקרה זה הטקסט שרצינו להדפיס הוא “Hello world”, בעוד שהתו n\ הוא סימן מוסכם ל-“שורה חדשה” – כלומר, הפונקציה printf תדפיס "Hello world", תגיע לתו n\ ואז תדפיס שורה חדשה. נשים לב שבמקרה זה נתנו לפונקציה ארגומנט אחד והוא "Hello world!\n" – בהמשך נראה שניתן לתת לפונקציות מספר גדול כרצוננו של ארגומנטים.
  3. ; – בסוף השורה נכתב התו ';'. התו הזה מסמן סוף של “משפט” בקטע הקוד שכתבנו. בהמשך נרחיב על משפטי קוד, אבל כרגע ניתן להתייחס ל-; כמו נקודה בין משפטים שונים.

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

  1. <include <stdio.h# - ב-C שורת קוד המתחילה ב-# נקראת מאקרו (macro). בקרוב נפגוש תוכנית חשובה הנקראת קומפיילר (compiler) - זוהי תוכנית שתפקידה לקחת את הקוד שכתבנו ולתרגם אותו לשפת מכונה. שורת מאקרו אינה מייצגת קוד בפני עצמה, אלא הוראה לקומפיילר לבצע פעולה כלשהי. במקרה זה, פקודת ה-include# מורה לקומפיילר להדביק את הקובץ stdio.h בקובץ שלנו - הסיבה שאנו זקוקים לכך היא על מנת לקבל גישה לפונקציה printf, הנמצאת בקובץ הזה.
  2. ()int main – זו עוד פונקציה. כשהקומפיילר קורא את הקוד שלנו, הוא מחפש פונקציה בשם main ושם קובע את נקודת ההתחלה של התוכנית.
  3. {} – התווים ‘{’ ו-‘}’ משמשים בשפת C לאגד ביחד מספר משפטים ליצירת בלוק קוד. במקרה זה התווים האלה משומשים על מנת לאגד ביחד את “הגוף” של פונקציית ה-main בתוכנית.
  4. נשים לב שלאחר ה-{ הראשון, השורה הרביעית מתחילה ב-4 רווחים. זוהי קונבנציה הנקראת הזחה או אינדנטציה (indentation) - כל ״בלוק״ קוד חדש מתחיל במספר רווחים על מנת להפריד אותו ויזואלית מאחרים. בשפת C הקומפיילר מתעלם לחלוטין מהזחות ולכן מדובר בקונבנציה בלבד, אבל היא שימושית מאוד בהפיכת הקוד לקריא יותר.  

קריאת קלט מהמשתמש

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

#include <stdio.h>
int main() {
    int number;
    scanf("%d", &number);
    printf("You entered %d\n", number);
}

יש הרבה מרכיבים שאנחנו כבר מכירים מהתוכנית הקודמת וכמה חדשים. נסביר אותם בקצרה:

  1. int number – זוהי נקראת “הצהרה” (declaration) של משתנה. הצהרות מאפשרות לנו לתת שם למשתנה כלשהו איתו נבצע פעולות וחישובים. לכל משתנה יש טיפוס (type) שמגדיר איך התוכנית מפרשת אותו וכמה מקום הוא צורך בזכרון. להצהרה תמיד יש שני חלקים – הטיפוס (type) של המשתנה ולאחר מכן השם שלו. במקרה זה הצהרנו על משתנה מטיפוס int (קיצור עבור integer, או מספר שלם) ששמו number.

  2. scanf("%d", &number) - זוהי שורה מורכבת יותר, נפרק אותה לרכיביה:

    1. scanf - קיצור של scan formatted, זוהי פונקציה מאותה ״משפחה״ כמו print שמתעסקות בקבלת קלט מהמשתמש והצגתו על המסך.
    2. d% - הפונקציה scanf צריכה לדעת איזה סוג משתנה היא צפויה לקבל מהמשתמש בשביל לדעת איך לכתוב אותו בזכרון. הסימון d% הוא סימון מוסכם למשתנה מסוג int - בהמשך נראה סימונים נוספים כמו lf% ו-s% שיסמנו משתנים מסוגים אחרים. number& - הפונקציה scanf שומרת את את המספר שהמשתמש כתב לתוכנית בתוך המשתנה number בשביל שנוכל לעשות בו שימוש אחרי זה. נשים לב לשימוש ב-& לפני שם המשתנה - אנחנו צריכים עוד מעט רקע בשביל להבין מה תפקידו פה בדיוק ולכן נשים לב לקיומו אבל לא ננתח אותו כרגע. ככלל אצבע לבינתיים, כאשר משתמשים ב-scanf בשביל לקרוא קלט מהמשתמש נשתמש ב-& לפני שם המשתנה - ב-printf לא נעשה זאת.
  3. לאחר מכן אנחנו מדפיסים את המספר שהכניס המשתמש. גם כאן אנחנו משתמשים במזהה d% בשביל לספר ל-printf איזה סוג משתנה היא צריכה להדפיס, ואז מעבירים אותו כארגומנט נוסף לפונקציה.