יום ראשון, 11 בדצמבר 2016

שפת C - עוד על מצביעים (יום רביעי וראשון)

עוד על מצביעים:

- שם מערך הוא למעשה גם מצביע, שמצביע על הבית הראשון של האיבר הראשון במערך.

- כדי להצביע על מערך אפשר לעשות בפשטות (כש 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.













בהצלחה!






אין תגובות:

הוסף רשומת תגובה