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

שפת C - מערכים וקריאת פונקציה


sharonp

Recommended Posts

בוקר טוב!

בשפת C אני כותב פונקציה שמקבלת מערך אחד ומחזירה מערך אחר (נקרא למערך y_p).

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

השאלה שלי היא בעצם, מספיק לי לכתוב בסוף הפונקציה

return y_p וזה יחזיר את המערך או שצריך לכתוב משהו אחר?

(עוד לא יצא לי להחזיר מערך מפונקציה)

הקריאה:

y_p=calc_f(t, y); 

בתוך הפונקציה הנקראת אני משנה פרטנית את האיברים של המערך y_p, וכותב בסוף הפונקציה return y_p ?

* עוד אחת: אם K_3 מערך (דאבל), h מספר (דאבל) ו y_p מערך (דאבל) מותר לי לעשות את הכפל הבא והאיברים של y_p יגדלו פי h ויאוכסנו בתוך המערך K_3 ?

K_3=h*y_p; 

עוד שאלה,

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

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

קישור לתוכן
שתף באתרים אחרים

קוד כל שאלה ראשונה שלך:

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

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

בקשר לשאלה השני:

למה נראה לך שמה שעשית יפעל

על מנת להכפיל את כל האלמנטים בh אתה צריך לעבור על כל איברי המערך בעזרת לולאת for

על מנת לדעת את גודל המערך שלך, אתה משתמש ב sizeof(array) שתחזיר לך את גודל המערך בבייטים

ומחלק ב sizeof(double) שיחזיר לך את גודל המערך בכמות אלמנטים

קישור לתוכן
שתף באתרים אחרים

קודם כל, ערוך בבקשה את הכותרת כך שתכיל את תמצית השאלה.

ועכשיו, לשאלתך:

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

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

void f(int[] a, int n) {
int i;
for (i = 0 ; i < n ; i++) {
a[i] = i;
}
}

הפונקציה הזו לדוגמה מקבלת מערך באורך n, וממלאת אותו בערכים 0 עד n-1.

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

int* f(int n) {
int* a = (int*)malloc(sizeof(int)*n);
for (i = 0 ; i < n ; i++) {
a[i] = i;
}
return a;
}

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

ולגבי שאלותיך הנוספות:

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

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

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

קישור לתוכן
שתף באתרים אחרים

לא כל כך הבנתי את ההסבר, אני אכתוב את הקוד בצורה מופשטת

#include <stdio.h>
int main()
{
double t, y[n], y_p[n];

y_p=calc_f(t, y);

double calc_f(double t, double* y)
{

.
.
.

return y_p;
}

}

אתה יכול להדגים על הקוד הזה מה היית עושה כדי שיוחזרו מהפונקציה הערכים של המערך y_p ?

קישור לתוכן
שתף באתרים אחרים

void calc_f(double t, double* y, double* y_p, int n) {
// some code
}

ואז הקריאה לפונקציה תתבצע ע"י:

double t, y[n], y_p[n];
calc_f(t, y, y_p, n);

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

דרך אגב, אי אפשר להגדיר פונקציה בתוך פונקציה אחרת.

קישור לתוכן
שתף באתרים אחרים

כלומר y_p מערך המוגדר בתוך main ו calc_f משנה את הערכים שלו, משמע לא צריך להיות שום return בסוף הפונקציה בעצם? (או שפשוט כותבים return;?)

חשבתי שאם אני משנה את הערכים של מערך בתוך הפונקציה שקראתי לה אז הערכים האלה לא ישמרו כשאני אצא ממנה. ומה בעצם גורם לכך שאברי המערך y_p כן ישתנו והשינוי ישמר ביציאה מהפונקציה?

פתאם אני נזכר שעשיתי דברים כאלה כשלמדתי שפת C לפני שנה.. :-\

הגדרתי פונקציה בתוך פונקציה כי..לא שמתי לב. זה לא באמת איך שהקוד שלי נראה

קישור לתוכן
שתף באתרים אחרים

לא צריך return (אפשר, אבל לא נחוץ).

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

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

void f(int* arr) {
arr = NULL;
}

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

void f(int* arr) {
arr[0] = 5;
}

אז המערך כן ישתנה, כי אתה עובר דרך המצביע.

קישור לתוכן
שתף באתרים אחרים

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

ושאלה אחרונה (בינתיים): בהנתן תכנית מהסוג שכתבתי, אני יודע את גודלו של המערך y (נקרא לגודל n) ואת הגודל של המערך y_p (גם כן n).

איך אני יכול 'למצוא' את n בתוך הפונקציה אליה אני שולח אותם, מבלי לשלוח את n יחד איתם?

קישור לתוכן
שתף באתרים אחרים

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

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

ושאלה אחרונה (בינתיים): בהנתן תכנית מהסוג שכתבתי, אני יודע את גודלו של המערך y (נקרא לגודל n) ואת הגודל של המערך y_p (גם כן n).

איך אני יכול 'למצוא' את n בתוך הפונקציה אליה אני שולח אותם, מבלי לשלוח את n יחד איתם?

כמו שאמרתי, אי אפשר, אלא אם ה-n הזה קבוע ושמור גם באיזשהו מקום חיצוני (משתנה גלובאלי או define).

קישור לתוכן
שתף באתרים אחרים

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

זה הסיבה שרשמתי שיפרסם את הקוד

קשה לדעת מה בדיוק לענות לו

קישור לתוכן
שתף באתרים אחרים

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

double call_RK4(int Ne, double t, double h, double* x_0, double* x) 
{
double K_0[Ne+1], K_1[Ne+1], K_2[Ne+1], K_3[Ne+1], y[Ne+1], y_p[Ne+1];
double temp_t, temp_y[Ne+1];
int i=0;

// x_0 is a vector, sent to calc_f as y by requirement //
for (i=1; i<(Ne+1); i++){
y[i]=x_0[i];
}


//////-K_0-//////
clc_f(t, y, y_p); /* changes the values of y_p (0,0) */
for (i=1; i<(Ne+1); i++){
K_0[i]=h*y_p[i];
}
//////-K_1-//////
/* temps */
temp_t=t;
for (i=1; i<(Ne+1); i++){
temp_y[i]=y[i];
}
/****/

/* Changing t, y before sent to calc_f */
t=temp_t+0.5*h;
for (i=1; i<(Ne+1); i++){
y[i]=temp_y[i]+0.5*K_0[i];
}
/* sending .. */
clc_f(t, y, y_p); /* changes the values of y_p (from the last send) */
for (i=1; i<(Ne+1); i++){
K_1[i]=h*y_p[i];
}

//////-K_2-//////
/* still : t=t+h/2 */

/* Changing y before sent to calc_f */
for (i=1; i<(Ne+1); i++){
y[i]=temp_y[i]+0.5*K_1[i];
}
/* sending .. */
clc_f(t, y, y_p); /* gain new values of y_p */
for (i=1; i<(Ne+1); i++){
K_2[i]=h*y_p[i];
}

//////-K_3-//////
/* Changing t, y before sent to calc_f */
t=temp_t+h;
for (i=1; i<(Ne+1); i++){
y[i]=temp_y[i]+K_2[i];
}
/* sending .. */
clc_f(t, y, y_p);
for (i=1; i<(Ne+1); i++){
K_3[i]=h*y_p[i];
}



// Solution after one step stored in x //
for (i=1; i<(Ne+1); i++){
x[i]=x_0[i]+(1/6)*(K_0[i]+2*K_1[i]+2*K_2[i]+K_3[i]);
}
return ;
}


double clc_f(double t, double* y, double* y_p)
{
double x[N+1];
// Built in first degree equations //

x[1]=y[2];
x[2]=-y[1];

y_p[1]=x[1];
y_p[2]=x[2];



return;
}

קישור לתוכן
שתף באתרים אחרים

ארכיון

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

×
  • צור חדש...