תכנות – שיעור
This presentation is the property of its rightful owner.
Sponsored Links
1 / 47

תכנות – שיעור 7 PowerPoint PPT Presentation


  • 93 Views
  • Uploaded on
  • Presentation posted in: General

תכנות – שיעור 7. חזרה -מערכים. נגדיר בעזרתו קבוצת משתנים כאשר יהיה לנו מספר רב של משתנים זהים Type name[SIZE]; Char a[10]; int b[50]; הגודל חייב להיות קבוע. פנייה לאיברי המערך מתבצעת ע"י a[k] כאשר K בין 0 ל- SIZE-1 אתחול ע"י לולאה או רשימת אתחול. החלפה בין משתנים.

Download Presentation

תכנות – שיעור 7

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


7

תכנות – שיעור 7


7

חזרה -מערכים

  • נגדיר בעזרתו קבוצת משתנים כאשר יהיה לנו מספר רב של משתנים זהים

  • Type name[SIZE];

  • Char a[10]; int b[50];

  • הגודל חייב להיות קבוע.

  • פנייה לאיברי המערך מתבצעת ע"י a[k] כאשר K בין 0 ל-SIZE-1

  • אתחול ע"י לולאה או רשימת אתחול


7

החלפה בין משתנים

  • נסתכל על התוכנית הבאה:

    int main()

    {

    int a,b,x,y,temp;

    temp = x;

    x = y;

    y = temp;

    temp = a;

    a = b;

    b = temp;

    }

החלפת הערכים

החלפת הערכים


7

החלפה בין משתנים

  • כפי שלמדנו במצב כזה הינו רוצים שתהיה פונקציה שתבצע את החלפה הזו בין המשתנים.


7

החלפה בין משתנים

  • נכתוב פונקציה כזו בשם swap

    void swap(int p, int q)

    {

    int tmp = p;

    p = q;

    q = tmp;

    }


7

החלפה בין משתנים

int main()

{

int a=10,b=2,x=3,y=5,temp;

swap(x,y);

swap(a,b);

}


7

החלפה בין משתנים

  • נעקוב אחרי הקריאה לפונקציה

    swap(x,y);

void swap (int q,int p)

{

int temp = p;

p = q;

q = temp;

}


7

מצביעים

  • ראינו שכל משתנה שהגדרנו בתוכנית שלנו מוצקה עבורו תא באזור כלשהו בזיכרון.

    int main()

    {

    Int x,y;

    }

  • לכל תא כזה יש כתובת בזיכרון של המחשב.

  • כדי להגיע לכתובת של משתנה משתמשים באופרטור &.

x

y


7

מצביעים

  • מה יחזירו &x ו&y .

x5000

y5004


7

מצביעים

  • ניתן להגדיר משתנים שסוגם הוא מצביע.

  • משתנים כאלה מחזיקים בתוכם את הכתובות.

    int main()

    {

    int x,y;

    int* p;

    p = &x;

    }

x5000

y5004

p9008


7

מצביעים

  • כדי לסמן שמצביע לא מצביע לשום מקום נהוג להשים לו NULL

  • p = NULL;

  • אפשר לחשוב על משתנה מסוג מצביע כאל חץ:

x

y

p


7

מצביעים

פורמט הדפסה של משתנה מסוג מצביע

int main()

{

int x=7,*p = &x;

printf(“Value %d Pointer %p\n”, x, p);

}

  • כדי להדפיס את ערך שאילו מצביע p.

    printf(“Value %d\n”,*p)


7

מצביעים

  • יש לשים לב שאין הצבעה לביטויים ולקבועים

    &3

    &(k+99)


Call by value and call by reference

Call by value and call by reference

  • בכל הפונקציות של c מנגנון העברת של הפונקציות הוא לפי ערך.

  • נחזור לפונקצית ה swap.

  • הבעיה הייתה שהחלפת הערכים התבצעה בין הפרמטרים של הפונקציה ולא בין המשתנים עצמם.


Call by reference

Call by reference

int main()

{

int a=10,b=2,x=3,y=5;

swap(&x,&y);

swap(&a,&b);

}

void swap (int* q,int* p)

{

int temp = *p;

*p = *q;

*q = *temp;

}


Call by reference1

Call by reference

  • בכדי לממש call by reference יש לבצע את הדברים הבאים:

    1 להגדיר את הפרמטרים של הפונקציה כמצביעים

    void swap(int *p, int *q)

    2 להשתמש בגוף הפונקציה בערכים שליהם שמצביעים מצביעים

    *p = *q;

    3 בקריאה לפונקציה להעביר כתובות כארגומנטים

    swap(&x, &y);


Call by value and call by reference1

Call by value and call by reference

  • בכל הפונקציות של c מנגנון העברת של הפונקציות הוא לפי ערך.

  • נחזור לפונקצית ה swap.

  • הבעיה הייתה שהחלפת הערכים התבצעה בין הפרמטרים של הפונקציה ולא בין המשתנים עצמם.


Call by reference2

Call by reference

int main()

{

int a=10,b=2,x=3,y=5;

swap(&x,&y);

swap(&a,&b);

}

void swap (int* q,int* p)

{

int temp = *p;

*p = *q;

*q = temp;

}


Call by reference3

Call by reference

  • בכדי לממש call by reference יש לבצע את הדברים הבאים:

    1 להגדיר את הפרמטרים של הפונקציה כמצביעים

    void swap(int *p, int *q)

    2 להשתמש בגוף הפונקציה בערכים שלהם שמצביעים מצביעים

    *p = *q;

    3 בקריאה לפונקציה להעביר כתובות כארגומנטים

    swap(&x, &y);


7

הקשר בין מערכים ומצביעים

  • כאשר אנחנו מגדירים מערך בגדול 20 של שלמים אזי יש לנו 20 משתנים מסוג int בזיכרון. מה הכתובת של משתנים אלו ?

  • int a[20];

a[0]

כמו לכל משתנה גם לאיברי המערך ישנה כתובת. כיצד נגיע לכתובת זו?

a[19]


7

הקשר בין מערכים ומצביעים

  • ניתן להגיע לכתובות בדרך הרגילה

  • int *p;

  • p = &a[0];

  • נזכר שהמערך ממוקם בצורה רציפה בזיכרון לכן כתובות איברי המערך הן רציפות למשל:

5000

5004

5008


7

משמעות שם המערך

  • פניה לשם המערך נותנת לנו את כתובת המערך שהיא למעשה מצביע לאיבר הראשון במערך.

  • בשם המערך ניתן להשתמש כדי לקבל את הכתובת הזו לא ניתן לשנות אותו (כלומר הוא מצביע קבוע)

  • int *p;

  • p = a;

  • p מצביע לראש המערך.(את p כמובן שניתן לשנות)


7

חשבון של מצביעים

  • ניתן להשתמש בפעולות חיבור וחיסור על כתובות. זה שימושי בעיקר בשילוב עם מערכים.

  • *(a+i) שקולa[i];

  • *(p+i) שקולp[i];


7

חשבון של מצביעים

  • מספר דרכים לכתוב לולאה שרצה על מערך:

    for (i=0; i<N; i++)

    sum + = a[i];

    for (p = a, i=0; i<N; i++)

    sum + = *(p+i);

    for (p=a; p<=&a[N-1]; p++)

    sum + = *p;


7

חשבון של מצביעים

  • כיצד ה++ יודע לקדם את המצביע לאיבר הבא ?

  • הבעיה: המערך יכול להיות של תווים של שלמים או של כל דבר והמרחק בין התאים הוא שונה.

  • מה המרחק עבור int ?

  • מה המרחק עבורchar ?


7

חשבון של מצביעים

  • כיוון שהגדרנו את סוג האיבר שאילו המצביע מצביע ולכן יש לנו את הגודל שצריך לקפוץ בכל פעם. זו החשיבות והסיבה שמגדירים את סוג האיבר שאילו מצביעים.

  • המקום השני שבו אנו משתמשים בסוג שאליו מצביעים הוא בשימוש ב-*


7

העברת מערך לפונקציה

  • כיצד נכתוב פונקציה שמקבל כערך מערך ומבצעת חישוב על איבריו?

  • נניח שנרצה לכתוב פונקציה שמקבלת מערך של מספרים ומחזירה את סכום איברי המערך.

  • העברת מערך לפונקציה מתבצעת למעשה ע"י העברת מצביע לראש המערך.

  • int sum(int a[], int size);

prototype


7

העברת מערך לפונקציה

  • a[ ] זהו פשוט מצביע למערך של int.

  • הפרמטר השני הוא גודל המערך.

  • מאחר ואנחנו עובדים עם מצביעים אין לנו מידע מהו גודל המערך ולכן נעביר את המידע הזה כפרמטר לפונקציה.


7

העברת מערך לפונקציה

  • ההגדרות הבאות שקולות:

  • int f(float arr[]);

  • int f(float arr[5]);

  • int f(float arr[100]);

  • int f(float *arr);


7

העברת מערך לפונקציה

int sum(int a[], int size)

{

int i, res = 0;

for(i = 0; i < size; i++)

res += a[i];

return res;

}


7

העברת מערך לפונקציה

Int sum(int *p, int size)

{

int i, res = 0;

for(i = 0; i < size; i++)

res += p[i];

return res;

}


7

העברת מערך לפונקציה

  • כאשר נרצה למנוע א אפשרות של שינוי איברי המערך בפונקציה נעביר את המערך כconst-

    int sum(const int a[], int size)

    {

    int i, res = 0;

    for(i = 0; i < size; i++)

    res += a[i];

    return res;

    }


7

מיון מערכים

  • המטרה נרצה למיין מערך של מספרים כאשר האיבר הקטן יהיה בתחילת המערך והגדול בסופו.

  • בעיה חשובה במדעי המחשב

  • המטרה היא לפתור באופן יעיל ככל הניתן (אנו נציג פיתרון לא יעיל)


7

מיון מערכים

  • מציאת אלגוריתם למיון

  • פסאודו קוד

  • קוד תיקני ב-C


7

מיון מערכים-אלגוריתם

  • האלגוריתם:

  • נגדיר אלגוריתם בעל N שלבים כאשר בסוף השלב ה-K, K האיברים הקטנים ביותר יהיו ממוינים.

  • אלגוריתם משני לשלב ה-K

  • נמצא את האיבר המינימל מבין N-K+1 האיברים הגדולים(אשר נמצאים במערך בין N-(K ונחליף בינו לבין האיבר K.


7

מיון מערכים – פסאודו קוד

min הערך המינימלי

min_index האיבר

בעל הערך המינמלי

SORT(A)

N = size(A)

For k =1 to N

min = A[k]

min_index = k

for j = k + 1 to N

if (A[j] < min)

min_index = j; min = A[j]

end

Swap(A,k,min_index);

end

מציאת האיבר המינימלי מ- k עד n


7

מיון מערכים –קוד

Void swap(int *, int *);

Void Sort(int A[], int size)

{

int min, min_index, k, j;

for(k = 0; k < size; k++)

{min = A[k]; min_index = k;

for(j = k + 1; j< size;j++)

{

…..

}

swap(A + k, A + min_index);

}

}


7

מיון מערכים –קוד

for(j= k + 1; j < size; j++)

{

if (a[j] < min)

{

min = a[j];

min_index = j;

}

}


7

מיון מערכים

  • מציאת איבר יכולה להיעשות מהר log2(N)) כאשר במערך לא ממוין ייקח למצוא איבר N צעדים


7

מציאת איבר במערך ממוין – חיפוש בינארי

int BinarySearch(const int arr[], int size, int key)

{

int low, middle, high;

low = 0;

high = size - 1;

while(low <= high)

{

middle = (low + high) / 2;

if (key == arr[middle])

return middle;

if (key > arr[middle])

low = middle + 1;

else

high = middle -1;

}

return -1;

}


7

  • איך יראה פיתרון רקורסיבי לבעיה?


7

מיון מערכים-יעילות

  • הזמן שייקח לתוכנית זאת למיין הוא סדר גודל של n^2

  • האם ניתן לשפר זאת?


7

מיון בזמן ליניארי- אם הערכים בטווח קטן

  • בכדי לבצע מיון זה נצטרך באופן כללי שני מערכי עזר אחד למערך הממוין ואחד למערך עזר (כאשר איברי המערך הם מספרים ניתן להסתפק רק במערך העזר)

  • הרעיון יהיה לספור בעזרת מערך העזר כמה איברים קטנים מאיבר עם ערך k וכך ניתן יהי להכניסו למקום ללא בעיות


7

מיון בזמן ליניארי- אם הערכים בטווח קטן

Counting_Sort(A,B)

Set C[N] to 0

For i=1 to SIZE

C[A[i]] = C[A[i]] + 1;

For i=2 to N

C[i] = C[i-1] + C[i]

For j=1 to SIZE

B[C[A[j]]] = A[j]

C[A[j]] = C[A[j]] - 1

כמה איברים מכל סוג

כמה איברים קטנים מאיבר מסוג k

הכנסה למערך הפלט


7

void CountSort(const int a[], int b[], int size)

{

int i;

int c[RANGE] = {0};

for(i = 0; i < size; i++)

c[a[i]]++;

for(i=1; i < RANGE; i++)

c[i] += c[i-1];

for(i=0; i < size; i++)

{

b[c[a[i]]] = a[i];

c[a[i]]--;

}

return;

}


7

#include <stdio.h>

#define SIZE 10

#define RANGE 6

void CountSort(const int a[], int b[], int size);

void Print(const int arr[], int size);

int main()

{

int a[SIZE] = {5,3,2,5,5,4,1,1,0,0}, b[SIZE] ={0};

Print(a, SIZE);

CountSort(a,b,SIZE);

Print(b, SIZE);

return 0;

}


7

יעילות

  • תוכנית זאת תרוץ בזמן ליניארי ב-גודל המערך ובגודל הטווח אך תשתמש במקום עזר


  • Login