דוא"ל:
תפריט משתמש




שתף |

קורס:"שפת C"

שיעור 2: הכרת שפת  C 

[ <<< הקודם ] [ תוכן עניינים ] [ הבא >>> ]

מתוך הספר: C - מדריך מקצועי       C - מדריך מקצועי
תוכן עניינים



תכנית ראשונה ב- C

נכתוב תכנית בסיסית בשפת C המדפיסה למסך שורה בודדת. קוד התכנית:

 
file: hello.c
#include <stdio.h>
 
void main ( )
{
          printf("hello, Israel!\n");
}
 

פלט התכנית:

 
hello, Israel!
 

הסבר התכנית

התכנית כתובה בקובץ בשם hello.c. בהמשך נראה כיצד ניתן להדר את התכנית ולהריץ אותה. החלק הראשון:

 
 #include <stdio.h>
 

מודיע למהדר שאנו עומדים להשתמש בספריית הקלט/פלט התקנית stdio.h (Standard I/O). החלק השני :

 
void main ()
{
 
}
 

הוא הגדרת הפונקציה הראשית של התכנית:

  - הפונקציה main חייבת להופיע בכל תכנית C.
  - הסוגריים המסולסלות מציינות את התחלת וסיום הפונקציה.
  - כפי שנראה בהמשך, התכנית יכולה להכיל פונקציות נוספות.

החלק הנמצא בין הסוגריים המסולסלות

 
{ 
          printf("hello, Israel!\n");   
}
 

הוא גוף הפונקציה הראשית, והוא כולל הוראת הדפסה ע"י קריאה לפונקצית הספרייה printf: הפונקציה מדפיסה את המחרוזת הנתונה לה בין הסוגריים, "hello, Israel!\n", כאשר סיומת המחרוזת "\n" היא צירוף תווים מיוחד המורה על הדפסת תו שורה חדשה (new line).

הפונקציה printf לא מדפיסה תו שורה חדשה אלא אם כן הוכנס צירוף התווים המיוחד במחרוזת להדפסה. לכן ניתן לכתוב את התוכנית גם כך:

 
#include <stdio.h>
void main( )
{
          printf("hello,");
          printf("Israel!");
          printf("\n");
}
 


כתיבה, הידור והרצת התכנית

לצורך יצירת והרצת התכנית יש צורך בסביבת פיתוח. קיימות סביבות פיתוח חינמיות רבות ליצירת תכניות C/C++, כגון "Eclipse", "GCC - GNU C/C++", "Borland C++".

ליצירת התכנית ולהרצתה דרושים מספר שלבים :

  • פתיחת קובץ חדש:  פותחים קובץ חדש ע"י בחירה בתפריט File / New:
  • כתיבת התכנית : כותבים את התכנית הנ"ל בקובץ החדש שיצרנו.
  • שמירת הקובץ: לצורך שמירת התכנית, יש לבחור ב- File / save ולבחור שם קובץ לשמירה hello.c.
  • הידור והרצת התכנית : להידור התכנית בוחרים בתפריט Compile. אם ההידור הצליח, ניתן להריץ את התכנית ע"י בחירה בתפריט Run.
אם יש שגיאות, הן מופיעות בחלון התחתי, חלון השגיאות. סימון הודעת השגיאה יציג בחלון העריכה את שורת השגיאה.

תרגול

קרא/י סעיף זה בספר ובצע/י את התרגיל שבעמ' 33.

הגדרת משתנים, קלט ופלט

בתכנית הדוגמא הבאה נכיר מרכיבים בסיסיים בשפת C:

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

חישוב והדפסת הממוצע של 3 מספרים

התכנית הבאה מממשת את האלגוריתם שראינו בפרק 1, "מבוא לתכנות", לחישוב והדפסת הממוצע של 3 מספרים שלמים:

משתנים: num1, num2, num3 - משתני הקלט, שלמים
               avg - משתנה התוצאה, ממשי
קרא מספר ראשון מהקלט לתוך num1
קרא מספר שני מהקלט לתוך num2
קרא מספר שלישי מהקלט לתוך num3
חשב את הסכום של num1, num2, num3 והצב אותו ב- avg
חלק את avg ב- 3 והצב את התוצאה ב- avg
הדפס את avg


תרשים האלגוריתם:

קוד התכנית

קוד התכנית בשפת C נכתב בקובץ average.c ונראה כך:

 
/* file: average.c */
#include <stdio.h>
 
/* calculate the average of 3 numbers */
void main()
{
          int num1, num2, num3;
          float avg;
 
          printf("Enter 3 integer numbers: ");
          scanf("%d %d %d", &num1, &num2, &num3);
 
          avg = num1 + num2 + num3;
 
          avg = avg / 3;
 
          printf("The average is: %f", avg);
}
 

הרצת התכנית

בהרצת התכנית הוכנסו 3 מספרים

 
Enter 3 numbers: 23 45 11
 


והתקבל הפלט:

 
The average is: 26.333334
 

הסבר התכנית

הקטע ההצהרתי

  • כמו בתכנית הקודמת, גם כאן נצטרך להשתמש בספריית הקלט/פלט התקנית ולכן נבצע את ההכללה המתאימה:
 
#include <stdio.h>
 
  • סימן הערה: המהדר מתעלם מהתווים הנמצאים בין /*...*/ ולכן הם משמשים לרישום הערות הסבר לתכנית:
 
/* calculate the average of 3 numbers */
void main ( )
{
...
}
 

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

  • הצהרה על משתנים וטיפוסיהם - בהצהרה על משתנה , ראשית מופיע הטיפוס (type) ואח"כ שם המשתנה.
  - הטיפוס int (integer) משמש להצהרה על משתנה מטיפוס שלם:
 
          int num1, num2, num3;
 
    num1, num2, num3 הם משתנים שלמים שלתוכם ייקלטו הערכים מהקלט. כפי שניתן לראות, ניתן להכריז על מספר משתנים באותה הוראה.
 
         
 
  - הטיפוס float (floating point) מציין טיפוס ממשי בהצהרת המשתנה avg:
 
          float avg;
 
    avg הוא משתנה ממשי שבו תחושב תוצאת הסכום ולאחר מכן הממוצע.


טיפוסים נוספים הקיימים בשפה:

    char - תו, בית בודד
    short - שלם קצר
    long - שלם ארוך
    double - ממשי בעל דיוק כפול
    long double- ממשי בעל טווח ערכים גדול

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

הקטע הביצועי

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

 
          printf("Enter 3 integer numbers: ");
 

בהוראה זו מתבקש המשתמש להקליד 3 מספרים שלמים. בשלב הבא נקראים המספרים ע"י ההוראה scanf :

 
          scanf("%d %d %d", &num1, &num2, &num3);
 

scanf היא פונקצית קלט הקוראת מהקלט לתוך רשימת פרמטרים עפ"י פורמט הנתון לה במחרוזת בקרה. לצורך ביצוע הקלט אנו מספקים ל- scanf את מחרוזת הבקרה 

 
          "%d %d %d"
 

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

 
          &num1, &num2, &num3
 

הפונקציה scanf קוראת נתונים מהקלט לתוך כתובות שניתנות לה כפרמטרים.

האופרטור "&" מציין "הכתובת של": הצבתו לפני שם המשתנה מציינת התייחסות לכתובתו - נעסוק במצביעים בהרחבה בפרק 8, "מצביעים".

במקרה זה ציינו שאנו מעונינים לקרוא 3 מספרים שלמים: %d במחרוזת הבקרה הוא מציין טיפוס המציין עבור המהדר טיפוס שלם של פרמטר מתאים ברשימת הפרמטרים.

לכל פרמטר מותאם מציין טיפוס, עפ"י הסדר:

קיימים מצייני טיפוס גם לטיפוסים האחרים, לדוגמא:

    %f - מציין טיפוס ממשי
    %c - מציין טיפוס תו
    %s - מציין טיפוס מחרוזת

scanf מתעלמת מהתווים ה"לבנים" - רווח, טאב ותו שורה חדשה - אלא אם כן סוג הנתון הנקרא הוא תווי.

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

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

 
          avg = num1 + num2 + num3;
 

הסימן "=" ב- C מציין פעולת הצבה (Assignment). תוצאת הביטוי שמימין לסימן מוצבת לתא בזיכרון שמשמאל לו. פעולה זו נקראת גם "השמה".

שאלה: איך מסמנים שוויון בביטוי לוגי?

תשובה: ע"י שני תווים רצופים כנ"ל : "==".

חישוב הממוצע מתבצע ע"י חילוק avg ב- 3 :

 
          avg = avg / 3;
 

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

ניתן לקצר את התכנית ע"י ביצוע פעולות החיבור והחלוקה בהוראה יחידה:

 
          avg = (num1 + num2 + num3) / 3;
 

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

בסיום מודפס ערכו של avg ע"י הפונקציה printf :

 
          printf("The average is: %f", avg);
 

בדומה לפונקציה scanf, גם printf כוללת מחרוזת בקרה ולאחריה רשימת פרמטרים.

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

 
The average is:
 


ולאחריה את ערכו של avg. כפי שראינו, פלט התכנית שהורצה לעיל הוא

 
The average is: 26.333334
 


משפטי תנאי ולולאות

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

שפת C כוללת הוראות בקרה לקביעת מהלך התכנית:

  • משפט if-else לביצוע מותנה של הוראות
  • לולאות מסוגים שונים משמשות לביצוע חוזר של קטע קוד

משפט if-else

משפט if-else מבצע הוראה או מספר הוראות כתלות בתנאי מסוים. לדוגמא, אם נרצה להדפיס את ההפרש שבין 2 מספרים, num1 ו- num2, בערכו המוחלט נבצע:

 
          if( num1 > num2 )
                   printf("|num1 - num2|= %d", num1 - num2);
          else
                   printf("|num1 - num2|= %d", num2 - num1);
 

ניתן לתאר את הוראת if-else ע"י תרשים זרימה:

ההוראה if כוללת ביטוי לוגי בסוגריים, ובמידה וערכו אמת - כלומר num1 גדול מ-  num2 - ההוראה העוקבת מבוצעת:

 
          if( num1 > num2 )
                   printf("|num1 - num2|= %d", num1 - num2);
 

ההוראה else לאחר ההוראה if מציינת פעולה אלטרנטיבית לביצוע אם תוצאת הביטוי הלוגי הייתה שקר:

 
          else
                   printf("|num1 - num2|= %d", num2 - num1);
 

ההוראה else היא אופציונלית - ייתכן משפט if ללא הוראת else.

עיין/י בתכנית הדוגמא המובאת בעמ' 40-41.

ביצוע מספר הוראות - בלוק

אם רוצים לבצע מספר הוראות בהוראת if או else, יש להקיפם בסוגריים מסולסלות, לדוגמא:

 
          if( num1 > num2 )
          {
                   max = num1;
                   printf("The maximum is: %d", max);
          }
 

סדרת הוראות מוקפת בסוגריים {} נקראת בלוק.



אופרטורים לוגיים 

האופרטור '>' מציין את היחס הלוגי "גדול מ-". הטבלה הבאה כוללת את האופרטורים הלוגיים ב- C ואת משמעותם:

x == y

            x שווה ל- y

x != y

            x שונה מ- y

x > y

            x גדול מ- y

x >= y

            x גדול מ- y או שווה לו

x < y

            x קטן מ- y

x <= y

            x קטן מ- y או שווה לו

לולאת while

לולאת while משמשת לביצוע חוזר של הוראות כתלות בתנאי מסוים: תחביר הלולאה הוא

while(ביטוי לוגי)

{

הוראות

}

כל עוד ערכו של הביטוי הלוגי אמת ההוראות שבגוף הלולאה מתבצעות. תרשים זרימה עבור ביצוע לולאת while:

נכתוב תוכנית להדפסת טבלת המרה מאינצ'ים לסנטימטרים. נוסחת ההמרה:

    1 inch = 2.54 cm  

קוד התכנית:

 
/* file: convert.c */
#include <stdio.h>
 
/* print an Inch - Centimeter conversion table */
void main ( )
{
          int    Xinch;
          float Xcm;                                            
          int    lower, upper, step;
          
          lower=0;   /* lower limit of table */
          upper=10;          /* upper limit */   
          step=1;      /* step size */
          Xinch=lower;
          while(Xinch<=upper) 
          {
                            Xcm = Xinch * 2.54;                                
                            printf("%d\t%f\n",Xinch,Xcm);           
                            Xinch=Xinch+step;
          }
}
 

פלט התכנית:

 
0       0.000000 
1       2.540000
2       5.080000
3       7.620000
4       10.160000
5       12.700000
6       15.240000
7       17.780000
8       20.320000
9       22.860000
10      25.400000
 

הסבר התכנית

בחלקה הראשון של התכנית מצהירים על משתנים :

 
          int    Xinch;
          float Xcm;                                            
          int    lower, upper, step;
 

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

 
          lower=0;   /* lower limit of table */
          upper=10;          /* upper limit */   
          step=1;      /* step size */
          Xinch=lower;
 

לולאת while מתבצעת כל עוד התנאי הנמצא בסוגריים מתקיים:

 
          while(Xinch <= upper)
 

הסימן "<=" מציין "קטן או שווה". משמעות התנאי היא "Xinch קטן או שווה ל- upper". הלולאה בכללותה :

 
          while(Xinch <= upper) 
          {
                   Xcm = Xinch * 2.54;                             
                   printf("%d\t%f\n",Xinch,Xcm);        
                   Xinch=Xinch+step;
          }
 

גוף הלולאה כולל 3 הוראות:

    1) תרגום הערך מאינצ'ים לסנטימטרים:
 
                   Xcm = Xinch * 2.54;
 
    2) הדפסת התוצאות: בהדפסה אנו מספקים לפונקציה printf את פורמט המשתנים להדפסה:
 
                   printf("%d\t%f\n",Xinch,Xcm);       
 

%d הוא מציין טיפוס שלם המתייחס לשלם Xinch , ו- %f מתייחס לממשי Xcm.

התווים '\t' ו- '\n' הם תווים מיוחדים להדפסה :

     \t - מציין הדפסת טאב
    \n - מציין הדפסת תו שורה חדשה

תרגול

קרא/י סעיף זה בספר ובצע/י את התרגיל שבעמ' 45.

סידור פלט התכנית

בעיה: פלט התכנית לא ערוך מספיק יפה:

  - המספרים השלמים אינם מוצמדים ימינה
  - מיקום הנקודה העשרונית בממשיים אינו אחיד
  - די בדיוק של שני מקומות אחרי הנקודה העשרונית בהדפסת הממשיים

פתרון: נשתמש בשדות רווח ושדות הצמדה בפלט:

 
          printf("%2d\t%5.2f\n", Xinch, Xcm);       
 

עבור הדפסת השלם:

  - רוחב השדה (2) מצוין בין הסימן % לבין סימן הטיפוס.

עבור הדפסת הממשי:

  - רוחב השדה (הכולל) מצוין בין הסימן % לבין סימן הטיפוס.
  - רוחב שדה השבר מצוין לאחר הנקודה העשרונית.

כמו כן, נוסיף לטבלה הדפסת כותרות ע"י :

 
          printf("Inch\tCm\n");
          printf("----\t-----\n");
 

התכנית המתוקנת מובאת בעמ' 46.

והפלט:

 
Inch  Cm
----  -----
 0     0.00
 1     2.54
 2     5.08
 3     7.62
 4    10.16
 5    12.70
 6    15.24
 7    17.78
 8    20.32
 9    22.86
10    25.40
 




סיכום שדות ההדפסה ב- printf שהכרנו עד כה:

הדפס כשלם עשרוני

            %d

הדפס כשלם עשרוני ברוחב 6 לפחות

            %6d

הדפס כממשי (floating point)

            %f

הדפס כממשי ברוחב 2 אחרי הנקודה העשרונית

            %.2f

הדפס כממשי ברוחב 6 לפחות, 2 מקומות אחרי הנקודה העשרונית

            %6.2f

תרגול

קרא/י סעיף זה בספר ובצע/י את תר' 1-2 שבעמ' 47.

הגדרת קבועים

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

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

קבועים הם שמות המייצגים ערכים קבועים שאינם משתנים לאורך כל התכנית.  הם מוגדרים בצירוף המילה השמורה const.

שימוש בהגדרת קבועים בתכנית מקל על פעולות העריכה, התיעוד והתחזוקה של ערכים קבועים בתכנית.

נבצע מספר שינויים בתכנית:

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

התכנית החדשה:

 
/* file: convert3.c */
#include <stdio.h>
 
/* print a Inch - Centimeter conversion table, define constants */
void main ( )
{
          const  int       LOWER=0, UPPER=10;
        const float FACTOR=2.54f;
          int    Xinch;
          float Xcm;                                            
 
          Xinch=LOWER;
          printf("Inch\tCm\n")/* print table header */
          printf("----\t--\n");
          while(Xinch<=UPPER) 
          {
                   Xcm = Xinch * FACTOR;                               
                   printf("%2d\t%5.2f\n",Xinch,Xcm);            
                   Xinch++;
          }
}
 

הגדרת הקבועים מתבצעת תוך שימוש במילה השמורה const :

 
          const         int    LOWER=0, UPPER=10;
          const float  FACTOR=2.54f;
 
הערה : לקבוע הממשי מצורפת האות 'f' המציינת שהקבוע הוא מטיפוס float. טיפוס ברירת המחדל עבור ערכים ממשיים בתכנית הוא double, כפי שנראה בפרק הבא. הסיומת f מונעת את הודעת האזהרה של המהדר שהייתה בגרסה הקודמת של התכנית.

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

 
          Xinch=LOWER;
          printf("Inch\tCm\n")/* print table header */
          printf("----\t--\n");
          while(Xinch<=UPPER) 
          {
                   Xcm = Xinch * FACTOR;                               
                   printf("%2d\t%5.2f\n",Xinch,Xcm);            
                   Xinch++;
          }
 

כעת לא ניתן לשנות את הקבועים בתכנית - ניסיון לשנותם ייתן הודעת שגיאה בהידור.

האופרטור "++" מבצע קידום ב- 1 של המשתנה. לכן, הביטוי

 
  Xinch++
 

שקול לביטוי

 
Xinch = Xinch +1;
 

באופן דומה משמש האופרטור "--" להחסרה של 1.

הגדרת קבועים ע"י הקדם-מעבד (Pre-processor)

קיימת דרך נוספת להגדרת קבועים - ע"י שימוש בקדם-מעבד:

 
/* file: convert4.c */
#include <stdio.h>
 
#define LOWER            0                       /* lower limit of table*/
#define UPPER            10                    /* upper limit*/
#define FACTOR   2.54f  /* conversion factor */
 
/* print a Inch - Centimeter conversion table, define constants */
void main ( )
{
          int    Xinch;
          float Xcm;                                            
 
          Xinch=LOWER;
          printf("Inch\tCm\n")/* print table header */
          printf("----\t--\n");
          while(Xinch<=UPPER) 
          {
                   Xcm = Xinch * FACTOR;                                
                   printf("%2d\t%5.2f\n",Xinch,Xcm);            
                   Xinch++;
          }
}
 

הסבר

הגדרות הקבועים

 
#define LOWER            0                       /* lower limit of table*/
#define UPPER            10                    /* upper limit*/
#define FACTOR   2.54f  /* conversion factor */
 

הן הוראות לקדם-מעבד (pre-processor): זוהי תת-תכנית במהדר העוברת על הקוד שבקובץ ומבצעת את כל ההוראות המתחילות בסימן # (נרחיב בנושא בפרק 11, בסעיף "הקדם-מעבד").

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

מה ההבדל בין שתי הצורות? בהגדרת קבוע מספרי ע"י const מוגדר תא בזיכרון עבור הקבוע, ואילו בהגדרה ע"י הקדם מעבד אין הגדרה של תא בזיכרון.

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

הבדל נוסף הקיים בין 2 הצורות הוא במרחב השם (namespace) של הקבוע: קבוע המוגדר ע"י הקדם מעבד מוכר בכל קובץ התכנית, החל מהמקום בו הוגדר. קבוע המוגדר ע"י const לעומת זאת הוא בעל מרחב שם מוגבל יותר, עפ"י מקום הגדרתו, כפי שנראה בפרק 6, "פונקציות".

קלט / פלט של תווים

לצורך ביצוע קלט/פלט של תווים נשתמש בפונקציות הספרייה התקנית stdio.h:

    c=getchar( )           - קוראת את התו הבא מהקלט לתוך המשתנה c.
    putchar(c)              - מדפיסה את המשתנה c למקום הבא בפלט.


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

קרא תו
כל עוד לא הגענו לסוף קובץ הקלט:
          - הדפס את התו שנקרא לקובץ הפלט
          - קרא תו

התכנית:

 
/* file: copy.c */
#include <stdio.h>
 
/* copy input to output: 1st version */
void main()
{        
          int c;
          c=getchar();
          while (c!=EOF) 
          {
                   putchar(c);
                   c=getchar();
          }        
}
 

הסבר: התכנית מגדירה משתנה מסוג int וקוראת תו ראשון לתוכו. הסימן "!=" מציין "שונה" - כלומר משמעות הביטוי (c!=EOF) היא "התו c שונה מתו סוף קובץ".

מדוע הגדרנו את c כ"int"  ולא כ"char"? מכיוון ש- c אמור גם לקבל את ערך הקבוע EOF (שהוא -1 ) בהגעה לסוף הקובץ.

יש לשים לב לכך שבהגעה לסוף שורה בקלט נקרא תו סוף השורה '\n' (תו יחיד) ע"י הפונקציה getchar() ומודפס ע"י הפונקציה putchar(). כמו כן ניתן להדפיסו ישירות ע"י

 
putchar('\n');
 

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

שימוש בביטוי הצבה כמחזיר ערך

בשפת C ביטוי הצבה מחזיר ערך. לדוגמא:

 
 c = getchar();
 

הוא ביטוי שערכו כערך שהושם ל- c. כלומר, ערך ביטוי ההצבה הוא הערך שהושם. למשל, ניתן לכתוב

 
 x = ( c = getchar() );
 

ואז x  יקבל את הערך שהושם ב- c.

נשנה את התכנית כך שההצבה ובדיקת ההגעה לסוף הקלט יבוצעו באותה הוראה. אלגוריתם התכנית:

כל עוד התו הנקרא אינו תו סוף הקובץ
          - הדפס את התו

קוד התכנית:

 
/* file: copy2.c */
#include <stdio.h>
 
/* copy input to output: 2nd version */
void main()
{        
          int c;
          while ((c=getchar())!=EOF) 
                   putchar(c);
}
 

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

שאלה : מדוע נחוצים סוגריים סביב ההצבה c=getchar()?

תשובה: מכיוון שלאופרטור  =! יש עדיפות גבוהה מלאופרטור =. לו כתבנו

 
          c = getchar() != EOF
 

הביטוי היה מחושב כ-

 
          c = ( getchar() != EOF )
 

כלומר c היה מקבל את הערך הבוליאני של אי-השוויון! בפרק הבא נעסוק בטיפוס בוליאני ובייצוגו בשפת C.



הצבה כפולה

הואיל וביטוי הצבה מחזיר ערך, ניתן לבצע הצבה כפולה, לדוגמא:

 
          x = y = 5;
 

ביטוי זה שקול לביטוי

 
          x = (y = 5);
 

מחרוזות

בשפת C לא קיים טיפוס מחרוזת בסיסי. מחרוזת מיוצגת כמערך תווים המסתיים בתו מסיים מחרוזת.

על מערכים נלמד בהרחבה בפרק 7, "מערכים", לעת עתה נראה רק כיצד להגדיר מחרוזות באמצעותם.

מציינים ערך מחרוזת ע"י גרשיים משני צידיה, לדוגמא:

 
char str[17] = "www.mh2000.co.il";                     /* home page of this book */
 

ההגדרה  char str[17] מציינת ש- str הוא מערך תווים בעל 17 מקומות. לאחר ביצוע ההשמה של המחרוזת "www.mh2000.co.il" ל- str היא מחרוזת בת 16 תווים + תו מסיים מחרוזת (בלתי נראה):

התו '\0' (קו נטוי הפוך ואפס) הוא תו סוף מחרוזת. באופן דומה, ניתן להגדיר את str גם ללא ציון גודל המערך:

 
char str[] = "www.mh2000.co.il";
 

המהדר יקצה אוטומטית ל- str את גדלו (17 תווים), עפ"י המחרוזת המוצבת לו. הדפסת מחרוזת מבוצעת ע"י הוראת printf באמצעות מזהה הטיפוס %s , לדוגמא:

 
char str[] = "www.mh2000.co.il";
printf("Welcome to %s !",str);
 

יודפס:

 
Welcome to www.mh2000.co.il !
 

הגדרת טיפוס מחרוזת פשוט

לשם טיפול נוח במחרוזות נגדיר טיפוס מחרוזת, String, באופן הבא:

 
typedef char String[256];
 

typedef משמש להגדרת טיפוס חדש: במקרה זה הגדרנו את הטיפוס String כמערך של 256 תווים.

בפרק הבא נכיר בפירוט את ההוראה typedef.

כעת ניתן להגדיר משתנים מסוג String :

 
String s1 = "hello";
String  s2 = "world";
 

תכנית דוגמא:

 
#include <stdio.h>
 
typedef char String[256]; 
 
void main ( )
{
          String first_name;
          String second_name;
 
          printf("Enter your first name: ");
          scanf("%s", first_name);
          printf("Enter your second name: ");
          scanf("%s", second_name);
 
          printf("Your full name is %s %s\n", first_name, second_name);
 
}
 

דוגמא להרצת התכנית:

 
Enter your first name: Louis
Enter your second name: Armstrong
Your full name is Louis Armstrong
 


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

 
          String first_name;
          String second_name;
 

המשתנים נקראים מהקלט ע"י הוראות scanf עם מציין הטיפוס %s, אולם בניגוד למשתנים רגילים, משתני המחרוזת עצמם מועברים כפרמטרים ולא כתובותיהם:

 
          printf("Enter your first name: ");
          scanf("%s", first_name);
          printf("Enter your second name: ");
          scanf("%s", second_name);
 

הסיבה לכך היא שמחרוזת, המיוצגת כמערך, היא בעצמה כתובת.

נעסוק בכך בהרחבה בפרק 9, "מחרוזות". לאחר ביצוע הקלט, המחרוזות מודפסות ע"י הוראת printf, שוב עם מציין הטיפוס %s:

 
          printf("Your full name is %s %s\n", first_name, second_name);
 

פעולות על מחרוזות

בשפת C לא ניתן להציב מחרוזת אחת לשנייה ע"י s1=s2 או לבדוק שוויון ביניהן ע"י s1==s2.

לביצוע פעולות אלו קיימות פונקציות הספרייה string.h שנכיר אותן בפרק 9, "מחרוזות".

סיכום

  • בפרק זה סקרנו את המרכיבים הבסיסיים בשפה :
    טיפוסים ומשתנים
    לפני שימוש במשתנה יש להכריז על שמו וטיפוסו בתחילת התכנית. הטיפוסים העיקריים: שלם (int), תו (char), ממשי (float) .
    ביטויים
    ניתן לבצע פעולות שונות בין משתנים. אוסף משתנים ופעולות עליהם נקרא ביטוי. ראינו מספר סוגי ביטויים: ביטויים חשבוניים (x*y) , ביטויים לוגיים (Xinch<=10), ביטויי הצבה (Xcm=0).
    קבועים
    קבועים הם שמות של ערכים שאינם משתנים לכל אורך התכנית. ניתן להגדיר קבועים ע"י שימוש במילה const או ע"י הגדרתם בקדם-מעבד (pre-processor) בהוראת #define.
    מילים שמורות
    המילים השמורות בשפה משמשות לציון טיפוסים והוראות בשפה ואינן ניתנות לשימוש אחר ע"י המתכנת. דוגמאות למילים שמורות: int, float, while,.
  • קלט / פלט של משתנים בתכנית מבוצע ע"י פונקציות הספרייה stdio.h. הכרנו את הפונקציות:
    scanf() לביצוע קלט של משתנים מטיפוסים שונים (מספרים ומחרוזות).
    printf() להדפסה מורכבת של טקסט משולב עם משתנים מטיפוסים שונים.
     getchar() ו- putchar() לקריאת ולהדפסת תו בודד.
  • לולאות משמשות לביצוע פעולות חוזרות מספר מסוים של פעמים או כתלות בקיום תנאי כלשהו. לולאת while היא לולאה המתבצעת כל עוד תנאי הלולאה מתקיים.
  • מחרוזות הן מערכי תווים בעלי תו סוף מחרוזת בסופם. הן ניתנות לקריאה ולהדפסה ע"י scanf() ו- printf() עם מציין הטיפוס %s.

תרגילי סיכום

בצע/י את תרגילי הסיכום 1-5 שבעמ' 55-56.



[ <<< הקודם ] [ תוכן עניינים ] [ הבא >>> ]