פורסם 2008 בפברואר 417 שנים שלום,אני מנסה לכתוב פונקציה שתקבל שתי מטריצות בגדלים זהים ותחזיר מטריצה של סכומם.הצלחתי לעשות את הפונקציה כאשר היא מקבלת תמיד מטריצות של 2 טורים אבל אני לא מצליח לעשות פונקציה שתקבל מטריצות בגדלים שונים.זה הקוד שכתבתי ועובד:void Add(int mat1[][2], int mat2[][2], int w, int h, int res[][2]){ //int res[w][h]; for (int i=0; i<w; i++) for (int j=0; j<h; j++) res[i][j] = mat1[i][j] + mat2[i][j];}וכאשר ניסית להעביר את זה למטריצה בגודל דינאמי זה לא עבד. הנה הקוד:void Add(int mat1[][], int mat2[][], int w, int h, int res[][]){ //int res[w][h]; for (int i=0; i<w; i++) for (int j=0; j<h; j++) res[i][j] = mat1[i][j] + mat2[i][j];}איך אני יכול להעביר את המטריצות בצורה דינאמית?
פורסם 2008 בפברואר 417 שנים כשאתה מעביר מערך רב-מימדי לפונקציה, אתה חייב לקבוע מראש את כל המימדים של המערך, פרט למימד הראשון.הפתרון הוא להעביר מצביעים במקום מערכים, אבל אז צריך מאוד להיזהר מבחינת אינדוקסים.
פורסם 2008 בפברואר 417 שנים מחבר אז למה כשאני עושה ככה הוא נותן לי שגיאה?הפונקציה:void Add(int** mat1, int** mat2, int w, int h, int** res){ for (int i=0; i<w; i++) for (int j=0; j<h; j++) res[i][j] = mat1[i][j] + mat2[i][j];}שורת הקריאה: Add(mat1,mat2,2,2,res);השגיאה שהוא נותן לי:12 C:\Documents and Settings\Hebrew\My Documents\C++\MatAdd2.cpp cannot convert `int (*)[2]' to `int**' for argument `1' to `void Add(int**, int**, int, int, int**)'
פורסם 2008 בפברואר 417 שנים אם אני זוכר נכון (עבר הרבה זמן מאז שתיכנתתי עם C++) אם תעביר ייחוסים זה יפתור לך את הבעיה וגם העבודה איתם פשוטה יותר.
פורסם 2008 בפברואר 417 שנים מערך רב מימדי הוא לא באמת מצביע למצביע. הוא בעצם רק מצביע אחד, ולכן ההמרה הזו לא יכולה להתבצע.טוב, התשובה קצת מסורבלת, אני אקווה שאתה מצליח לעקוב:תזכורת קצרה (או אם לא ידעת):כשאתה מגדיר מערך, לדוגמה:int arr[N];אז הקומפיילר מקצה בלוק של N אינטים בזכרון. arr הוא בעצם מצביע לתחילת המערך. הביטוי הזה:arr[i]שקול לביטוי הזה:*(arr+i)שזה אומר להוסיף i פעמים את הגודל של arr* (== הגודל של int) ל-arrarr הוא בעצם מצביע לתחילת המערך.כשאתה מגדיר מערך דו מימדי, ככה:int arr[N][K];אז הקומפיילר מקצה בלוק של N*K אינטים בזכרון. arr הוא טיפוס עם התנהגות מוזרה - הוא מצביע ל-int (ולא מצביע למצביע ל-int), אבל אם תעשה לו dereferencing אז הוא יישאר מצביע עם טיפוס [int[K, אבל עם אותו הערך (כלומר arr == arr*, אתה יכול לבדוק את זה אפילו בעצמך עם printf). אם תמיר את arr ל-*int, אז הוא יתנהג כמו מערך חד-מימדי בגודל N*K.הבעיה היא שכל הבלגן הזה דורש שהקומפיילר יידע מראש את גודל המערך. אם אתה רוצה לעבוד עם מערכים דינמיים, אז זה פשוט בלתי אפשרי. בשביל זה יש כמה פתרונות:1. להקצות מערך של מצביעים, כך שבעצם תוכל להעביר מצביע למצביע:int* parr[N];for (int i = 0 ; i < N ; ++i){ parr[i] = mat[i];}כל מצביע במערך הזה מצביע לשורה במטריצה, ולכן אתה יכול להעביר את parr לפונקציה בבטחה.2. "לשטח" את המטריצה שלך - להתייחס אליה כמערך חד-מימדי, ולבצע את חישובי האינדקסים בעצמך במקום לתת אותם לקומפיילר:void Add(int* mat1, int* mat2, int w, int h, int* res){ for (int i=0; i<w; i++) for (int j=0; j<h; j++) res[i*h+j] = mat1[i*h+j] + mat2[i*h+j];}שים לב שזה דורש התעסקות עם מצביעים, ולכן דורש המרה של הקלט ל-*int:Add((int*)mat1,(int*)mat2,2,2,(int*)res);3. לעקוף לחלוטין את הבעיה, ולא להשתמש במערכים - כיוון שאתה עובד ב-++C, מומלץ להימנע משימוש במערכים ומצביעים איפה שאפשר - אם אתה יכול להשתמש ב-Vector, אז עדיף. במקרה שלך, אתה יכול להגדיר מטריצה ע"י וקטור של וקטורים:vector< vector<int> >ולעקוף לחלוטין את הבעיה.
ארכיון
דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.