C (שפת תכנות)
| C | |
|---|---|
|
כריכת המהדורה השנייה של הספר The C Programming Language, התואמת את תקן ANSI של השפה |
|
| פרדיגמות | תכנות אימפרטיבי, תכנות פרוצדורלי, תכנות מובנה |
| הופיעה ב | 1972 |
| תוכננה על ידי | דניס ריצ'י |
| פותחה על ידי | דניס ריצ'י במעבדות בל |
| גרסה אחרונה | C11 (דצמבר 2011) |
| טיפוסיות | סטטית, חלשה, מפורשת |
| מימושים | Clang, GCC, Intel C, MSVC, Turbo C, Watcom C |
| ניבים | Cyclone, Unified Parallel C, Split-C, Cilk, C* |
| הושפעה על ידי | B (BCPL, CPL), ALGOL 68, Assembly, PL/I, FORTRAN |
| השפיעה על | מספר רב של שפות: AMPL, AWK, csh, C++, C--, C#, Objective-C, BitC, D, Go, Java, JavaScript, Limbo, LPC, Perl, PHP, Pike, Processing |
| סיומת | .h, .c |
שפת C היא שפת תכנות פרוצדורלית. זוהי שפה עילית הכוללת בקרת זרימה ומבני נתונים, ועם זאת היא מאפשרת ניצול מרבי של יכולות המחשב, בדומה לשפת סף. C היא אחת השפות היעילות והמהירות בתעשייה, והיא השפיעה על שפות תכנות רבות, ובמיוחד על C++, שנכתבה בתחילה כהרחבה של C.
תוכן עניינים |
[עריכה] מאפייני שפת C
שפת C תוכננה לראשונה בין השנים 1969 ל-1973 על ידי דניס ריצ'י במעבדות בל על מערכות UNIX שרצו על מחשבי PDP-11. הצורך בשפה עלה לשם כתיבת מערכת הפעלה. באותה עת הייתה קיימת שפת ה-B, ובאמצעותה נכתבה שפת C בתחילה. כאשר התפתחה שפת C, הגיעה למצב בו המהדר בו מהדרים את השפה כתוב אף הוא בשפת C עצמה, תהליך הנקרא Bootstrapping. מקור השם של השפה הוא באותה שפת B, תוך התקדמות אות אחת באלפבית, או האות הבאה אחרי B בשמה של BCPL.
רוב הגרעין (Kernel) של מערכת ההפעלה לינוקס כתוב ב-C, כמו גם הרבה תוכנות אחרות המהוות את מערכת ההפעלה GNU/Linux.
סביבות עבודה לשפת C כיום כוללות מהדר, כלי לניפוי שגיאות (מציאת תקלות, באגים), וכן אפשרות לערוך את הקוד בחבילת תוכנה אחת.
עיקרון מנחה בשפה הוא עקרון היעילות, ובכך היא מצטיינת. כל פעולה בשפה מתבטאת בפעולה בודדת או במספר מועט של פעולות בשפת סף. משום כך אין בה סוגי מבנים מורכבים כגון מחרוזות או בדיקות סמויות בגישה למערכים ומערכת הטיפוסים שלה לא בטוחה. מסיבה זו היא גם כוללת לא מעט אפשרויות לשגיאות שהמהדר (Compiler) לא יאתר, כגון פנייה לאיבר שלא קיים במערך או פנייה לערך לא חוקי בזיכרון וכדומה. הנחת העבודה של מתכנני השפה (והתקנים המאוחרים יותר) היא כי "המתכנת מבין מה הוא עושה".
[עריכה] תקנים
שפת C היא שפה בעלת תקן פתוח המנוהל על ידי ANSI ו-ISO. העדכון האחרון לתקן נעשה בשנת 2011, ונקרא בפי משתמשי השפה "C11". התקן הראשון לשפה הונהג על ידי ANSI ב-1989 (נהוג להתייחס אליו כ-"ANSI C" או "C89") ואומץ על ידי ISO ב-1990 (בשינוים מינוריים, ולתקן הזה מתייחסים כ-"C90"). מספר התקן לשפת C ב-ISO הוא 9899. ממציאי השפה, דניס ריצ'י ובריאן קרניגן, כתבו את הספר "The C Programming Lanuage" המתעד את השפה ומהווה תקן נוסף, ראשון ולא רשמי, לשפה. מתייחסים לתקן הזה לפעמים כ-"K&R" על פי האותיות הראשונות של שמות המשפחה של מחבריו. מהדורה שנייה של הספר מתייחסת לתקן C89.
[עריכה] מושגים בתכנות ומימושם בשפת C
כאמור, הייחוד של השפה הוא הפשטות והיעילות שבה, והדבר מתבטא בין השאר גם באופן מימושם של המושגים הבסיסיים בתכנות.
[עריכה] משתנים
- משתנה - כינוי לחלק זיכרון שמכיל מידע מסוים. למשל אם מוגדר משתנה מטיפוס מספר שלם (Integer) בשם x אז x יהיה כינוי למספר שאת ערכו תוכל התוכנית לשנות או לקרוא.
- לדוגמה, הגדרת משתנה מסוג int, המייצג מספר שלם בגודל 16 ביט לכל הפחות:
int x;
- מצביע - משתנה המכיל כתובת בזיכרון המחשב - כתובת של משתנה או של פונקציה. משמש בין היתר ליצירה של מבני נתונים דינמיים.
- לדוגמה, מצביע למשתנה מסוג short, שהוא משתנה המייצג מספר שלם:
short *x;
- דגל - טיפוס נתונים המכיל אחד משני ערכים המציינים קיומו או סתירתו של תנאי. בתקן השפה C99 נוסף טיפוס בוליאני מיוחד הקרוי _Bool. במקרה ואין בעיות תאימות לקוד ישן, ניתן להשתמש בסיפרייה <stdbool.h> על מנת להשתמש בשם המקובל bool.
- אתחול משתנה - מתן ערך התחלתי למשתנה. לעתים (בעיקר בזמן דיבאג) המהדר נותן ערך התחלתי למשתנים, ולעתים לא, תלוי בסוג המשתנה (לפי התקן, משתנים סטטיים וגלובאליים מאופסים על ידי המהדר, משתנים מקומיים שמוקצים על המחסנית - לא). אם לא ניתן ערך התחלתי על ידי המהדר, הערך התחלתי של המשתנה הוא נתון אקראי או נתון סתמי (ערך התחלתי כזה מכונה לעתים זבל והוא מכיל את מה שהכיל האזור הזה בזיכרון לפני היווצרות המשתנה), על כן אין להסתמך על כך שערכו ההתחלתי של משתנה מספרי יהיה אפס. הנחה כזו היא שגיאה נפוצה אצל מתחילים.
- לדוגמה, איתחול משתנה מסוג char, המייצג תו בייצוג כלשהו:
char ch = 'a';
- מערך - אוסף של משתנים המסודרים ברצף בזיכרון. גם כאן, באה לידי ביטוי החסכוניות שבשפה, בה ניתן לרוב להתייחס למערך כאילו הוא מצביע קבוע אל האיבר הראשון שלו. כך פונקציה הצריכה מערך כפרמטר, תבקש מצביע; אם יועבר עליה מערך הוא "ידעך" ויועבר כמצביע. מספרו הסידורי של התא הראשון במערך בשפת C הוא 0, ולכן האיבר האחרון במערך a בן חמישה איברים יהיה [a[4 (גישה לאיבר מתבצעת על ידי רישום מספרו בתוך סוגריים מרובעים. [a[4 שקול בשפה ל(a + 4)*, כאשר a יכול להיות מצביע או מערך).
- לדוגמה, הגדרת מערך של מספרים מסוג נקודה צפה (float):
float n[5];
- לחלופין, ניתן להגדיר מערך על ידי איתחול ערכיו. נגדיר מערך של מספרים מסוג double, המייצג מספר נקודה צפה בן שמונה בתים (דיוק כפול):
double n[] = {3.14, 2.71, 0.8, 5, 32};
- רשומה (מכונה גם מבנה) - קבוצה של משתנים, שניתן להגדירם בבת אחת ותחת שם זהה, כאשר כל אחד מהמשתנים הוא עצמאי. בניגוד למערך, לא כל המשתנים צריכים להיות מאותו הסוג. רשומה מאפשרת לאחד מספר משתנים העוסקים באותו פריט מידע לתוך משתנה יחיד.
חשוב לציין, כי ב C אין משמעות למבנה בפני עצמו, אלא רק כסימון (tag) המאחד טכנית את המשתנים הכלולים בו. ולכן אין מובן לשם המבנה בפני עצמו, אלא רק בתוספת המילה השמורה struct.
- לדוגמה, רשומה (או מבנה) המתארת שם וגיל של אדם. היא מכילה שני שדות:
struct person { char *name; int age; }; struct person yossi;
אפשרות נוספת היא להשתמש במילה שמורה typedef הנותנת שם חדש לטיפוס. למשל:
typedef struct person tPerson; tPerson moshe;
מגדיר משתנה בשם moshe מהסוג struct person.
- מחרוזת - מיוצגת בשפת C כמערך של תווים המסתיים בתו '0\'. הטיפול במחרוזת נעשה על ידי פונקציות של הספרייה התקנית.
- לדוגמה, המחרוזת:
char name[] = "John";
- הזהה מבחינת תוכנה למערך:
char name[] = {'J', 'o', 'h', 'n', '\0'};
[עריכה] מבני בקרה
- לולאה - מבנה בקרה שמאפשר חזרה על אותו קוד ברצף מספר פעמים. ב־C נהוגים שלושה סוגי לולאות: לולאות while שמבוססות על בדיקת תנאי להמשך הלולאה לפני ביצוע הקוד, לולאות do-while שדומות ללולאות while רק שהתנאי נבדק ביציאה, ולולאות for, שבנוסף לבדיקת התנאי גם משלבות בצורה טבעית משתני עזר שיפקחו על ריצת הלולאה (למשל, ספירת מספר הפעמים שהלולאה חזרה על עצמה).
- לולאת for:
int i; for (i=0; i < 5; i++) { /*your code here... */ }
- לולאת while עם בקרה בכניסה:
while (/*some boolean condition*/) { /*your code here... */ }
- לולאת do-while עם בקרה ביציאה:
do { /*your code here... */ } while (/*some boolean condition*/);
[עריכה] פונקציות
- פונקציה - המבנה הבסיסי של השפה שבו יכולות להתבצע פקודות ומבני בקרה. אוסף של פקודות (אלגוריתם) שיכול (אך לא חייב) לקבל ערכים כקלט ולהחזיר משתנה יחיד כפלט. שינוי בערכי משתני הקלט בפונקציה לא ישפיע על ערכיהם בחלקים אחרים בתוכנית, אלא אם מדובר במשתנים מיוחדים שהוגדרו מראש כגלובליים, או לחלופין, אם הערך שהועבר לפונקציה לא היה ערך של משתנה, אלא ערך של המיקום בזיכרון שבו נמצא המשתנה, כלומר מצביע.
- לדוגמה, פונקציה המקבלת שני מספרים ומצביע למקום בזיכרון, מחזירה את הפרשם, ושמה במקום שבזיכרון את סכומם:
int add(int a, int b, int *sum) { *sum = a + b; return a - b; }
[עריכה] מודולים
- מודול - יחידה עצמאית של תוכנה (או חומרה). למשל: טיפול במדפסת נעשה על ידי מודול למדפסת אשר לא כולל דבר בנוסף למדפסת וטיפולה. כל מודול מקומפל בנפרד אולם הם כולם יוצרים קשר אחד עם השני, בשפת C הקשר נוצר על ידי קובצי h. שמכילים את ההגדרות של המודולים האחרים. בכל תוכנה יש מודול אחד ראשי שמכיל את הפונקציה main שבה מתחילה התוכנית.
- ספריה - אוסף של פקודות המאוגדות יחד במקום אחד המאפשר לנו להשתמש בהן ללא צורך לכתיבתן מחדש. בשפת C יש צורך לבצע פקודת include# לקובץ שמכיל את ההגדרה של הספרייה בשביל להשתמש בה.
- לדוגמה, הכללת הספרייה string, המכילה פונקציות לטיפול במחרוזות:
#include <string.h>
- לפני תרגום התוכנית לשפת מכונה, תוכנית הנקראת "קדם מעבד" (pre-processor) יוצרת קובץ חדש הכולל בנקודה בה מוכרזת ההכללה את תוכן הקובץ המוכלל, ואז מועבר הקובץ להידור לשפת מכונה.
- ספריות סטנדרטיות - שפת C היא בעיקרון שפה מינימאלית. היא אינה מכילה פקודות הקושרות אותה למערכת הפעלה מסוימת או לתחום תוכנה מסוים. מסיבה זו, פקודות ספציפיות שכאלה (למשל לקלט ופלט, לחישובים מתמטיים, לעבודה עם מחרוזות ולהקצאות זיכרון דינמיות) נמצאות בספריות סטנדרטיות, שאינן חלק מתחביר השפה אך עונות לקונבנציה מוכרת וקבועה ומהוות חלק מהתקן הרשמי שלה. ספריות אלה מסופקות עם המהדר עבור מערכת הפעלה וחומרה מסוימות והתוכנה מקושרת (linked) עימן על פי צורך והגדרת כותב הקוד.
[עריכה] שונות
- סוגי קבצים - קובץ טקסט וקובץ בינארי. קובץ טקסט יכול לעלות על ידי כל מעבד תמלילים. קובץ בינארי לעומתו מכיל ייצוגים של נתונים וכדומה ואינו מיועד לקריאה על ידי כל מעבד תמלילים. הגישה השונה מתבצעת על ידי קריאה לפונקציות ספריה שונות.
- גישה לקובץ - גישה לקובץ נעשית לרוב על ידי חוצץ הנוטל בכל פעם קטע נתונים מהקובץ. המיקום של החוצץ ניתן על ידי המצביע לקובץ. ב־C ישנה אפשרות לעקוף את החוצץ אולם היא בשימוש רק בתוכנות המפעילות גישה ברמה נמוכה (מערכות הפעלה למשל).
- הערה - שימוש בשפה המדוברת להסברת שלבי התוכנית. אינו משפיע על ריצת התוכנית עצמה, אך הכרחי להבנתה בידי מתכנתים אחרים או בזמן מאוחר יותר. (מופיע בין התווים /* */). ראו דוגמאות למעלה. בתקן C99 נוספה האפשרות לסמן הערה של שורה אחת על ידי // (שני לוכסנים סמוכים).
- שגיאת ריצה - תקלה הנגרמת על ידי התוכנית בזמן הרצתה. למשל: חלוקה באפס, כתיבה לאזור שמור בזיכרון.
[עריכה] "Hello World" בשפת C
תוכנית פשוטה זו מדפיסה את המחרוזת "!Hello, World" לפלט הסטנדרטי.
#include <stdio.h> int main(void) { printf("Hello, World!\n"); return 0; }
[עריכה] ראו גם
[עריכה] לקריאה נוספת
- Brian Kernighan, Dennis Ritchie, The C Programming Language
- 1st, Prentice Hall 1978; ISBN 0-13-110163-3. Pre-ANSI C.
- 2nd, Prentice Hall 1988; ISBN 0-13-110362-8. ANSI C.
- ISO/IEC 9899. The official C:1999 standard, along with technical corrigenda and a rationale. As of 2005 the latest version is ISO/IEC 9899:TC2.
- Peter van der Linden, Expert C Programming.
[עריכה] קישורים חיצוניים
- מילים לזכרו של דניס ריצ'י ועל שפת C "שפת התיכנות המשפיעה ביותר, ובהרבה, בהיסטוריה" (באנגלית)
| מיזמי קרן ויקימדיה |
|---|
- The Development of the C Language
- קצת על ההסטוריה של C - מתוך קורס שניתן באוניברסיטה העברית