שפת C/פונקציות: הבדלים בין גרסאות בדף

תוכן שנמחק תוכן שנוסף
שורה 196:
</source>
 
בדיקה
==מעט על פונקציות והנדסת תוכנה==
 
שפת C משמשת לכתיבת תוכנות מסובכות מאד. הקוד של [[w:לינוקס (ליבה)|ליבת לינוקס]], לדוגמה, מורכב ממיליוני שורות קוד. בשפת C מתמודדים עם מורכבות זו בעזרת חלוקת הקוד לפונקציות (וכן, במידה מסויימת, על ידי חלוקה ל[[שפת C/מודולים|מודולים]]). תכנות טוב מבוסס על חלוקת כל תוכנית למספר פונקציות, כך שלכל אחת מטרה מוגדרת אחת. כאשר פונקציה עושה יותר מדי פעולות, או כאשר קטעי קוד חוזרים על עצמם בפונקציות שונות, מחלקים את הקוד לפונקציות קטנות יותר. בצורה זו ניתן לפשט תוכנית שמבצעת משימות מורכבות לתוכנית שבה כל פונקציה לבדה מבצעת משימה פשוטה, ומורכבות התוכנית נובעת מהבנייה ההדרגתית של פונקציות אחת על השנייה. הייתרונות המושגים על ידי כך:
*הקוד נוח לקריאה וברור.
*קל יותר לשנות או לתקן כל פונקציה בנפרד, כך שאם מתגלה בעיה באחד מחלקי התוכנית מספיק לתקן רק את החלק הזה, מבלי שהדבר ישפיע על שאר חלקי התוכנית.
*הקוד מאפשר שימוש חוזר. אם קטע קוד נבדק ועובד, ואנו צריכים את אותו קטע קוד בחלק אחר של התוכנית, אין צורך לשכפל אותו.
 
נשתמש בקוד שראינו ב[[שפת C/פונקציות#הצורך בפונקציות|צורך בפונקציות]] כדוגמה (למרות שזהו קוד פשוט מאד). ראשית נתבונן בפונקציה main:
<source lang = "c">
#include <stdio.h>
 
 
int main()
{
int c, f;
 
for(c = 0; c <= 40; c += 4)
{
f = 1.8 * c + 32;
printf("%d in Celsius is %d in Fahrenheit\n", c, f);
}
 
printf("Enter degrees in Clesius: ");
scanf("%d", &c);
f = 1.8 * c + 32;
printf("This is %d in Fahrenheit\n", f);
return 0;
}
</source>
ברור למדי שהפונקציה מבצעת שני דברים: מדפיסה טבלת המרות, וממירה שאילתה בודדת. נחלק, לכן, את הקוד לפונקציות:
<source lang = "c">
#include <stdio.h>
 
 
void print_init_conversion_table();
void handle_conversion_query();
 
 
int main()
{
print_init_conversion_table();
handle_conversion_query();
return 0;
}
 
 
void print_init_conversion_table()
{
int c, f;
 
for(c = 0; c <= 40; c += 4)
{
f = 1.8 * c + 32;
printf("%d in Celsius is %d in Fahrenheit\n", c, f);
}
}
 
 
void handle_conversion_query()
{
int c, f;
 
printf("Enter degrees in Clesius: ");
scanf("%d", &c);
f = 1.8 * c + 32;
printf("This is %d in Fahrenheit\n", f);
}
</source>
כעת נשים לב לשורת ההמרות שחוזרת על עצמה (כפי שראינו מקודם), ונהפוך אותה לפונקציה:
<source lang = "c">
#include <stdio.h>
 
 
float celsius_to_fahrenheit(int celsius);
void print_init_conversion_table();
void handle_conversion_query();
 
 
int main()
{
print_init_conversion_table();
handle_conversion_query();
return 0;
}
 
 
void print_init_conversion_table()
{
int c, f;
 
for(c = 0; c <= 40; c += 4)
printf("%d in Celsius is %d in Fahrenheit\n", c, (int)celsius_to_fahrenheit(c));
}
 
 
void handle_conversion_query()
{
int c;
 
printf("Enter degrees in Clesius: ");
scanf("%d", &c);
printf("This is %d in Fahrenheit\n", (int)celsius_to_fahrenheit(c));
}
 
 
float celsius_to_fahrenheit(int celsius)
{
return 1.8 * celsius + 32;
}
</source>
איכות הקוד כעת טובה יותר:
*הקוד חסין יותר מטעויות - צמצמנו את מספר המקומות בהם נצטרך לשנות משהו אם יש טעות בנוסחת ההמרה, לדוגמה.
*הקוד גמיש יותר - קל יהיה לשנות את הקוד אם תגיע דרישה לתוכנית שתעשה משהו אחר, לדוגמה:
**תוכנית ששואלת את המשתמש האם להדפיס טבלת המרה '''או''' לענות על שאילתה
**תוכנית שמדפיסה טבלת המרה, ואז עונה על שאילתות בלולאה עד שהמשתמש מציין שסיים
 
 
 
ב[[שפת C/ניהול זיכרון דינאמי#מעט על מבנים והנדסת תוכנה|מעט על מבנים והנדסת תוכנה]] נדבר עוד על עניינים אלה בהקשר של ''[[שפת C/מבנים|מבנים]]''.
 
{{שפת C|מוגבל}}
 
[[קטגוריה:שפת C|פונקציות]]