עבור לתוכן

שפת C - מערכים

Featured Replies

פורסם

צהריים טובים :xyxthumbs:

כחלק מתוכנית שאני צריך לכתוב באנליזה נומרית אני יוצר מערך בעל 20 מקומות, אותו אני רוצה לחלק ל 17 מערכים אחרים שמכילים 4 מקומות בצורה הבאה:

מערך1 - איברים 0 -> 3 (כולל)

מערך 2- איברים 1 -> 4 (כולל)

מערך 3- איברים 2 -> 5 (כולל)

.

.

.

מערך 17- איברים 16 -> 19 (כולל)

אחרי כן אני צריך לשלוח כל מערך (1 עד 17) לפונקציה שמקבלת אך ורק את המערך והגודל שלו (כלומר אם אני רוצה למספר את המערכים 1->17 ע"י כך שאני הופך אותם למערכים דו-מימדיים x[j] - אני לא יכול)

איך עושים דבר כזה?

פורסם

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

כלומר, אם תעשה דבר כזה:

int a[10] = {1,2,3,4,5,6,7,8,9,10};
int* p = a;

אז a ו-p יצביעו בדיוק לאותו המקום בזכרון. אגב, מתקיים השוויון:

p == &a[0]

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

איך הקומפיילר ניגש לאיבר במערך? כשאתה עושה [a[n (עבור n כלשהו), הקומפיילר מתרגם את זה ל:

*(a+n)

כלומר, לוקחים את המצביע לתא הראשון במערך, ממנו מתקדמים n צעדים, ואז עושים לזה dereference, כלומר מסתכלים מה נמצא בתא הזה במערך.

שים לב ש-a לא חייב להיות "מערך", אלא מספיק שהוא יהיה מצביע - כלומר, אפשר לעשות [p[n, וזה יעבוד.

עכשיו, מה יקרה אם תעשה ככה:

int* q = p+1;

ואז ננסה לגשת ל-[q[n? אז הקומפיילר יתרגם את זה ל:

*(q+n)

שזה למעשה:

*(p+(n+1))

שזה כמובן [p[n+1. כלומר, גישה לאיבר ה-n ב"מערך" q היא כמו גישה לאיבר ה-n+1 במערך המקורי p. כלומר, q הוא כאילו "תת המערך" של p, החל ממקום 1. באותו אופן, אם הוגדר q=p+m עבור m כלשהי, אז q בעצם מצביע ל"תת המערך" שמתחיל במקום m.

יש מבין?

פורסם
  • מחבר

האמת שלא. רק בולבלתי עוד יותר.. אני גם לא רואה את הרלוונטיות לבעיה שלי

פורסם

יש לך מערך a בגודל 20.

אתה רוצה להתייחס לתת המערך החל ממקום 1? אז אתה צריך לעשות

int* p = a+1;

ואז p הוא המערך a החל ממקום 1, כלומר [ 0]p זה האיבר ה-1 ב-a, ו-[p[1 זה האיבר ה-2 ב-a, וכן הלאה.

רוצה את תת המערך החל ממקום 2? אז אתה צריך:

int* p = a+2;

וכן הלאה.

אתה רוצה לעשות מערך דו מימדי, שכל אחד מהם יצביע לתת מערך של a? אז תשתמש במערך של מצביעים:

int* p[17];
for (int i = 0 ; i < 17 ; ++i)
p[i] = a+i;

יש מבין? עכשיו, [p[ i הוא המערך ה-i, כלומר תת המערך של a החל ממקום i. אם אתה רוצה לגשת לאיבר ה-n שבמערך ה-i, אז אתה צריך לגשת ל- [p[ i][n.

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

פורסם
  • מחבר

אוקי, סבבה :)

אני חושב שמה שאני אעשה פשוט זה ליצור מערך tmp כלשהו שכל פעם יכיל 4 איברים מהמערך הגדול..

בינתיים יש משהו קטן שמחרפן אותי

int main()
{
double x[N], jump;
int i=0;


jump = (5/19);

for (i=1; i<21; i++){
x[i]=-3 + jump;
}

printf("%lf\n", jump);


בהדפסה זה כותב לי ש jump=0 ולא 5/19 .. למה זה קורה?

פורסם

כי כשמחלקים int ב-int אז התוצאה היא int, כלומר מעוגלת כלפי מטה. אם אתה רוצה שהחלוקה תהיה נכונה, אחד מהם צריך להיות double.

נ.ב. מפתיע אותי שאתה לא יודע את זה, כי זה צריך להיות חומר מאוד בסיסי (הרבה יותר ממערכים).

פורסם
  • מחבר

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

עוד משהו ששמתי לב אליו זה שהוא מדפיס לי את ה double עם 6 ספרות אחרי הנקודה העשרונית. חשבתי שלטיפוס מסוג דאבל יש הרבה יותר 'מקום', לא?

והפעם זה די קריטי

פורסם

קודם כל, אתה יכול לקבוע את רמת הדיוק ע"י:

printf("%.5lf", jump);

כשבמקום 5 שים את מספר הספרות שאתה רוצה. אם אתה רוצה לדעת על עוד אפשרויות דומות, חפש בגוגל על printf.

חוץ מזה, רמת הדיוק של מספרים ממשיים (double/float) לא בדיוק עובדת לפי מספר הספרות אחרי הנקודה, ככה שיש מספרים עם 6 ספרות אחרי הנקודה שאפשר לייצג באופן מדויק, ויש כאלה שלא. לפי מה שהבנתי המקצוע האחר הוא אנליזה נומרית, שזה בדיוק התחום שבו מתעסקים עם רמת הדיוק של מספרים כאלה.

פורסם
  • מחבר

צודק, תודה!

ועוד שאלה בסיסית-

מיליתי מערך x[] במספרים ועכשיו אני רוצה להציב בפונקציה נתונה כדי לקבל את ערך ה y[] בהתאם של כל x.

אני לא יכול לכתוב דברים מהסוג:

y[1]=(1/((x[1]-0.3)*(x[1]-0.3) + 0.01)) + (1/((x[1]-0.9)(x[1]-0.9) + 0.04)) - 6;

?

השגיאה שנכתבת היא

called object is not a function

פורסם

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

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

פורסם
  • מחבר

מה ז"א? לפי הסוגריים נראה לי שכתבתי הכל נכון.

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

זה כל הקוד

int main()
{
double x[N], y[N];
double jump, a, b;
int i=0;

a=5;
b=19;
jump = a/b;

x[1]=-3;
// filling up x[21] - equal spaces//
for (i=2; i<21; i++){
x[i]=x[1] + jump;
jump+=(a/b);
}

y[1]=1/((x[1]-0.3)*(x[1]-0.3) + 0.01) + 1/((x[1]-0.9)(x[1]-0.9) + 0.04) - 6;
printf("%lf\n", y[1]);
scanf("%lf", &i);
for (i=2; i<21; i++){
y[i] = (1/((x[i]-0.3)*(x[i]-0.3) + 0.01)) + (1/((x[i]-0.9)(x[i]-0.9) + 0.04)) - 6;
}

אני לא מבין מה הבעיה של הקומפיילר עם השורה הזאת?

פורסם

*אהם*

תסתכל על מה שסימנתי (לצערי אני לא יכול להדגיש בתוך קוד...)


y[i] = (1/((x[i]-0.3)*(x[i]-0.3) + 0.01)) + (1/((x[i]-0.9)(x[i]-0.9) + 0.04)) - 6;
^^ here

פורסם
  • מחבר

אויייייייששששששששששש !!!!!! :kopfpatsch:

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים