Presentation is loading. Please wait.

Presentation is loading. Please wait.

מבוא למדעי המחשב – סמסטר א' תשע"ב

Similar presentations


Presentation on theme: "מבוא למדעי המחשב – סמסטר א' תשע"ב"— Presentation transcript:

1 מבוא למדעי המחשב – סמסטר א' תשע"ב
תרגול 3 - מערכים

2 היום בתרגול 1. מערך חד-מימדי: 2. משתנים שאינם פרימיטיביים.
מה זה מערך ולמה צריך אותו? איך מגדירים? איך זה נראה בזכרון? עבודה עם מערכים. 2. משתנים שאינם פרימיטיביים. 3. מערך דו-מימדי: למה צריך? איך מגדירים? איך זה נראה בזכרון? דוגמאות לשימוש במערך דו-מימדי.

3 נושא ראשון: מערך חד מימדי

4 מערך חד-מימדי מערך הינו מבנה זיכרון המכיל מספר ערכים מאותו טיפוס, גודל המערך נקבע כאשר הוא נוצר (בזמן ריצה) ולאחר מכן הוא קבוע. אילו טיפוסים אנו מכירים? 3 4 2 6 7 8 1

5 מערך - מאפיינים טיפוס שאינו פרימיטיבי מבנה מסודר של ערכים.
לכל ערך יש מקום. כל איברי המערך הם מאותו סוג. לכל טיפוס פרימיטיבי ניתן לייצר מערך מתאים. וכן לטיפוסים שאינם פרימיטיביים כפי שנלמד בהמשך 3 4 2 6 7 8 1

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

7 הגדרת מערך כמו כל משתנה, גם מערך צריך הגדרה והשמה.
//declares an array of integers int[] myArray; ההגדרה מורכבת מטיפוס המערך ומשם המערך. הסוגריים המרובעים לאחר הטיפוס מציינים שהמשתנה המוגדר הוא מסוג מערך.

8 כמה מקום בזיכרון דורש מערך?
בשיעור קודם למדנו שטיפוס של משתנה מגדיר כמה מקום צריך בזיכרון כדי להכיל ערכים שיכול לקבל המשתנה ואיך להתייחס לערכים אלו. כמה מקום יש להגדיר למערך? כמה מקום דורש int[] ?

9 הקצאת זכרון myArray = new int[5];
בזמן הגדרת המערך יש מקרים בהם הקומפיילר לא יכול לדעת כמה תאים ידרשו למערך. מסיבה זו ואחרות, ההגדרה עצמה אינה מקצה זיכרון עבור כל המערך, אלא רק מקום שיכול להכיל מצביע למיקומם של תאי המערך אשר יוקצו בזמן ריצה עלידי שימוש במילה השמורה new. myArray = new int[5]; תמונה של מערך בזיכרון: אוסף של תאים "רצופים", כל אחד בגודל המתאים לסוג המערך. הקצאת הזכרון למערך מתרחשת פעם אחת בלבד, בזמן יצירתו. תוכן התאים במערך יכול להשתנות תוך כדי ריצה, אך לא כן מספר התאים (הגודל). למערך קיים מאפיין בשם length המחזיר את גודל המערך. ניתן בעיקרון להקצות מערך בכל גודל חיובי שלם(גם בגודל אפס אך מערך כזה אינו שימושי). myArray

10 הקצאת זכרון באמצעות משתנה
int size = Math.random() * 10; int[] myArray; myArray = new int[size]; נשים לב שבמקרה זה ניתן לדעת את גודלו של המערך רק בזמן ריצה!

11 הגדרה והקצאה בשורה אחת int[] myArray = new int[5];
int[] smallPrimes ={2,3,5,7,11}; myArray איתחול זה יכול להתבצע רק בסמוך להגדרה smallPrimes 2 3 5 7 11

12 length –גודל המערך int size = 5; int[] myArray;
myArray = new int[size]; System.out.println(myArray.length(; // prints 5 size = 6; מה לדעתכם תדפיס כעת השורה הבאה? System.out.println(myArray.length); להוסיף טבלת משתנים על הלוח

13 מספור תאים במערך אם במערך יש n תאים הם ממוספרים 0…n-1

14 פנייה לאיבר (תא) במערך int[] smallPrimes = {2,3,5,7,11};
קריאת ערך מתא במערך : int num = smallPrimes[3] * 2; // num = 7*2 = 14 index 1 2 3 4 value 5 7 11 טבלת משתנים

15 פנייה לאיבר במערך num נשאר ללא שינוי smallPrimes[3] = 13; index 1 2 3
1 2 3 4 value 5 13 11

16 Run Time Error פנייה לאיבר במערך smallPrimes[5] = 17;
index 1 2 3 4 value 5 13 11 smallPrimes[5] = 17; num = smallPrimes[-1]; Run Time Error פניה למערך במיקום שאינו קיים (כלומר מעבר לגבולות המערך) תגרור שגיאה בזמן ההרצה, בדומה לחילוק באפס, הקומפיילר לא בודק חריגה מגבולות מערך אפילו שלכאורה הוא יכול

17 פנייה לאיבר במערך int i = 5; myArray[i] = 3; myArray [i/2] = 1;
בתוך ה-[] יכול להיות ביטוי מתמטי,קריאה לפונקציה וכו', כל עוד התוצאה הינה מטיפוס שלם. mArray[3.5] שגיאת קומפילציה mArray[(int) 3.5] בסדר למרות, שאין סיבה לעשות משהו מוזר כזה!!

18 פעולות על מערך //Demonstrates basic array operations public class BasicArray { public static void main(String[] arg) { int[] smallPrimes = {2,3,5,7,11}; System.out.println(smallPrimes[0]); 2 smallPrimes[0] = 13; 13 System.out.println(smallPrimes.length); 5 for(int i=0;i<smallPrimes.length;i=i+1) System.out.print(smallPrimes[i]+", "); 13, 3, 5, 7, 11, } //main } //class BasicArray Print vs. println() 18 18

19 איתחול מערך ע"י לולאה //Demonstrate array init with a loop
public class IntArray { public static void main(String[] arg) { int[] intArray = new int[5]; System.out.println(); for(int i=0;i < intArray.length ;i=i+1) intArray [i] = i*3; for(int i=0;i<intArray.length;i=i+1) System.out.print(intArray[i]+", "); } //main } //class IntArray 0, 3, 6, 9, 12,

20 משתנים שאינם פרימיטיביים
נושא שני: משתנים שאינם פרימיטיביים

21 זיכרון של תוכנית רצה (תהליך)
תוכנית רצה נקראת תהליך. הזיכרון של התהליך מחולק לחלקים מתוכם 2 עיקריים: מחסנית (Stack) : חלק קטן מהזיכרון המיועד להחזקת משתנים פרימיטיביים וכתובות. ערימה (Heap) : חלק גדול מהזיכרון המיועד להקצאות דינאמיות (כמו אלו שראינו עבור המערך). בJava זיכרון זה מחזיק רק ערכים מטיפוסים שאינם פרימיטיביים.

22 משתנה פרימיטיבי y נשאר ללא שינוי. משתנים אלו מוחזקים במחסנית. 3 7 3
int x = 3; int y = x; x=7; y נשאר ללא שינוי. משתנים אלו מוחזקים במחסנית. טיפוס שם משתנה ערך int x y 3 7 3 עם טבלת משתנים על הלוח

23 משתנה שאינו פרימיטיבי int[] xArray = new int[5];
int[] yArray = xArray; xArray[1] = 6; xArray 6 עדיף לצייר טבלת משתנים על הלוח, אחר כך להראות את האנימציה yArray

24 שאלה מה יקרה בזכרון בזמן הרצת הקוד הבא? int[] myArray;
myArray = new int[5]; myArray = new int[10]; myArray עם טבלת משתנים על הלוח

25 אינו פרימיטיבי vs. פרימיטיבי
משתנה שאינו פרימיטיבי משתנה פרימיטיבי כתובת למקום ב Heap הערך עצמו מה נמצא במחסנית הכתובת (שהיא למעשה הערך במחסנית) מועתקת הערך מועתק השמה השוואה בין כתובות (שהם למעשה הערך במחסנית) השוואה בין ערכים (==) השוואה עם טבלת משתנים על הלוח

26 null – ערך מיוחד משתנים המחזיקים כתובות (כמו מערכים) יכולים גם לקבל השמה לערך המיוחד null: myArray = null; במחסנית ערכו של המשתנה myArray הוא הקבוע null – שלמעשה אומר, invalid address. myArray null להדגיש נקודה זו

27 null כתובת int[] arr1 = null; int[] arr2 = null;
System.out.println(arr1==arr2); true

28 שאלה מה נקבל כאשר נבקש myArray.length לפני שהקצינו את המערך?
int[] myArray; System.out.println(myArray.length); תשובה: שגיאת קומפילציה, הקומפיילר מזהה את השגיאה ועוצר את תהליך הקומפילציה.

29 שאלה ואם נבקש myArray.length כאשר נעשתה לו השמה ?null
int[] myArray = null; System.out.println(myArray.length); תשובה: שגיאת זמן ריצה (מסוג NullPointerException) המציינת שניסינו לפנות למשתנה שערכו הוא null, הקומפיילר אינו מזהה את השגיאה.

30 שאלה ובמקרה: int[] myArray = new int[0];
System.out.println(myArray.length);מה יודפס למסך? תשובה: 0

31 נושא 3: מערכים דו מימדיים.

32 מערך דו-מימדי מערך שבו כל איבר הוא גם מערך,כלומר מערך של מערכים.
חלק שני של התרגול

33 מערך דו-מימדי int[][] array1 = new int [3][2]; array1 0 0 0 0 0 0
ניתן בקלות ליצור מערך דו-מימדי שבו כל המערכים הפנימיים הם באותו האורך, מערך כזה נקרא מטריצה:

34 מערך דו-מימדי int[][] array2 ={{1,3},{5,6,7},{4}}; 5 array2 3 6 4 1 7

35 length – אורך של מערך array1.length  array1[0].length 
5 array2 3 6 4 1 7 3 2 3 1 3 Run time Error

36 פנייה לאיבר // prints 5 System.out.println(array2[1][0]);
3 6 4 System.out.println(array2[1][0]); array2[2][0] = 9; 1 7 9 // prints 5

37 Run Time Error (NullPointerException)
public class ArrayRef{ public static void main(String []args){ int[][] x; x = new int[3][]; x[0] = new int[3]; x[1] = x[0]; x[0][1] = 7; //prints the 2D array for (int i = 0 ; i < x.length ; i= i+1){ for(int j=0 ; j < x[i].length; j = j+1){ System.out.print(x[i][j]+” ”); } System.out.println(); 0 7 0 Run Time Error (NullPointerException) 37 37

38 שאלה מה יקרה אם נוסיף את השורה הבאה? x[2]= x;
תשובה: java מבדילה בין מערך של מספרים ובין מערך של מערכים של מספרים ולכן השורה הזאת לא תעבור קומפילציה (שכן איברי המערך צריכים להיות מאותו טיפוס).

39 העתקת מערך public class Copy2dArray{
public static void main(String[] args){ int[][] a = {{1,3},{5,6,7},{4}}; int[][] c; //Create the 2dArray row by row c = new int[a.length][]; int i,j; for ( i=0 ; i < c.length; i = i+1) c[i] = new int[a[i].length]; for ( i=0; i < c.length; i = i+1) for (j=0 ; j < c[i].length ; j = j+1) c[i][j] = a[i][j]; } //main } כדאי להתעכב על דוגמה זו

40 משולש פסקל Wikipedia מה החוקים לחישוב משולש פסקל 1 1 1 1 2 1 להראות את הקוד בנפרד להתמקד בחלק השמאלי, ולנסות להסביר החוקים לחישוב המשולש Pascal[j][0] = Pascal[j][j]=1 Pascal[j][i] = Pascal[j-1][i] + Pascal[j-1][i-1]

41 הדפסת לוח הכפל public class MultiplicationTable {
public static void main(String[] arg) { final int ROW = 13; final int COLUMN = 13; int[][] mat = new int[ROW][COLUMN]; for (int i=0; i < ROW; i=i+1) for (int j=0; j < COLUMN; j=j+1) mat[i][j] = i*j; //prints the matrix for (int i=0; i < ROW; i=i+1) { System.out.print(mat[i][j]+"\t"); System.out.println(); } } //main } //class הערה: כדי להדפיס למסך את לוח הכפל יכולנו להסתפק בלולאה כפולה ולא היינו צריכים להשתמש במערך דו-מימדי. דוגמא זו באה להמחיש שימוש ב lookup table : אילו החישוב של i*j היה מסובך, היינו אולי מעוניינים בטבלה כדוגמת הטבלה הזו, שתכיל את כל התוצאות. ע"י כך ניתן להבטיח כי החישוב ייעשה פעם אחת, ולנו תהיה גישה קלה לתוצאה. רק במקרה שיישאר זמן

42 חיבור מטריצות // Adds two matrices public class Add{
public static void main(String[] args){ int[][] a = { /* insert data here */ }; int[][] b = { /* insert data here */ }; int[][] c; c = new int[a.length][a[0].length]; for (int i = 0 ;i<a.length;i=i+1) for (int j =0;j< a[i].length;j= j+1) c[i][j] = a[i][j] + b[i][j]; } //main } //class Add . רק במקרה שיישאר זמן

43 הכפלת מטריצות* . רק במקרה שיישאר זמן

44 //Multiplies two matrices pbulic class Mul{
public static void main(String[] args){ int[][] a = { /* insert data here */ }; int[][] b = { /* insert data here */ }; int[][]c; //Create the matrix row by row c = new int[a.length][]; for (int i = 0 ; i < c.length ; i = i+1) c[i] = new int[b[0].length]; //For each element in the matrix for (int i=0; i<a.length ; i=i+1) for(int j=0; j<b[0].length; j=j+1){ //NOTICE that b.length is equal to a[i].length //Calculate the sum c[i][j] = 0; for (int k=0; k<a[i].length ; k= k+1) c[i][j] = c[i][j] + (a[i][k] * b[k][j]); } //for } //main } //class Mul . רק במקרה שיישאר זמן


Download ppt "מבוא למדעי המחשב – סמסטר א' תשע"ב"

Similar presentations


Ads by Google