הרצאה: פונקציות, מודולים ו־Header Files¶
מבוא¶
עד עכשיו כתבנו את כל הקוד שלנו בקובץ אחד – main.c, והשתמשנו רק בפונקציה אחת – main.
אבל בעולם האמיתי, תוכנה גדולה לא יכולה להיות רק פונקציה אחת.
תכנות נכון דורש חלוקה לפונקציות – כל פונקציה אחראית על פעולה אחת. בנוסף, נרצה לפצל את הקוד לקבצים שונים (מודולים) – כדי שיהיה ברור יותר, קריא יותר, ונוכל לשתף פונקציות בין קבצים.
למה פונקציות?¶
במקום לכתוב שוב ושוב את אותו קוד – אנחנו מגדירים אותו פעם אחת בתוך פונקציה, ואז יכולים לקרוא לה מתי שנרצה.
דוגמה בסיסית:
#include <stdio.h>
void say_hello() {
printf("שלום עולם\n");
}
int main() {
say_hello(); // קריאה לפונקציה
return 0;
}
איך מגדירים פונקציה?¶
דוגמה עם פרמטרים והחזרת ערך:
שימוש:
מודולריות – פיצול לקבצים¶
נגיד שיש לנו הרבה פונקציות של מתמטיקה. לא נרצה שכולן יהיו ב־main.c.
ניצור קובץ חדש: math_utils.c
אבל איך main.c ידע על הפונקציות האלו?
בשביל זה יש header file!
Header Files – קבצי .h¶
הHeader (כמו "כותרת") – מכיל רק את ההצהרות של הפונקציות, בלי מימוש.
ככה נגיד ל־main.c: "היי, יש פונקציות כאלו – תאמין לי, תוכל להשתמש בהן".
שימוש ב־main.c:¶
#include <stdio.h>
#include "math_utils.h" // שים לב: סוגריים כפולים לקובץ משלנו
int main() {
int sum = add(3, 4);
printf("3 + 4 = %d\n", sum);
return 0;
}
איך לקמפל פרויקט עם כמה קבצים?¶
נניח שיש לנו:
-
main.c -
math_utils.c -
math_utils.h
כדי לקמפל, נכתוב את הפקודה הבאה:
או שנקמפל שלב אחרי שלב את קבצי האובייקט ואז נאחד אותם:
gcc -c main.c # יוצר main.o
gcc -c math_utils.c # יוצר math_utils.o
gcc main.o math_utils.o -o program
כתיבת header נכון¶
שימו לב, שכשאתם כותבים קובץ header, חשוב מאוד לשים בתחילת הקובץ header ובסופו 3 הוראות מסוימות:
למעשה, ההוראות האלו מוודאות שאם הקוד עשה פעמיים include לקובץ, הפונקציה לא תוגדר פעמיים.
פעולת הifndef (if not define) בודקת אם הסימבול "MATH_UTILS_H" לא מוגדר, אם זה לא מוגדר- אז היא לא מבצעת את הקוד שכתוב עד "endif" (כל ההגדרות של הפונקציות) ואם לא, אז הוא מגדיר באמצעות פעולת define את הסימבול- ואז מבצע את כל ההגדרות, כך שאם יעשו שוב include לקובץ, הסימבול כבר יוגדר (MATH_UTILS_H בדוגמה למעלה) ואז התנאי יתקיים והקוד לא יורץ (ההגדרות).