עוד על מצביעים:
- שם מערך הוא למעשה גם מצביע, שמצביע על הבית הראשון של האיבר הראשון במערך.
- כדי להצביע על מערך אפשר לעשות בפשטות (כש p הוא מצביע):
p = &A[0];
אבל אפשר לעשות גם:
.שכן שניהם מצביעים, ואפשר להשוות שני מצביעים- p = A;
- כל ערך שמוסיפים למצביע, ערך זה מייצג את כמות האיברים שרוצים להתקדם, ולא כמות הבתים.
לדוגמה:
אם p הוא מצביע מסוג int שמצביע על האיבר הראשון של המערך A
*p = 13; => A[0] = 13
p++; => p = 1004
*p = 27; => A[1] = 27
p+=2; => p = 1012
*p = 20; => A[3] = 20
לכן הפקודות הבאות זהות (עבור מערך A בעל 10 איברים):
for (p = &A[0] ; p <= &A[9] ; p++)
printf ("%d",*p);
:זהה לפקודה
for (p = A ; p <= A+9 ; p++)
printf ("%d",*p);
וכן קליטת מערך באמצעות מצביע:
for (p = A ; p <= &A[9] ; p++)
scanf ("%d",p); => כי בקלט רגיל תמיד השתמשנו ב & אז במצביע לא צריך
- קיים הבדל אחד ויחיד בין מצביע רגיל (המוגדר ע"י *) ובין שם של מערך:
שם המערך הוא מצביע קבוע, לא ניתן לשנות אותו. מצביע רגיל הוא לא קבוע, כן ניתן לשינוי.
לכן כל הביטויים הבאים מתכוונים לאותו הבית בדיוק (אם A הוא מערך מסוג int ו p הוא מצביע שמצביע על A):
A[0] , *p , *A , p[0]
וכן האיבר השלישי:
A[2] , *(p+2) , p[2]
..............................
אם נתונים:
int A [10] = {19, 27, 35, -5, ..... };
int *p = A , x;
ואם הכתובת של האיבר הראשון של A היא 600
אז נתבונן מה עושה כל פקודה למצב הנתון (הפקודות לא משפיעות אחת על השנייה):
x = *p++; => x=19 , p=604
x = (*p)++; => x=19 , A[0]=20
x = ++*p; => A[0]=20 , x=20
x = ++(*p); => -אותו דבר כמו הפקודה שמעל-
x = *++p => p=604 , x=27
.............................
אם נתונים:
int A [10] = {19, 27, 35, -5, ..... };
int *p , x;
p = &A[3];
x = p-A;
לא משנה מה הכתובת של הבית הראשון, עכשיו x שווה 3 (ולא 12 כמו שהייתי חושב)
זאת משום שהפעולה עובדת בדומה ל ++p שמעלה לאיבר הבא ולא לבית הבא.
דוגמאות בשיעור:
/* #include <stdio.h> #include <math.h> int f(int a, int b, int c, double *p1, double *p2) { double tmp = pow(b,2) - 4*a*c; if(a == 0 || tmp < 0) return 0; if(tmp == 0) { *p1 = -b / (2.0 * a); return 1; } *p1 = (-b + sqrt(tmp)) / (2.0 * a); *p2 = (-b - sqrt(tmp)) / (2.0 * a); return 2; } /// void main() { int a, b, c, k; double x1, x2; printf("Enter a , b & c: "); scanf("%d %d %d",&a, &b, &c); k = f(a, b, c, &x1, &x2); if(k == 0) printf("No Solution\n"); if(k == 1) printf("x1: %.2f\n",x1); if(k == 2) printf("x1: %.2f x2: %.2f\n",x1, x2); } */ ////////////////////////////////////// #include <stdio.h> #define N 10 void main() { int A[N] , *p; for(p=A; p <= &A[9]; p++) scanf("%d",p ); // for(i=0; i<N; i++) // scanf("%d",&A[i]); //for(p=&A[0]; p <= A + 9; p++) for(p=A; p <= &A[9]; p++) printf("%d ==> %d\n",p, *p); }
מצבעים .
1)כתוב פונקציה המקבלת מצביע למחרוזת ותו, הפונקציה מחזירה את מספר
ההופעות של התו במחרוזת.
לדוגמא:
עבור המחרוזת: "abma32a23ma" והתו ‘a’, הפונקציה מחזירה 4.
int find(char *s, char ch);
2)כתוב פונקציה המקבלת מצביע למערך בגודל 10 של מספרים שלמים.
הפונקציה תהפוך את אברי המערך.
לדוגמא:
עבור המערך:
1,2,3,9,5,4,8,-12,6,10
נקבל המערך:
10,6,-12,8,4,5,9,3,2,1
3) כתוב תוכנית המכילה מערך חד ממדי של מספרים ממשיים.
התוכנית מציבה כתובת התחלת מערך זה למצביע, ומוצאת הממוצע, והאיבר הכי
קרוב והכי רחוק מן הממוצע .
לדוגמא: עבור המערך:
1,3,5,6,8,-8,9,-10,2,5
הממוצע הוא 2.1 האיבר הכי קרוב לממוצע הוא 2 והכי רחוק הוא \10- , יש לסרוק המערך בעזרת המצביע.
4) כתוב פונקציה המקבלת מצביע למחרוזת, הפונקציה תחזיר את מספר הפעמים
שספרות הופיעו ברצף.
לדוגמא:
“435fgfg 5443d3fd56”
אז הפונקציה תחזיר 4.5) כתוב תכנית אשר קולטת מחרוזת ומוצאת סכום הספרות באותה
מחרוזת.
לדוגמא: עבור המחרוזת:
“A23rt56drt”
הפלט יהיה: 16 .6) לכתוב פונקציה בשם atoi אשר מקבלת מצביע למחרוזת המכילה ספרות .
הפונקציה מחשבת הערך המספרי של המחרוזת ומכניסה אותו למשתנה
מטיפוס int ומחזירה אותו.
אם המחרוזת מכילה תו שהוא לא ספרה, אז היא מחזירה –1.
בהצלחה!
אין תגובות:
הוסף רשומת תגובה