למדריך לשפת C

‫שפת ‪C‬‬
‫נתנאל גרינברגר‬
‫תוכן עניינים‬
‫משתנים ‪3 .................................. ................................ ................................ ................................‬‬
‫פעולות חשבוניות ולוגיות ‪4 ............ ................................ ................................ ................................‬‬
‫קלט‪ /‬פלט ‪6 ................................ ................................ ................................ ................................‬‬
‫מבנה בסיסי ‪7 ............................. ................................ ................................ ................................‬‬
‫תווים ‪8 ...................................... ................................ ................................ ................................‬‬
‫בקרת זרימה ‪9 ............................ ................................ ................................ ................................‬‬
‫לולאות ‪11 .................................. ................................ ................................ ................................‬‬
‫פונקציות ‪14 ................................ ................................ ................................ ................................‬‬
‫מערכים ‪16 ................................. ................................ ................................ ................................‬‬
‫מחרוזות ‪18 ................................ ................................ ................................ ................................‬‬
‫מצביעים‪20 ................... ................................ ................................ ................................ pointer -‬‬
‫חוברת זו אינה מיועדת ללימוד אלא לצורך חזרה והעמקה‪.‬‬
‫יצירת קשר‪[email protected] :‬‬
‫כל הזכויות שמורות ©‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪2‬‬
‫משתנים‬
‫בזכרון הנדיף ישנם בתים שבהם נשמרים נתונים במהלך התוכנית‪.‬‬
‫משתנה הוא בית או מספר בתים בזכרון שבהם נשמרים הנתונים‪.‬‬
‫ישנם מספר טיפוסי משתנים‪ ,‬כל טיפוס משתמש במספר בתים בזכרון‪.‬‬
‫טיפוס משתנה‬
‫‪int‬‬
‫מטרה‬
‫מספר שלם‬
‫‪ short‬מספר שלם קטן‬
‫‪ long‬מספר שלם גדול‬
‫גודל בזכרון (מספר הבתים בד"כ)‬
‫‪4‬‬
‫‪float‬‬
‫‪double‬‬
‫מספר ממשי‬
‫מספר ממשי גדול‬
‫‪4‬‬
‫‪8‬‬
‫‪char‬‬
‫תו‬
‫‪1‬‬
‫הערות‪:‬‬
‫‪.1‬‬
‫‪.2‬‬
‫‪.3‬‬
‫‪.4‬‬
‫‪.5‬‬
‫לא ניתן לתת שם למשתנה )או פונקציה וכדומה( המכילים‪:‬‬
‫א‪ .‬התחלה בספרה‪.‬‬
‫ב‪ .‬המכילים את התווים‪– ! # :‬‬
‫ג‪ .‬מילה שמורה )כגון ‪.(if , while‬‬
‫רצוי לתת שם בעל משמעות )גם לפונקציה(‪.‬‬
‫יש הבדל בין אות גדולה לאות קטנה‪ .‬נהוג לרשום רק באותיות קטנות‪.‬‬
‫ניתן לאתחל את ערך המשתנה‪ ,‬כאשר מצהירים עליו‪.‬‬
‫נתונים שידוע שלא ישתנו במהלך התוכנית‪ ,‬ניתן לשמור אותם בתור קבועים‪:‬‬
‫;‪const int age = 65‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪3‬‬
‫פעולות חשבוניות ולוגיות‬
‫‪‬‬
‫סדר הפעולות‪ ,‬כמו במתמטיקה )סוגרים ‪ ‬כפל‪/‬חילוק ‪ ‬חיבור‪/‬חיסור(‪.‬‬
‫‪7‬‬
‫‪567‬‬
‫‪19‬‬
‫‪‬‬
‫;‪num= 70-7*9‬‬
‫;‪num= (70-7)*9‬‬
‫;‪num= (70-7)-5*9+1‬‬
‫ככל שהמספר יהיה מדיוק יותר‪ ,‬כך התוצאה תהיה באותו דיוק‪.‬‬
‫‪7+2=9‬‬
‫‪7+2.0=9.0‬‬
‫‪7*2=14‬‬
‫‪7*2.0=14.0‬‬
‫הפעולות‬
‫‪.1‬‬
‫‪.2‬‬
‫‪.3‬‬
‫‪.4‬‬
‫‪.5‬‬
‫‪.6‬‬
‫‪.7‬‬
‫סוגרים‪( ) :‬‬
‫השמה‪= :‬‬
‫חיבור‪+ :‬‬
‫חיסור‪- :‬‬
‫כפל‪* :‬‬
‫חילוק‪/ :‬‬
‫חילוק שארית)מודלו(‪% :‬‬
‫קיצורים‬
‫‪ .1‬הורדה‪ /‬הוספה‪:‬‬
‫א‪ .‬שימוש במשתנה ‪ ‬והפעולה עליו‪n++ :‬‬
‫ב‪ .‬פעולה עליו ‪ ‬ושימוש במשתנה‪++n :‬‬
‫‪Y‬‬
‫‪8‬‬
‫‪9‬‬
‫‪X‬‬
‫‪9‬‬
‫‪9‬‬
‫שורת קוד‬
‫;‪x=8‬‬
‫; ‪y = x++‬‬
‫;‪x=8‬‬
‫; ‪y = ++x‬‬
‫‪ .2‬יתבצעו על הפעולות החשבוניות‪) :‬לדוגמא(‬
‫;‪a=a+2;  a+=2‬‬
‫;‪a=a*2;  a*=2‬‬
‫;‪a=a%2;  a%=2‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪4‬‬
‫ביטויים לוגים‬
‫ישנם מספר פעולות הנמצאות בין שני ביטויים המביעות טענה מסוימת‪:‬‬
‫א‪.‬‬
‫ב‪.‬‬
‫‪5<3‬‬
‫‪5>3‬‬
‫הטענה יכולה להיות אמת‪.TRUE -‬‬
‫או שקר‪.FALSE -‬‬
‫הפעולות‪:‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫קטן מ‬
‫גדול מ‬
‫שווה ל‬
‫קטן או שווה ל‬
‫גדול או שוווה ל‬
‫שונה מ‬
‫>‬
‫<‬
‫==‬
‫=>‬
‫=<‬
‫=!‬
‫לאחר שהגענו לטענות מסוימות‪ ,‬ניתן לבדוק את היחס בין הטענות האלו‪.‬‬
‫לשם כך ישנם שלושה פעולות לוגיות‪:‬‬
‫א‪.‬‬
‫ב‪.‬‬
‫ג‪.‬‬
‫וגם‪ -‬בודקת שטענת אמת מתקיימת בכל‪.‬‬
‫או‪ -‬בודקת שטענת אמת מתקיימת לפחות באחד‪.‬‬
‫שלילה )היפוך(‪ -‬הופכת טענת אמת לשקר‪ /‬וטענת שקר לאמת‪.‬‬
‫הפעולות‪:‬‬
‫© ‪Netanel Greenberger‬‬
‫‪!a‬‬
‫היפוך‬
‫‪a||b‬‬
‫או‬
‫‪a&&b‬‬
‫וגם‬
‫‪b‬‬
‫‪a‬‬
‫‪1‬‬
‫‪0‬‬
‫‪0‬‬
‫‪0‬‬
‫‪0‬‬
‫‪1‬‬
‫‪1‬‬
‫‪0‬‬
‫‪1‬‬
‫‪0‬‬
‫‪0‬‬
‫‪1‬‬
‫‪0‬‬
‫‪0‬‬
‫‪1‬‬
‫‪0‬‬
‫‪1‬‬
‫‪1‬‬
‫‪1‬‬
‫‪1‬‬
‫עמוד ‪5‬‬
‫קלט‪ /‬פלט‬
‫ישנם שני פונקציות הנמצאות בספריה >‪ ,<stdio.h‬תפקידם הוא לקלוט ולהדפיס נתונים לתוכנית ומהתכונית‪.‬‬
‫כל פונקציה מקבלת‪:‬‬
‫א‪.‬‬
‫ב‪.‬‬
‫פורמט הדפסה‪ /‬קליטה‪.‬‬
‫הערך עצמו‪.‬‬
‫קלט‬
‫;)‪Scanf("%d",&num‬‬
‫פונקצית הקלט מקבלת שני ערכים‪:‬‬
‫א‪.‬‬
‫ב‪.‬‬
‫פורמט קליטה‪ -‬כלומר באיזה צורה הנתונים יקלטו לתוך המשתנה‪.‬‬
‫המצביע למשתנה‪.‬‬
‫פלט‬
‫;)‪Printf("%d",num‬‬
‫פונקצית הפלט מקבלת שני ערכים‪:‬‬
‫א‪.‬‬
‫פורמט הדפסה‪ -‬כלומר באיזה צורה הנתונים יודפסו על המסך‪.‬‬
‫הנתונים יודפסו בצורה של תווים‬
‫הנתונים יודפסו בצורה של מספרים‪ ,‬כלומר מספר אסקיי של התו‬
‫ב‪.‬‬
‫;‪char tav‬‬
‫;)‪scanf("%c",&tav‬‬
‫;)‪printf("%c\n",tav‬‬
‫;)‪printf("%d\n",tav‬‬
‫המשתנה‪.‬‬
‫פורמט הדפסה‪ /‬קליטה‬
‫מייצג‬
‫פורמט‬
‫הערות‬
‫‪ %d‬מספר שלם )‪(int‬‬
‫‪ %c‬תו‬
‫‪%f‬‬
‫‪%e‬‬
‫‪%g‬‬
‫‪%lf‬‬
‫מספר ממשי )‪(double/float‬‬
‫מספר ממשי )‪(double/float‬‬
‫מספר ממשי )‪(double/float‬‬
‫מספר ממשי )‪(double/float‬‬
‫הצגה עשרונית‬
‫הצגה עם מעריך‬
‫הצגה יותר ברורה‬
‫נועד לקליטה ב ‪double‬‬
‫הערות‪:‬‬
‫ניתן להדפיס ולקלוט מספר משתנים בפונקציה אחת‪.‬‬
‫בהדפסה ניתן לבצע את החישוב בתוך הקריאה לפונקציה‪.‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪6‬‬
‫מבנה בסיסי‬
#include <stdio.h>
int main()
{
int num;
Scanf("%d",&num);
Printf("%d",num);
{
#define - ‫השימוש ב‬
.‫ הערך יקבע בתחילת התוכנית‬.‫ שתייצג ערך מסוים‬,‫במהלך התוכנית ניתן לרשום מילה קבועה‬
:‫למשל‬
#define TRUE
#define FALSE
7 ‫עמוד‬
1
0
Netanel Greenberger ©
‫תווים‬
‫קלט‪ /‬פלט‬
‫‪‬‬
‫ישנם שני פונקציות המבצעות קלט ופלט של תו בודד‪.‬‬
‫קליטת תו לתוך משתנה‬
‫הדפסת תו למסך‬
‫;)(‪chgetchar‬‬
‫;)‪putchar(ch‬‬
‫תווים מיוחדים‬
‫ירידת שורה‬
‫מעבר טאב‬
‫קפיצת תווים בשורה באורך המספר המצוין‬
‫© ‪Netanel Greenberger‬‬
‫ ‪\n‬‬‫‪\t‬‬‫‪%5d-‬‬
‫עמוד ‪8‬‬
‫בקרת זרימה‬
‫בד"כ תוכנית מבצעת את ההוראות‪ ,‬שורה אחר שורה‪.‬‬
‫לפעמים נרצה להתנות שורה‪/‬שורות מסוימות בתנאי‪ ,‬אם התנאי מתקיים התוכנית תבצע את השורה‪ ,‬אם לא‬
‫היא תמשיך לשורה הבאה‪.‬‬
‫משפט ‪if-else‬‬
‫התנאי יופיע בתוך סוגרים‪ ,‬לדוגמא‪(x>y) :‬‬
‫רגיל‬
‫)‪if (x>y‬‬
‫התנאי מתקיים ‪//‬‬
‫{‬
‫הוראה ‪//‬‬
‫}‬
‫‪else‬‬
‫התנאי לא מתקיים ‪//‬‬
‫{‬
‫הוראה ‪//‬‬
‫}‬
‫‪‬‬
‫כאשר יש יותר מהוראה אחת‪ ,‬יש להכניס את ההוראות בסוגרים { }‪.‬‬
‫מקונן‬
‫)‪if (x>y‬‬
‫התנאי מתקיים ‪//‬‬
‫{‬
‫)‪if (a<b‬‬
‫הוראה ‪//‬‬
‫‪else‬‬
‫הוראה ‪//‬‬
‫הוראה ‪if (c==d) //‬‬
‫התנאי לא מתקיים ‪//‬‬
‫}‬
‫‪else‬‬
‫{‬
‫הוראה ‪//‬‬
‫}‬
‫‪‬‬
‫כאשר מופיע ‪ ,else‬הוא מתייחס אל ה ‪ if‬האחרון‪ ,‬אלא אם כן הוא מופיע בתוך סוגרים מסולסלים‬
‫)כמו בדוגמא האחרונה(‪.‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪9‬‬
‫משפט תנאי מקוצר‬
‫ניתן לכתוב משפט תנאי מקוצר‪ ,‬המקביל למשפט ‪.if-else‬‬
‫תחביר‬
‫> במקרה ששקר< ‪> :‬במקרה שאמת< ? >תנאי<‬
‫‪‬‬
‫;)'‪(num>0)? printf("%c\n",'g'):printf("%c\n",'b‬‬
‫> במקרה ששקר< ‪> :‬במקרה שאמת< ? >תנאי והשמה <‬
‫‪‬‬
‫;'‪ch=(num>0)? 'g':'b‬‬
‫משפט ‪switch‬‬
‫ישנם תוכניות המכילות משפטי תנאי רבים‪ ,‬והתוכנית נראת מסובכת וקשה לקריאה‪.‬‬
‫במקרים מסוימים ניתן להמיר את משפטי התנאי למשפט ‪.switch‬‬
‫משפט ‪ switch‬בודק את ערכו של משתנה מסויים ומבצע את ההוראה בהתאם לערכו‪.‬‬
‫דוגמא‬
‫)‪switch (ch‬‬
‫{‬
‫‪case 'a':‬‬
‫;‪re++‬‬
‫;‪break‬‬
‫‪case 'b':‬‬
‫;‪re--‬‬
‫;‪break‬‬
‫‪default:‬‬
‫;‪re=0‬‬
‫}‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫משפט ‪ switch‬יכול לבדוק את ערכו של משתנה שלם‪ /‬תו בלבד‪.‬‬
‫כאשר נמצא ערכו של המשתנה‪ ,‬הוראות ה ‪ switch‬יובצעו מהמקום והלאה‪ ,‬כדי למנוע זאת יש‬
‫להשתמש בהוראת ‪ ,break‬היוצאת מה ‪ ,switch‬לאחר ביצוע ההוראה המבוקשת‪.‬‬
‫אם לא נמצא התאמה ניתן להגדיר ערך ברירת מחדל שיובצע‪.defult -‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪01‬‬
‫לולאות‬
‫לפעמים נרצה לחזור על הוראה מסוימת מספר פעמים‪.‬‬
‫פעמים שנדע את מספר הפעמים שנרצה לחזור‪ ,‬ופעמים שלא נדע ונצטרך להשתמש בתנאי‪.‬‬
‫לשם כך ישנם שלושה סוגי לולאות‪.do while ,while ,for :‬‬
‫משותף לכל הלולאות‪ ,‬שבכל סוג נצטרך לבצע פעולה שתביא אותנו לסיום הלולאה )אחרת היא תהיה לולאה‬
‫אינסופית(‪ .‬ברוב המקרים נצטרך לאתחל את אינדקס הלולאה‪.‬‬
‫‪‬‬
‫‪‬‬
‫אם גוף הלולאה הוא הוראה אחת‪ ,‬אין צריך להכניסו לסוגריים { }‪.‬‬
‫ניתן לבצע לולאות מקוננות‪.‬‬
‫לולאת ‪while‬‬
‫כאשר נרצה לחזור על ביצוע הוראות מסוימות מספר פעמים לא ידוע‪ ,‬נשתמש בלולאת ‪.while‬‬
‫סד"פ לולאה‬
‫דוגמא‬
‫)‪while (re>90‬‬
‫{‬
‫;)‪printf("%d\n",re‬‬
‫;‪re-=10‬‬
‫}‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪00‬‬
‫לולאת ‪do while‬‬
‫כמו לולאת ‪ ,while‬אלא שתנאי הלולאה נמצא לאחר גוף הלולאה‪ .‬כלומר‪ -‬גוף הלולאה יבוצע לפחות פעם‬
‫אחת‪.‬‬
‫דוגמא‪:‬‬
‫‪do‬‬
‫{‬
‫;)‪printf("%d\n",re‬‬
‫;‪re-=10‬‬
‫}‬
‫;)‪while (re>90‬‬
‫לולאת ‪for‬‬
‫כאשר ידוע מראש מספר הפעמים שבו אנו רוצים לחזור על הוראות מסוימות ניתן להשתמש בלולאת ‪.for‬‬
‫מבנה‬
‫)קידום אינדקס ; תנאי ; אתחול אינדקס( ‪for‬‬
‫סד"פ לולאה‬
‫דוגמא‬
‫)‪for (i=0; i<10; i++‬‬
‫{‬
‫;)‪printf("%d",i‬‬
‫}‬
‫‪‬‬
‫ניתן לבצע מספר פקודות אתחול‪ ,‬תנאי‪ ,‬ועדכון‪.‬‬
‫)‪for (i=0 , j=20 ; i<10 , j>10 ; i++ , j--‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪02‬‬
‫‪break & continue‬‬
‫לפעמים נרצה להפסיק‪ /‬לקדם לולאה באמצע פעולתה‪ ,‬בעקבות נתונים מסוימים שהגענו אליהם‪.‬‬
‫‪break‬‬
‫גורמת יציאה מתוך הלולאה הפנימית ביותר‪.‬‬
‫)‪while (re>90‬‬
‫{‬
‫;)‪printf("%d\n",re‬‬
‫;‪if (re %9==0) break‬‬
‫;‪re-=2‬‬
‫}‬
‫‪‬‬
‫פקודה זו עובדת גם במשפט ‪.switch‬‬
‫‪continue‬‬
‫מסיימת את הפעולה הנוכחית‪ ,‬לאחר מכן בודקת את התנאי‪.‬‬
‫)‪while (re>90‬‬
‫{‬
‫;)‪printf("%d\n",re‬‬
‫)‪if (re %9==0‬‬
‫{‬
‫;‪re-=8‬‬
‫;‪continue‬‬
‫}‬
‫;‪re-=2‬‬
‫}‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪03‬‬
‫פונקציות‬
‫תוכנית מורכבת מהוראות )= קוד( רבות‪ ,‬ככל שההוראות רבות יותר נרצה לייעל את התוכנית‪:‬‬
‫‪ .1‬כדי שלא לחזור על הוראות דומות‪.‬‬
‫‪ .2‬כדי להבין מה הולך בתוכנית‪.‬‬
‫לדוגמא‪ ,‬אם נרצה להדפיס למסך‪ ,‬אנו נצטרך לרשום שורות קוד רבות‪ -‬דבר זה הופך את התוכנית‬
‫למסורבלת‪ ,‬במיוחד אם נרצה להדפיס מספר שורות‪ .‬כדי למנוע את הבלגן הזה אנו נשתמש בפונקציה‪.‬‬
‫פונקציה‪ -‬קטע קוד‪ :‬המקבל ערכים‪ ,‬עושה חישובים‪ ,‬ומחזיר תוצאות‪.‬‬
‫כלומר במקום לרשום שורות קוד רבות‪ ,‬נוכל לקרוא בשם של הפונקציה‪ ,‬והיא תבצע את החישובים ותחזיר‬
‫תוצאות‪ ,‬וכל זה בשורות קוד מעטות‪.‬‬
‫מבנה‬
‫>פרמטרים<>שם<>טיפוס משתנה שיחזור לתוכנית הקוראת<‬
‫;)‪double power(int x,int y‬‬
‫פרמטרים‬
‫‪ .1‬הפרמטרים המעוברים לפונקציה‪ ,‬מוכרים אך ורק לאותה פונקציה‪.‬‬
‫‪ .2‬אפשר שלא להעביר פרמטרים לפונקציה‪ ,‬אך יש לרשום ) (‪.‬‬
‫טיפוס משתנה‬
‫‪‬‬
‫אם הפונקציה לא מחזירה ערך‪ ,‬רושמים ‪ void‬במקום טיפוס המשתנה‪.‬‬
‫קריאה והחזרה‬
‫‪‬‬
‫‪‬‬
‫חייבים להעביר לפונקציה את כל הפרמטרים בהתאמה‪.‬‬
‫הקריאה יכולה להתבצע מהפונקציה הראשית ומכל פונקציה אחרת‪.‬‬
‫‪‬‬
‫‪‬‬
‫כאשר הפונקציה מחזירה ערך‪ ,‬זה נעשה ע"י שימוש ב ‪.return‬‬
‫כאשר מגיעים ל ‪ return‬הפונקציה סיימה את תפקידה‪ ,‬למרות שיש עדין שורות קוד באותה פונקציה‪.‬‬
‫;)‪power(num1,num2‬‬
‫;‪return x/y‬‬
‫משתנים‬
‫סוגי משתנים‬
‫‪‬‬
‫‪‬‬
‫מקומיים‪ -‬משתנים המוגדרים בפונקציה‪ ,‬מוכרים רק באותה פונקציה‪.‬‬
‫גלובליים‪ -‬משתנים המוגדרים בתחילת הקובץ‪ ,‬מוכרים בכל הפונקציות‪{ .‬לא מומלץ! עלול לעשות‬
‫בעיות}‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪04‬‬
‫העברת ערכים‬
‫‪‬‬
‫אל הפונקציה עובר הערך של המשתנה‪ -‬העתק שלו‪ ,‬לא המשתנה עצמו‪ .‬כלומר אין שינוי למשתנה‬
‫בפונקציה הקוראת‪.‬‬
‫הכרזה‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫כל פונקציה תרשם לפני הפונקציה הקוראת לה‪.‬‬
‫ניתן לרשום רק את כותר הפונקציה ואת מימוש הפונקציה לרשום בסוף הקובץ‪.‬‬
‫כותר הפונקציה‪//‬‬
‫;) ‪double power(int ,int‬‬
‫מימוש הפונקציה‪//‬‬
‫)‪double power(int x,int y‬‬
‫{‬
‫;‪return x/y‬‬
‫}‬
‫אם התוכנית מורכבת ממספר קבצים‪ ,‬המימוש יופיע בקובץ אחד‪ ,‬וההכרזה בכל קובץ הקורא‬
‫לפונקציה‪.‬‬
‫שימוש בספריה‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫ישנם ספריות רבות בשפת ‪ ,C‬כל ספריה מכילה מספר פונקציות‪.‬‬
‫הספריה הבסיסית ביותר שאנחנו מכירים היא >‪.<stdio.h‬‬
‫הכרזה על שימוש בספריה תעשה בתחילת התוכנית‪:‬‬
‫>שם הספריה< ‪#include‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪05‬‬
‫מערכים‬
‫כאשר יש לנו מספר משתנים שיש בהם מכנה משותף )בד"כ(‪ ,‬נתייחס אליהם בתור משתנה אחד המחולק‬
‫לתאים‪ ,‬וכל תא מכיל ערך מסוים‪.‬‬
‫לדוגמא‪ :‬ציון מבחן של ‪ 10‬סטודנטים‪ ,‬ניתן להגדיר ‪ 10‬משתנים‪ ,‬אבל לא כדאי‪ -‬זה יכול להיות ארוך מאוד‪.‬‬
‫נגדיר מערך המחולק ל ‪ 10‬תאים ובכל תא נכניס את ציינו של סטודנט אחר‪.‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫לכל מערך יש שם וגודל וכמובן סוג טיפוס‪.‬‬
‫כל תא הוא משתנה ללא יוצא מן הכלל‪.‬‬
‫גישה לאיבר במערך היא באמצעות אינדקס‪.‬‬
‫המערך הוא רצף של תאים צמודים בזכרון‪.‬‬
‫מבנה‬
‫>גודל< >שם< >סוג טיפוס<‬
‫הגדרה‬
‫;]‪int arr[3‬‬
‫‪‬‬
‫לא חייבים לציין את מספר אברי המערך‪ ,‬במקרה שרושמים את איבריו ב { }‪.‬‬
‫;}‪int arr[]={1,2,3‬‬
‫‪‬‬
‫‪‬‬
‫גודל המערך חייב להיות מספר קבוע‪ ,‬ולא משתנה‪.‬‬
‫בשורת ההגדרה מגדירים את גודל המערך‪ .‬במהלך התוכנית המספור של התאים מתחיל מתא ‪.0‬‬
‫כלומר‪ ,‬מיקום התא האחרון = גודל המערך ‪1 -‬‬
‫אתחול‬
‫‪‬‬
‫ניתן לאתחל בצורה של { } רק בשורת ההגדרה‪.‬‬
‫‪‬‬
‫‪‬‬
‫הכנסת האיברים למערך תתבצע בהתאמה מהאיבר הראשון‪.‬‬
‫עם האתחול לא מכסה את שאר המערך‪ ,‬בשאר האיברים יוצב ‪.0‬‬
‫;}‪int arr[3]={1,2,3‬‬
‫;}‪int arr[10]={1,2,3‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪06‬‬
‫גישה‬
‫‪‬‬
‫במהלך התוכנית‪ ,‬גישה למערך תעשה לגבי כל תא בנפרד‪ .‬כלומר‪:‬‬
‫‪ o‬אסור לבצע השוואה‪ ,‬קלט‪ ,‬פלט‪ ,‬איפוס של מערך שלם‪ -‬בבת אחת‪ ,‬כגון ‪.arr = 0‬‬
‫‪ o‬אלא‪ ,‬גישה תהיה בד"כ ע"י לולאה‪ ,‬ואינדקס הלולאה ישמש כאינדקס המערך‪.‬‬
‫;]‪int arr[10‬‬
‫;‪for (i=0 ; i<10; i++) arr[i]=0‬‬
‫‪‬‬
‫אסור לחרוג מגבולות המערך‪.‬‬
‫העברת מערך לפונקציה‬
‫‪‬‬
‫‪‬‬
‫מועברת לפונקציה כתובת המערך‪ ,‬כלומר בשינוי ערכו של המערך בפונקציה ישתנה המערך המקורי‪.‬‬
‫כדאי להעביר לפונקציה גם את גודל המערך‪.‬‬
‫;)‪void ini_array(int a[],int size‬‬
‫‪‬‬
‫אין צורך לרשום את גודל המערך בכותר הפונקציה‪.‬‬
‫מערך קבוע‬
‫‪‬‬
‫‪‬‬
‫ניתן בכותר לקבוע שהמערך המועבר לפונקציה יהיה קבוע‪ ,‬ובכך להבטיח שהמערך לא ישתנה‪.‬‬
‫לא ניתן להעביר מערך שהוגדר כקבוע‪ ,‬לפונקציה שבה הוא לא קבוע‪.‬‬
‫;)‪void print_array(const int a[],int size‬‬
‫מערכים רב‪ -‬מימדים‬
‫מייצגים מטריצות )טבלאות(‪ ,‬או מימדים גבוהים יותר‪.‬‬
‫מיוצגים ע"י שני אינדקסים )או יותר(‪.‬‬
‫ההגדרה‪ ,‬האיתחול והגישה אליו נשארים אותו דבר‪ -‬רק עם שינוי קטן של הוספת אינדקס נוסף‪.‬‬
‫‪‬‬
‫‪‬‬
‫במערך דו‪-‬מימדי‪ ,‬האינדקס הראשון מייצג שורה‪ ,‬והאינדקס השני מייצג עמודה‪.‬‬
‫בהעברת מערך רב מימדי לפונקציה צריך לציין את גודל המימד השני והלאה‪.‬‬
‫;)‪void print_array(int a[][20],int size‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪07‬‬
‫מחרוזות‬
‫מחרוזת היא מערך של תווים‪.‬‬
‫ישנם פקודות ופונקציות בשפת ‪ C‬שעוזרות לנו לעבוד עם מחרוזות בצורה פשוטה יותר‪.‬‬
‫‪‬‬
‫בכל סוף מחרוזת‪ ,‬יופיע תו סיום מחרוזת‪.'\0' -‬‬
‫אתחול‬
‫‪‬‬
‫ניתן לאתחל מערך תווים בהגדרה עם גרשיים כפולים " "‪ ,‬סימון סוף מחרוזת יוכנס אוטומטית‪.‬‬
‫;"‪char str[]="Hellow‬‬
‫קלט‪ /‬פלט‬
‫קלט‬
‫ניתן לקלוט בדרך הרגילה‪ ,‬הכנסת איברים למערך ע"י ‪ scanf‬או ע"י )(‪.getchar‬‬
‫במקום ניתן לקלוט כך‪:‬‬
‫;)‪scanf("%s",str‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫הקלט יהיה עד רווח או ירידת שורה‪.‬‬
‫סימון סוף מחרוזת יוכנס אוטומטית‪.‬‬
‫אם נרצה להגביל את מספר התווים שיכולים להקלט נכתוב כך‪:‬‬
‫;)‪scanf("%15s",str‬‬
‫‪ ‬ישנה עוד פקודת קלט‪ , gets (str); -‬הקולטת מחרוזת שלמה‪ .‬חסרון‪ :‬לא ניתן להגביל את מספר‬
‫התווים שיקלטו‪.‬‬
‫פלט‬
‫כמו בקלט ישנו קיצור‪ ,‬וניתן לכתוב כך‪:‬‬
‫;)‪printf ("%s",str‬‬
‫‪ ‬ההדפסה עצמה תתבצע עד להגעה לתו סיום מחרוזת‪.‬‬
‫‪ ‬ישנה עוד פקודת פלט‪ , puts (str); -‬המדפיסה עד לתו סיום מחרוזת‪ ,‬ויורדת שורה‪.‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪08‬‬
‫שימוש במחרוזות‬
‫כמו שבמערכים לא ניתן לבצע פעולות על מערך שלם בבת אחת‪ ,‬כך גם במחרוזות‪.‬‬
‫לשם כך נבנתה ספריה >‪<string.h‬‬
‫המכילה פונקציות לעבודה עם מחרוזות‪.‬‬
‫פונקציות מרכזיות‪:‬‬
‫‪.1‬‬
‫‪.2‬‬
‫‪.3‬‬
‫‪.4‬‬
‫‪.5‬‬
‫‪.6‬‬
‫‪ -Strlen‬מקבלת מחרוזת‪ ,‬מחזירה את אורך המחרוזת‪.‬‬
‫‪ -Strcmp‬מקבלת שני מחרוזות‪ ,‬מחזירה ‪ 0‬כאשר הם זהות לחלוטין‪ ,‬מספר חיובי כאשר הראשונה‬
‫גדולה יותר )ע"פ סדר הא"ב(‪ ,‬מספר שלילי כאשר השנייה גדולה יותר‪.‬‬
‫‪ -Strcpy‬מקבלת מחרוזת מקור‪ ,‬ומחרוזת יעד‪ ,‬מעתיקה את המחרוזת מקור ליעד‪.‬‬
‫‪ -Strcat‬מקבלת שני מחרוזות‪ ,‬משרשרת את השנייה לסוף של הראשונה‪.‬‬
‫‪ -Strchr‬מקבלת תו ומחרוזת‪ ,‬מחזירה את מיקמו הראשון של התו במחרוזת‪.‬‬
‫‪ -Strstr‬מקבלת שני מחרוזות‪ ,‬מחפשת את ההופעה )הראשונה( של המחרוזת השנייה בראשונה‪.‬‬
‫ישנה עוד ספריה <‪ >ctype.h‬העובדת על תווים בודדים‪.‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪09‬‬
‫מצביעים‪pointer -‬‬
‫לכל כתובת‪/‬משתנה בזכרון יש כתובת וערך‪.‬‬
‫בשפת ‪ C‬ניתן לתת שם נורמאלי לאותם כתובות בפונקציה מסוימת‪ ,‬ולהכניס בהם ערכים‪ ,‬לדוגמא‪x=4; :‬‬
‫עד עכשיו עבדנו כך‪ ,‬עכשיו נראה שאפשר לגשת גם לכתובות ולערכים ישר‪.‬‬
‫גישה לכתובת‬
‫אל הכתובת ניגשים ע"י הסימן & לפני שם המשתנה‪.‬‬
‫‪ ‬לא ניתן לשנות כתובת של משתנה!‬
‫‪ ‬לא קיים כתובת לקבועים וביטויים‪.‬‬
‫גישה לערך‬
‫כאשר נתונה לנו כתובת בזכרון ניתן להכניס לתוכה ערך‪ ,‬ע"י הסימן *‪.‬‬
‫‪ ‬מסוכן לשנות את ערכו של כתובת בזכרון‪ ,‬כאשר הוא אינו מוכר לנו‪ .‬לדוגמא‪:‬‬
‫;‪*(37693)= 700‬‬
‫משתנה מסוג מצביע‬
‫למשתנה מסוג רגיל שהכרנו עד עכשיו‪ ,‬יש שני פרמטרים‪ -‬סוג וערך‪.‬‬
‫למשתנה מסוג מצביע‪ ,‬יש שני פרמטרים‪ -‬סוג וערך של כתובת‪.‬‬
‫הצהרה‬
‫;‪int *num‬‬
‫שימוש במשתנה‬
‫קבלת כתובת‪-‬‬
‫;‪num=&i‬‬
‫שימוש בכתובת‪-‬‬
‫;‪*num=5‬‬
‫כאשר משתנה‪-‬מצביע‪ ,‬לא מצביע לשום מקום‪ ,‬נגדיר שהוא מצביע לריק‪.‬‬
‫;‪int *num=NULL‬‬
‫קידוד הדפסה של כתובת בזכרון הוא באמצעות ‪%p‬‬
‫;)‪printf("%p",&i‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪21‬‬
‫מצביעים ופונקציות‬
‫‪‬‬
‫‪‬‬
‫פונקציה יכולה להחזיר ערך מסוג מצביע‪.‬‬
‫אבל‪ ,‬אין להחזיר מצביע של משתנה מקומי בתוך הפונקציה‪ ,‬כי בסיום הפונקציה הוא נמחק‪.‬‬
‫מצביעים ומערכים‬
‫מערך בזכרון מורכב מתאים הצמודים זה לזה‪.‬‬
‫שם המערך הוא בעצם המצביע לאיבר הראשון במערך‪.‬‬
‫מצביע למערך הוא בעצם הכתובות לתא הראשון במערך‪) .‬דוגמאות שוקלות(‬
‫;‪arr_p= arr‬‬
‫;]‪arr_p= &arr[0‬‬
‫גישה לאיברי המערך‬
‫;)]‪1. printf("%d",arr[i‬‬
‫;))‪2. printf("%d",*(arr+i‬‬
‫‪ ‬תזכורת‪ :‬שמעבירים מערך לפונקציה‪ ,‬מה שמעובר זה כתובת התא הראשון במערך‪.‬‬
‫כותר פונקציה‪ ,‬שמועבר אילה מערך‪:‬‬
‫;)‪void ini_arr(int *a‬‬
‫© ‪Netanel Greenberger‬‬
‫עמוד ‪20‬‬