שאלות
שאלה 1
כתבו פונקציה המקבלת מצביע למספר ומגדילה את ערכו ב-1.
void inc_by_one(int *n) { (*n)++; }
הביטוי n* הוא המשתנה שנמצא בכתובת שהמצביע n מצביע אליו, ולכן הגדלתו ב-1 ע״י ++ תתן את התוצאה הרצויה.
שאלה 2
כתבו פונקציה שמקבלת מצביעים לשני מספרים. הפונקציה תכתוב לקטן מביניהם את ההפרש בין הגדול לקטן, ולגדול מביניהם את הסכום שלהם.
void q2(int *a, int *b) {
int *small;
int *big;
if (*a < *b) {
small = a;
big = b;
} else {
small = b;
big = a;
}
int sub = *big - *small;
int sum = *big + *small;
*small = sub;
*big = sum;
}
ניתן לראות בשאלה זו כיצד נוח להשתמש במצביעים בתור ״כינוי״ למשתנה אחר, בלי להסתבך עם משתנים זמניים.
שאלה 3
כתבו תוכנית שמקבלת שלושה מספרים עשרוניים a, b, c ושני מצביעים r1, r2. התוכנית תפתור את המשוואה הריבועית המיוצגת ע״י a, b, c ותכתוב את התוצאות למצביעים r1, r2, במידה וקיימים. אם לא קיים פתרון, הפונקציה תחזיר 1- - אחרת, תחזיר 0.
#include <math.h>
#define NO_SOL -1
float calc_discr(float a, float b, float c) { return b * b - 4 * a * c; }
int quad(float a, float b, float c, float *r1, float *r2) {
float discr = calc_discr(a, b, c);
if (discr < 0) {
return NO_SOL;
}
*r1 = (-b + sqrt(discr) / (2 * a));
*r2 = (-b - sqrt(discr) / (2 * a));
}
זו דוגמא לשימוש במצביעים על מנת ״להחזיר״ ערכים מהפונקציה. שיטה זו נקראת output arguments.
שאלה 4
כתבו פונקציה המקבלת מצביעים ל-3 מספרים i1, i2, i3 ומסדרת אותם לפי סדר עולה. כלומר, לאחר הקריאה לפונקציה יתקיים \(i_1 \le i_2 \le i_3\).
void swap(int *a, int *b);
void sort3(int *i1, int *i2, int *i3) {
if (*i1 > *i2) {
swap(i1, i2);
}
if (*i2 > *i3) {
swap(i2, i3);
}
if (*i1 > *i2) {
swap(i1, i2);
}
}
הרעיון בפתרון הוא לבעבע את המספרים הנמוכים כלפי מטה ע״י שימוש ב-swap כפי שהכרנו.