מבוא לתכנות ולמדעי המחשב בשפת C/מתמטיקה, הערות ומשפט תנאי.: הבדלים בין גרסאות בדף

תוכן שנמחק תוכן שנוסף
יצירת דף עם התוכן "{{תבנית:ניווט מבוא|2|4}} == שימוש בכלים מתמטיים == עד כה ראינו שימוש באריטמתיקה בסיסית - ארבעת ..."
 
שורה 85:
</syntaxhighlight>
 
== הערות (comments) ==
 
בכל שפת תכנות (לפחות כל אלה ששמעתי אודותם) קיימת אפשרות לכתוב תוכן שהקומפיילר מתעלם ממנו התעלמות מוחלטת. האפשרות הזאת יכולה להראות מוזר בהתחלה אבל יש לה חשיבות רבה. חשוב לזכור שלא רק הקומפיילר קורא את הקוד שאנחנו כותבים. גם אנחנו וגם אנשים נוספים שירצו להבין מה עשינו, להוסיף, לשנות או לתחזק את הקוד.
 
לאנשים חשוב להבין את המשמעות של הדברים שכתובים. חשוב להם להבין מה המטרה, מה תפקיד כל חלק בקוד וכ'. לקומפיילר זה לא חשוב, הוא רק מתרגם את הקוד. גם למחשב המבצע זה לא חשוב, הוא מבצע בלי להבין משמעויות. לאדם הצורך הזה קריטי, אם הוא לא מבין מה קורה בקוד, מה הכוונה, הוא לא יכל לשנות אותו, רק להריץ אותו.
 
ב C יש שתי אפשרויות לכתוב הערות. האחת היא שימוש בסימון /*...*/. סימונים אלה פועלים כמו סוגריים שתוחמים קטע בקובץ ממנו הקומפיילר מתעלם. השניה היא שימוש בסימון // שמאפשר כתיבת הערה החל מהסימון הזה ועד לסיום השורה.
 
הנה דוגמה:
<syntaxhighlight>
#include <stdio.h>
/* This is a very interesting program.
It manages to capture the delicate relationship between
the computer and the user.
*/
int main() {
printf("hello lord\n"); // this is the key point
return 0;
}
 
</syntaxhighlight>
מבחינת התפקוד, תוכנית זו שקולה לתוכנית הראשונה שכתבנו (hello world) אבל היא כוללת הסברים שנועדו לבני אדם והקומפיילר מתעלם מהם.
 
 
שימוש נפוץ נוסף היערות נקרא comment out (ו - uncomment). לפעמים, במהלך הפיתוח אנו מעוניינים לנטרל חלקים מסויימים של הקוד ולראות איך התוכנות מתפקדת בלעדיהם. אנו לא מעוניינים למחוק אותם כי יכל להיות שנשתמש בהם בעתיד.
 
הנה דוגמה:
<syntaxhighlight>
 
 
#include <stdio.h>
/* This is a very interesting program.
It manages to capture the delicate relationship between
the computer and the user.
*/
int main() {
/*
printf("hello lord\n"); // this is the key point
*/
return 0;
}
 
</syntaxhighlight>
במצב זה התוכנית לא מבצעת דבר אבל אפשר בקלות להחזיר אותה למצב הקודם.
 
יש לשים לב שהערה בתוך הערה עלולה לבלבל את הקומפייר, כמו בדוגמה הבאה:
<syntaxhighlight>
#include <stdio.h>
/* This is a very interesting program.
It manages to capture the delicate relationship between
the computer and the user.
*/
int main() {
/*
/* bla bla */ printf("hello lord\n"); // this is the key point
*/
return 0;
}
 
</syntaxhighlight>
 
תוכנית זו לא תעבור קומפילציה מכיוון שכאשר הקומפיילר מוצא את סימן "סגור הערה" הוא סוגר את ההערה החיצונית ולא את הפנימית (אין לו מנגנון של סוגריים מאוזנים). אפשר לראות את הבעיה הזאת גם כאן באמצעות מנגנון הצביעה האוטומטי שבו משתמש הויקי הזה לצבוע את הקוד. שימו לב שסוגר ההערה האחרונה הוא בצבע ירוק ושהקוד לפניו איננו צבוע כהערה.
 
בגלל תופעות כאלה, כדאי לשים לב ולהשתמש בשני סוגי ההערות או להשתמש בסימון // בתחילת כל שורה למטרות comment out (יש עורכי טקסט שתומכים בפעולה).
 
== פקודת תנאי - if ==
כאמור, תוכנית מחשב היא סדרת פקודות שאמורה להביא למטרה רצויה. בכדי שנוכל לכתוב תוכניות מעניינות יש צורך בנקודות התפצלות, נקודות שבהם נשאלת שאלה שמפרידה למקרים כך שבכל מקרה מתרחש משהו אחר. הפקודה שמאפשרת זאת בשפת C היא if (אם). הנה דוגמה פשוטה:
<syntaxhighlight>
 
#include <stdio.h>
 
int main() {
 
printf("Please enter your age: ");
int age;
scanf("%d",&age);
if(age < 13)
printf("Hey, you're just a kid!\n");
else
printf("OK, you are an adult\n");
return 0;
}
 
 
</syntaxhighlight>
הרצה בה המשתמש הקליד 34:
 
<syntaxhighlight lang = "text">
 
Please enter your age: 34
OK, you are an adult
 
</syntaxhighlight>
 
הרצה בה המשתמש הקליד 12:
<syntaxhighlight lang = "text">
 
Please enter your age: 12
Hey, you're just a kid!
 
</syntaxhighlight>
 
===תחביר===
פקודת if יכולה להכתב בשתי דרכים. ללא else:
<syntaxhighlight lang="text" >
if (תנאי)
בלוק קוד
 
</syntaxhighlight>
 
או עם else:
 
<syntaxhighlight lang="text" >
if (תנאי)
בלוק קוד
else
בלוק קוד
 
</syntaxhighlight>
 
'''בלוק קוד''' יכל להיות פקודה בודדת או אוסף פקודות המוקפות בסוגריים מסולסלים.
 
=== קינון (nesting) ===
בכל בלוק קוד אפשר לכתוב כל קוד חוקי ב C. בפרט, ניתן לכתוב פקודות תנאי נוספות. כתיבה כזו נקראת ''קינון'' (nesting). כמו קן בתוך קן.
 
התוכנית הבאה משתמשת בקינון בשביל להבין איזה מספר הוגרל בתחום בין 1 ל 4. לאחר שמצאה את המספר, היא מדפיסה אותו באנגלית.
<syntaxhighlight>
#include <stdio.h>
 
#include <stdlib.h> // required for random() and srand
#include <time.h> // required for time()
 
int main() {
 
srand(time(0)); // initialize the random generator using the time
int n = rand()%4 + 1; // generate a random integer in the range 1..4
printf("In English, %d is ",n);
if(n<=2) {
if(n==1)
printf("One");
else
printf("Two");
}
else {
if(n==3)
printf("Three");
else
printf("Four");
}
printf("\n");
return 0;
}
 
 
</syntaxhighlight>
(בשלב זה אין חשיבות להבין את הפקודות המתועדות. כל תפקידם הוא לדאוג להגרלת מספר שלא חוזרת על עצמה)
 
פלט לדוגמה:
<syntaxhighlight lang = "text" >
In English, 4 is Four
</syntaxhighlight>
 
הרצה נוספת עשויה לתת:
<syntaxhighlight lang = "text" >
In English, 3 is Three
</syntaxhighlight>
 
=== שימוש בפקודת תנאי בשביל לשפר קוד קודם ===
נתבונן שוב בקוד שכתבנו למציאת שורשים של משוואה ריבועית:
 
<syntaxhighlight>
#include <stdio.h>
#include <math.h>
 
int main() {
 
printf("Please enter the three coefficients of a quadratic equation\n(a*x^2+b*x+c=0)\n");
 
double a,b,c;
printf ("a: ");
scanf("%lf",&a);
 
printf ("b: ");
scanf("%lf",&b);
 
printf ("c: ");
scanf("%lf",&c);
 
double d = sqrt(b*b-4*a*c);
printf("x1 = %.2lf, x2 = %.2lf \n",(-b+d)/(2*a),(-b-d)/(2*a));
return 0;
}
 
</syntaxhighlight>
 
האם הקוד הזה עובד נכון עבור כל פלט אפשרי? האם התוכנית שלנו מכילה באגים?
 
מה יקרה אם נכניס את הערכים הבאים: a=1, b=0, c=1?
קלט זה מייצג את המשוואה:
<m>
x^2 + 1 = 0
</m>
 
משוואה ללא פתרונות ממשיים.
אם ננסה להריץ את התוכנית שלנו על קלט כזה, נקבל את הפלט הבא:
 
<syntaxhighlight lang= "text">
 
Please enter the three coefficients of a quadratic equation
(a*x^2+b*x+c=0)
a: 1
b: 0
c: 1
x1 = -nan, x2 = -nan
 
</syntaxhighlight>
 
nan (או nan-) הוא הערך שמקבלים ב C מנסיון לחשב שורש של מספר שלילי (קיצור של not a number). במקרה שלנו, תוצאה של נסיון חישוב שורש ריבועי של 3 שאיננו מספר ממשי.
 
נשנה את הקוד שלנו לבדוק את ערך הדסקמיננטיה ולפעול בהתאם. אם היא שווה ל 0, יש רק פתרון אחד ואם היא שלילית, אין פתרונות ממשיים:
 
<syntaxhighlight>
#include <stdio.h>
#include <math.h>
int main() {
printf("Please enter the three coefficients of a quadratic equation\n(a*x^2+b*x+c=0)\n");
double a,b,c;
printf ("a: ");
scanf("%lf",&a);
printf ("b: ");
scanf("%lf",&b);
printf ("c: ");
scanf("%lf",&c);
double d = b*b-4*a*c;
if (d < 0)
printf ("There are no real solutions to this equation\n");
else
if (d==0)
printf("x = %.2lf \n",-b/(2*a));
else {
d = sqrt(d);
printf("x1 = %.2lf, x2 = %.2lf \n",(-b+d)/(2*a),(-b-d)/(2*a));
}
 
return 0;
}
</syntaxhighlight>
 
'''פלט:'''
<syntaxhighlight lang="text">
Please enter the three coefficients of a quadratic equation
(a*x^2+b*x+c=0)
a: 1
b: 0
c: 1
There are no real solutions to this equation
</syntaxhighlight>
 
<syntaxhighlight lang="text">
Please enter the three coefficients of a quadratic equation
(a*x^2+b*x+c=0)
a: 1
b: 0
c: -1
x1 = 1.00, x2 = -1.00
</syntaxhighlight>
 
 
האם כעת הקוד נקי מבאגים? נסו לחשוב מה קורה כאשר המשתמש מכניס ל a את הערך 0.