מבוא למחשב בשפת C צעדים הרצאה 2: ראשונים בשפת C מבוסס על השקפים שחוברו ע"י שי ארצי, גיתית רוקשטיין, איתן אביאור וסאהר אסמיר עבור הקורס "מבוא למדעי המחשב". עודכן ע"י דן רביב נכתב על-ידי טל כהן, נערך ע"י איתן אביאור. כל הזכויות שמורות לטכניון מכון טכנולוגי לישראל
איך לראות את ההגשה 2
תוכנייה מבנה תוכנית בשפת C הערות )Comments( פונקציות )Functions( הכללת קבצים ע"י #include תוספות ושיפורים לתוכנית מהשיעור הקודם )סיכום 10 מספרים( #define אבני בניין של השפה מילות מפתח )Keywords( מזהים )Identifiers( הגדרת סמלים לקבועים באמצעות 3
מבנה תוכנית בשפת C /* The traditional first program in honor of Dennis Ritchie who invented C at Bell Labs in 1972 */ #include <stdio.h> הערה הכללת קובץ הפונקציה main int main() { printf("hello World!\n"); return 0; } הדפסה למסך ע"י קריאה לפונקציה ערך מוחזר אנו נעבור על כל אחד ממרכיבי התוכנית בשקפים הבאים 4
הערות הערה )Comment( טקסט בתוך */... /* הערה יכולה להשתרע על פני מספר שורות דוגמה: /* In this part of the program we handle the computation of the final grades. */ בשפות תכנות אחרות ישנם סימונים אחרים להערות. למשל ב- ++C מותר להשתמש ב- //. הערה בסגנון זה אינה חוקית בשפת C )בסטנדרט של הקורס C89( 5
הפונקציה main תוכנית סטנדרטית בשפת C צריכה הביצוע המעשי של התוכנית יחל בפונקציה זו. בשלב זה נניח כי main הפרמטרים של main להכיל פונקציה אשר שמה הוא main אינה מקבלת פרמטרים. הינם מעבר להיקף הקורס שלנו. הערך המוחזר ממנה הוא "קוד סיום התוכנית", אשר מוחזר למערכת ההפעלה לגבי קוד זה, המוסכמה היא ש-: 0: סיום בהצלחה שונה מ- 0 : בעיה כלשהי int main() {... return 0; /* or return -1; */ } 6
פונקציות דוגמה: חישוב חזקה הצהרה )חתימה(: שם טיפוס מוחזר float power(float x, int n); #include <stdio.h> int main() { printf("hello World!\n"); return 0; { } נקודה-פסיק הגדרה )גוף(: שני פרמטרים float power(float x, int n) } float p; int i; שני פרמטרים שם טיפוס מוחזר p = 1.0; for ( i = 0; i < n; i++) p = p * x; return p; 7
קבצי כותרת והכללתם ע"י #include ספרייה STDIO כוללת פונקציות קלט/פלט printf / scanf ספרייה MATH כוללת פונקציות מתמטיות pow / exp / sqrt קובץ כותרת File( :)Header קובץ בעל סיומת "h." אשר מכיל הצהרות על עצמים חיצוניים. הנחיה להכליל קובץ כותרת מכיל הצהרות על פונקציות קלט-פלט // <stdio.h> #include מכיל הצהרות על פונקציות מתמטיות // <math.h> #include בתוכנית HelloWorld שראינו, ישנה הכללה של <stdio.h> שאנו משתמשים בפונקציה printf המוצהרת שם. כיוון 9
פלט חכם ע"י printf פרמטרים: הארגומנט הראשון הוא מחרוזת תסדיר )format( )פירוט בתרגול(, ואחריה באים הערכים )המשתנים( אותם יש להדפיס לפי התסדיר. כל ארגומנט מתאים לקוד ה-% הבא בתור במחרוזת התסדיר. מחרוזת התסדיר יכולה גם להכיל טקסט רגיל )ללא %( שיודפס כמו שהוא. ערך החזרה: מספר התווים שנכתבו, או מספר שלילי בעת כישלון. printf("just printing text.\n"); דוגמאות: int i = 5; printf("the sum of %d and %d is %d", i, 2, 2+i); 10
אתר cplusplus.com 11
קלט חכם ע"י scanf פרמטרים: הארגומנט הראשון הוא מחרוזת תסדיר )format( )פירוט בתרגול(, ואחריה באים המשתנים אותם יש לקרוא לפי התסדיר. כל ארגומנט מתאים לקוד ה-% הבא בתור במחרוזת התסדיר. יש להוסיף & לפני שם המשתנה )נבין מדוע בהמשך(. ערך החזרה: מספר הנתונים שנקראו בהצלחה, או 1- במקרה של כישלון כללי )שגיאה חמורה(. int i; לא לשכוח את ה-& double x; float y; scanf("%d%lf%f", &i, &x, &y); שימוש )קריאה לפונקציה(: 12
תוכנייה מבנה תוכנית בשפת C הערות )Comments( פונקציות )Functions( הכללת קבצים ע"י #include תוספות ושיפורים לתוכנית מהשיעור הקודם )סיכום 10 מספרים( #define אבני בניין של השפה מילות מפתח )Keywords( מזהים )Identifiers( הגדרת סמלים לקבועים באמצעות טיפוסי מידע בסיסיים 13
תוכנית לסיכום 10 מספרים מהשיעור שעבר #include <stdio.h> int main() { int i, sum, value; } sum = 0; for ( i = 0; i < 10; i++ ) { scanf("%d", &value); sum = sum + value; } printf("%d\n", sum); return 0; 14
תוכנית לסיכום מספרים שיפורים #include <stdio.h> int main() { int i, sum = 0, value, numbers_to_read; printf("please enter number of values\n"); scanf("%d", &numbers_to_read); for ( i = 0; i < numbers_to_read; i++ ) { printf("enter the next integer: "); scanf("%d", &value); sum = sum + value; } printf("the sum of the %d numbers is %d\n", numbers_to_read, sum); } return 0; 15
הסברים על התוספות תכנית אינטראקטיבית הינה תכנית הכוללת דו-שיח עם המשתמש דרך פעולות קלט ופלט. (1 על התכנית להיות "ידידותית למשתמש" להסביר לו במשפטים ברורים מה עליו לבצע ומהו הפלט שניתן לו. (2 3) מספר הערכים המסוכמים נקבע על-ידי המשתמש בזמן הריצה. ואם המשתמש יכניס אות במקום מספר? בדיקת חוקיות הקלט מונעת שיבוש ריצת התכנית בשל הימצאות ערכים שגויים בקלט. (4 16
תוכנית לסיכום 10 מספרים בדיקת קלט...... int scanf_result; printf("please enter number of values\n"); scanf_result = scanf("%d", &numbers_to_read); if ( scanf_result < 1 ) { printf("failed reading the number of values\n"); return 1; } for ( i = 0; i < numbers_to_read; i++ ) { printf("enter the next integer: "); scanf("%d", &value); sum = sum + value; } מה יקרה אם נכניס מספר לא שלם? איזה בדיקה נוספת כדאי לעשות? 17
תוכנייה שימוש בסביבת העבודה מבנה תוכנית בשפת C הערות )Comments( פונקציות )Functions( הכללת קבצים ע"י #include תוספות ושיפורים לתוכנית מהשיעור הקודם )סיכום 10 מספרים( #define אבני בניין של השפה מילות מפתח )Keywords( מזהים )Identifiers( הגדרת סמלים לקבועים באמצעות 18
אבני הבניין של שפת C אוסף הסימנים )תווים )characters שמהם מורכבת תכנית בשפת C מכיל: אותיות קטנות, אותיות גדולות, ספרות, סימני רווח, ומספר סימנים מיוחדים. 19
תווים בשפת C Lowercase letters a b c d z Uppercase letters A B C D Z Digits 0 1 2 3 4 5 6 7 8 9 Other characters + - * / = ( ) { } [ ] < > ' "! # % & _ \ ^ ~., ; :? White space characters blank, newline, tab, etc. 20
אבני הבניין של שפת C תכנית בשפת C הינה סדרה של תווים מהאוסף הנ"ל. השלב הראשון בקריאת תוכנית )בתהליך קומפילציה( הוא חלוקת סדרת התווים ל"מילים".)tokens( סוגי המילים )tokens( בשפת C: מילים שמורות )= מילות מפתח(, מזהים, קבועים, קבועי מחרוזת, סימני פעולה )אופרטורים( וכן סימני פיסוק. 21
רווחים לבנים Spaces( )White רווח לבן Space( )White רצף של אחד או יותר מהדברים הבאים: רווח 1) Tab (2 מעבר שורה 3) הערה 4) רווחים לבנים משמשים להפרדה בין מילים )tokens( צמודות. מלבד זאת, אין להם משמעות. #include <stdio.h> int main() { int i, sum, value; "הזחה" )Indentation( על מנת להפוך את התוכנית לקריאה יותר לאדם: נהוג להשתמש ברווחים/ tab הזחה היא הרחקה של שורה כתובה מהשוליים. הזחה נהוגה בדפוס ובתכנות מחשבים. על מנת לבצע } sum = 0; for ( i = 0; i < 10; i++ ) { scanf("%d", &value); sum = sum + value; } printf("%d\n", sum); return 0; נהוג לרשום כל פסוק בשורה נפרדת. 22
סוגי המילים מילות מפתח int while return וכו'. :(keywords) סימני פעולה = % / * - + וכו'. :(operators) סימני פיסוק ),( ; } { וכו'. :(punctuation) בכל אחת משלוש הקבוצות הללו יש מספר סופי של tokens אפשריים. sum value main scanf מזהים :(identifiers) 0 100 23.137 קבועים :(constants) "hello" "The result is %d." קבועי מחרוזת literals) :(string בכל אחת משלוש הקבוצות הללו יש מספר אינסופי של tokens אפשריים. 23
מילות מפתח )מילים שמורות( מילות מפתח words( )key הן מילים שיש להן משמעות קבועה מראש בשפה. בשפת C, מילות המפתח הן מילים שמורות words( )reserved ועל כן, אסור לעשות בהן שימוש אחר מלבד השימוש שלהן כמילות מפתח. מלבד מילות המפתח השמורות קיימות בסביבת העבודה מילים נוספות מוגדרות מראש, שמומלץ לא להגדיר את משמעותן מחדש: מזהים של רכיבים סטנדרטיים בתוכניות בשפת C, כגון: scanf,printf,main וכדומה. 24
המילים השמורות של שפת C ישנן 32 מילים שמורות, ואילו הן: ב- ANSI-C auto do goto signed unsigned break double if sizeof void case else int static volatile char enum long struct while const extern register switch continue float return typedef default for short union המילים הנוטות אינן בשימוש שכיח. 25
מזהים כשנכתוב תוכנית, למשל: יהיו בה רכיבים שונים שנרצה לתת להם שמות. פונקציות, משתנים, טיפוסים ועוד. שם של רכיב כזה נקרא מזהה. ) מזהה מורכב מרצף )באורך כלשהו( של ספרות, אותיות וקו תחתון ( _ אך אינו יכול להתחיל בספרה ואיננו יכול להיות מילה שמורה. דוגמאות למזהים חוקיים: x factor total sort_data result12 After2OClock _AVOID דוגמאות לרצפים שאינם מזהים חוקיים: 2day 12 register you&me ibm.com אות גדולה ואות קטנה אינן שקולות זו לזו. לכן, המזהה x שונה מהמזהה X. 26
חשיבותם של מזהים בעלי משמעות מבחינת המחשב, לא חשוב כלל באיזה מזהה תבחרו עבור כל חלק בתוכנית. זכותכם לקרוא למשתנה cosinus אמנם הערך שלו הוא.sin זכותכם גם לקרוא " () "my_sin לפונקציה שמחשבת קוסינוס. יחד עם זאת, חשוב מאוד לבחור מזהים בעלי משמעות, שיסייעו להבנת התוכנית! שימו לב, כמה בלתי מובנים הם הביטויים הבאים: t = p * tr sa = gr + fff וכמה קל להבין את התפקיד של הביטויים עכשיו: tax = price * tax_rate grade_of_semester_a = test_grade + factor 27
קבועים... num_of_students = 600; קבוע )constant( הוא רצף תווים המביע ערך מספרי מסוים. בפסוקים אלה מופיעים: success_sign = '+'; failure_sign = 'F'; if ( failure_rate > 0.25 )...... קבוע שלם 2 קבועי תו קבוע ממשי קבוע משמש אותנו להביע ערך הידוע בזמן כתיבת התוכנית, ואינו משתנה בזמן ריצתה. 28
קבועים מספריים שלמים ושבורים דוגמאות לקבועים שלמים: 0x1B7 032 10000 4 דוגמאות לקבועים ממשיים: 2.0.53 2.5 6. 3.3e+9 2e7.2e-7 אוקטלי )בסיס 8( הקסדצימאלי )בסיס 16( 3.3e+9 3.3 10 9 2e7 2 10 7.2e-7 0.2 10 7 הקבוע 2.0 )מספר ממשי( מיוצג בזיכרון באופן שונה מהקבוע 2 )מספר שלם(. על מנת להביע ערכים שליליים, ניתן להקדים סימן מינוס לקבוע או ממשי(: -4-10000 -2.0-6. -.2e-7 )שלם 29
קבועי תו, קבועי מחרוזת תו כלשהו המוקף בגרשים יחידים הינו קבוע תו: 'a' 'B' '+' '"' ' ' ישנם תווים מיוחדים שעל מנת לרשום את קבוע התו שלהם יש להשתמש בלוכסן הפוך: הוא התו המציין מעבר לשורה חדשה )newline( הוא התו גרש עצמו '\n' '\'' ועוד. רצף תווים כלשהם המוקף במרכאות כפולות )ג ר ש י ים( הינו קבוע מחרוזת: "I am a string" "I am a string\nwith embedded newlines!\n" בתוך מחרוזת, אין משמעות לביטוי או פסוק, והוא לא יתבצע:.a לא יגרום לשינוי ערכו של "a = b + c" מעמדם של קבועי תו וקבועי מחרוזת בתוכנית שונה, ויש להיזהר לא לערבב ביניהם שלא כדין!! 30
קבועים המופיעים בתוכנית התוכנית שלנו עשויה להכיל קבועים מסוגים שונים: 3.14159265358979323846 קבועים מתמטיים, כגון: 1. 23+6.02214179e קבועים פיזיקאליים, כגון: 2. 3. קבועים של גודל הבעיה, כגון: אורך הקלט, קבועים הנובעים משיטת הפתרון )האלגוריתם(, 4. קבועים נוספים. שני הסוגים הראשונים הם באמת קבועים, ולא ישתנו )ואולי כן?( הסוגים האחרים הם קבועים בזמן ריצת התוכנית, אבל עם הזמן עשויים להשתנות, ואז יש צורך לשנותם ולקמפל מחדש את התוכנית. בכל מקרה, לא נרצה שהתוכנית שלנו תהיה זרועה במופעים רבים של הקבועים הללו, כי תמיד אנחנו שואפים שלא לכתוב את אותו דבר יותר מאשר פעם אחת. 31
הגדרת סמלים לקבועים באמצעות #define #define MAX_SIZE 1000 ההגדרת קבוע )שלם(: זו הנחייה למהדר להתייחס לסדרת התווים MAX_SIZE כאילו היא סדרת התווים 1000 בפועל זה מתבצע )בד"כ( ע"י שלב מקדים להידור, הנקרא עיבוד-מקדים )pre-processing( ובו מוחלפות סדרות התווים בגוף התוכנית. - רק מופע של MAX_SIZE כמילה עצמאית )token( יוחלף: הסדרה MAX_SIZE2 לא תוחלף לסדרה 10002. - מופעים של MAX_SIZE בתוך קבוע מחרוזת )בין מרכאות( אינם מוחלפים. הגדרת הקבוע הנ"ל מאפשרת, באמצעות שינוי בודד, להפוך תכנית המטפלת ב- 1000 נתונים לתכנית המטפלת ב- 2500 נתונים. שימו לב: MAX_SIZE זה לא משתנה, ועל כן, לא מוקצה עבורו זיכרון. הגדרת קבוע אחר )ממשי(: #define PI 3.141592653589793238 תורמת לקריא ות של התכנית וחוסכת בזמן כתיבת התוכנית, ובזמן עריכת שינויים. כלל אצבע: כל קבוע שאיננו 1, 0, או 2, ראוי שיוגדר באמצעות סמל בעל משמעות. 32
המשך #define לעיתים נרצה להגדיר סמל קבוע ע"י ביטוי-קבוע, ולא ע"י מספר. לדוגמה: נניח שפרק זמן מסוים מוגדר כ"שעתיים וארבעים וחמש דקות". #define PERIOD 165 נוכל להגדיר: אבל אז קשה קצת להבין מה המשמעות של המספר ואולי נעדיף להגדיר: 165 ומנין נלקח. #define PERIOD 2*60 + 45 מה יקרה אם נרצה לחשב את משך הזמן של שתי תקופות? twice = PERIOD * 2 twice = 2*60 + 45 * 2 #define PERIOD (2*60 + 45) על כן, נגדיר: ואז נקבל: twice = PERIOD * 2 twice = (2*60 + 45) * 2 כלל אצבע: אם בהגדרה מופיע ביטוי )ולא מילה פשוטה( הקף אותו בסוגריים נוהג שכדאי לאמץ: הגדר שמות קבועים באותיות גדולות בלבד 33