נושאים פעיליםנושאים פעילים  הצגת רשימה של חברי הפורוםרשימת משתמשים  חיפוש בפורוםחיפוש  עזרהעזרה
  הרשמההרשמה  התחברותהתחברות RSS עדכונים
תיכנות
RSS UnderWarrior Forums : RSS תיכנות
נושא

נושא: שאלה ב++C - מערכים ושגרות

שליחת תגובהשליחת נושא חדש
כותב
הודעה << נושא קודם | נושא הבא >>
שני
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 06 December 2007 בשעה 23:32 | IP רשוּם
ציטוט שני

היי, שאלה: כששולחים מערך לשגרה בצורה הבאה  (func(arrVec

אז כשהשגרה מחזירה את הוקטור היא מחזירה אותו עם השינויים שנעשו בו בשגרה, או שעליי לכתוב (func(&arrVec ?

תודה לעונים 

חזרה לתחילת העמוד הצג את כרטיס החבר של שני חפש הודעות אחרות של שני בקר בדף הבית של שני
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 07 December 2007 בשעה 00:18 | IP רשוּם
ציטוט אלצ'קו

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


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 07 December 2007 בשעה 01:58 | IP רשוּם
ציטוט שני

מערך חד מימדי.... איזה תיעוד?מה...?  

חזרה לתחילת העמוד הצג את כרטיס החבר של שני חפש הודעות אחרות של שני בקר בדף הבית של שני
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 07 December 2007 בשעה 09:54 | IP רשוּם
ציטוט אלצ'קו

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


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 07 December 2007 בשעה 21:34 | IP רשוּם
ציטוט לוק

נתוני המערך ישתנו,
כידוע שם המערך הוא מצביע לאיבר הראשון בו וכמו כן שאר איבריו נמצאים ברצף
בזיכרון, מכאן שהעברת מערך by value תעביר את הכתובת לאיבר הראשון וזו שקולה
להעברת כל איברי המערך by reference.

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

הצטרף / הצטרפה: 12 January 2005
מדינה: Israel
משתמש: מנותק/ת
הודעות: 3296
נשלח בתאריך: 08 December 2007 בשעה 16:45 | IP רשוּם
ציטוט ניר

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

__________________
מספר האייסיקיו שלי ו/או כתובת ה-MSN שלי אינם מהווים מוקד תמיכה
חזרה לתחילת העמוד הצג את כרטיס החבר של ניר חפש הודעות אחרות של ניר בקר בדף הבית של ניר
 
שני
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 08 December 2007 בשעה 20:07 | IP רשוּם
ציטוט שני

אלצ'קו כתב:
ומה ה-prototype של הפונקציה שלך?

ה-prototype : 

;ׁ([void func(int arrVec[VEC_SIZE



.

חזרה לתחילת העמוד הצג את כרטיס החבר של שני חפש הודעות אחרות של שני בקר בדף הבית של שני
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 09 December 2007 בשעה 22:54 | IP רשוּם
ציטוט אלצ'קו

שני כתב:

אלצ'קו כתב:
ומה ה-prototype של הפונקציה שלך?

ה-prototype : 

;ׁ([void func(int arrVec[VEC_SIZE



.



במקרה הזה אם תשני את arrVec* או את [arrVer[x אז זה ייראה גם מחוץ לפונקציה.
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 09 December 2007 בשעה 22:55 | IP רשוּם
ציטוט אלצ'קו

לוק כתב:

נתוני המערך ישתנו,
כידוע שם המערך הוא מצביע לאיבר הראשון בו וכמו כן שאר איבריו נמצאים ברצף
בזיכרון, מכאן שהעברת מערך by value תעביר את הכתובת לאיבר הראשון וזו שקולה
להעברת כל איברי המערך by reference.



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


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 10 December 2007 בשעה 14:37 | IP רשוּם
ציטוט שני

תודה!
חזרה לתחילת העמוד הצג את כרטיס החבר של שני חפש הודעות אחרות של שני בקר בדף הבית של שני
 
לוק
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 10 December 2007 בשעה 17:16 | IP רשוּם
ציטוט לוק

 

אלצ'קו כתב:
...אבל במקרים מסויימים...

הייתי רוצה דוגמה מתי זה לא קורה...

חזרה לתחילת העמוד הצג את כרטיס החבר של לוק חפש הודעות אחרות של לוק בקר בדף הבית של לוק
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 11 December 2007 בשעה 20:32 | IP רשוּם
ציטוט אלצ'קו

לוק כתב:

 

אלצ'קו כתב:
...אבל במקרים מסויימים...

הייתי רוצה דוגמה מתי זה לא קורה...



בבקשה. קרא: http://c-faq.com/aryptr/index.html
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
שני
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 11 December 2007 בשעה 21:06 | IP רשוּם
ציטוט שני

רגע אז מה החלטנו...?

אם אני שולחת שגרה בצורה הבאה => (func(arrVec

כשה-prototype של השגרה הוא:  ;ׁ([void func(int arrVec[VEC_SIZE

המערך יחזור עם השינויים שהוא עבר בפונקציה?

חזרה לתחילת העמוד הצג את כרטיס החבר של שני חפש הודעות אחרות של שני בקר בדף הבית של שני
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 11 December 2007 בשעה 21:16 | IP רשוּם
ציטוט אלצ'קו

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


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 11 December 2007 בשעה 21:59 | IP רשוּם
ציטוט שני

מה הכוונה אין משמעות? אני חייבת אותו להצהרה של השגרה לא?
חזרה לתחילת העמוד הצג את כרטיס החבר של שני חפש הודעות אחרות של שני בקר בדף הבית של שני
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 11 December 2007 בשעה 22:28 | IP רשוּם
ציטוט אלצ'קו

לא. את לא חייבת.
הבאתי קישור למעלה.
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
לוק
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 12 December 2007 בשעה 13:16 | IP רשוּם
ציטוט לוק

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


 

חזרה לתחילת העמוד הצג את כרטיס החבר של לוק חפש הודעות אחרות של לוק בקר בדף הבית של לוק
 
לוק
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 12 December 2007 בשעה 13:46 | IP רשוּם
ציטוט לוק

אלצ'קו קראתי ואין שם שום דבר שיכול לרמוז על מתי זה לא קורה.

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

 



 

חזרה לתחילת העמוד הצג את כרטיס החבר של לוק חפש הודעות אחרות של לוק בקר בדף הבית של לוק
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 12 December 2007 בשעה 18:28 | IP רשוּם
ציטוט אלצ'קו

לוק כתב:

אלצ'קו קראתי ואין שם שום דבר שיכול לרמוז על מתי זה לא קורה.

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

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


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 12 December 2007 בשעה 22:33 | IP רשוּם
ציטוט לוק

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

;{int array[4] ={1,2,3,4
;[int *ptr = &array[0

;"!if(array != ptr) cout<<"your'e right
;"!else cout<<"your'e wrong

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

חזרה לתחילת העמוד הצג את כרטיס החבר של לוק חפש הודעות אחרות של לוק בקר בדף הבית של לוק
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 12 December 2007 בשעה 22:53 | IP רשוּם
ציטוט אלצ'קו

תראה, חבוב, אתה מביך את עצמך כאן, ולא שום דבר מעבר לזה.
העובדה הפשוטה היא שהקוד הבא פולט שני מספרים שונים:
קוד:
#include <iostream>

int main() {
    int *p = new int[7];
    int a[7];

    std::cout << sizeof(p) << std::endl;
    std::cout << sizeof(a) << std::endl;
    return 0;
}

בעוד שאם המערך a היה "מתנוון" למצביע, הגודל שלו היה צריך להיות זהה לגודל של המצביע p.

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


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 12 December 2007 בשעה 23:06 | IP רשוּם
ציטוט לוק

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

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

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 12 December 2007 בשעה 23:12 | IP רשוּם
ציטוט אלצ'קו

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


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 13 December 2007 בשעה 00:08 | IP רשוּם
ציטוט לוק

חחחחחחח "מערך אמיתי למצביע"........

התכוונת בין מערך דינאמי לסטאטי...לא?!

"העובדה הפשוטה" היא שמפעילים sizeof על מצביע ולא משנה אם הוא לקובץ למערך
למשתנה פרימטיבי ל-struct או אובייקט. הוא תמיד יחזיר את גודל המצביע ולא שטח
הזיכרון שהוא מצביע עליו. אבל אתה לא יודע מה sizeof עושה....

חזרה לתחילת העמוד הצג את כרטיס החבר של לוק חפש הודעות אחרות של לוק בקר בדף הבית של לוק
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 13 December 2007 בשעה 20:32 | IP רשוּם
ציטוט אלצ'קו

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

נשתמש בואריאציה קלה של הקוד שכתבת למעלה:
קוד:
#include <iostream>

int main() {
    int array[4] = {1,2,3,4};
    int *ptr = &array[0];
   
    if (sizeof(array) != sizeof(ptr)) std::cout << "your'e right" << std::endl;
    else std::cout << "your'e wrong!" << std::endl;

    return 0;
}


הקורא האינטליגנט ינחש מה יהיה הפלט של התוכנית. קטע קוד קטן זה מדגים בבירור שהמערך array והמצביע ptr אינם interchangeable. כלומר, לא בכל מקום שבו כתוב שם של מערך, ניתן להחליף את שם המערך במצביע לאיבר הראשון שבו.

האשכול שוחרר.
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
TheOne
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 18 December 2007 בשעה 02:05 | IP רשוּם
ציטוט TheOne

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

שאתה אומר זה לא תמיד הולך שמשווים?

חזרה לתחילת העמוד הצג את כרטיס החבר של TheOne חפש הודעות אחרות של TheOne בקר בדף הבית של TheOne
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 18 December 2007 בשעה 02:24 | IP רשוּם
ציטוט אלצ'קו

TheOne כתב:

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

שאתה אומר זה לא תמיד הולך שמשווים?



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


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 18 December 2007 בשעה 15:37 | IP רשוּם
ציטוט TheOne

סליחה

הכוונה היתה לכתובת לאיבר הראשון

פשוט אני לומד C עכשיו והמרצה שלי אמר אותו דבר כמו לןק

אתה כתבת "לא בכל מקום שבו כתוב שם של מערך, ניתן להחליף את שם המערך במצביע לאיבר הראשון שבו."

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

חזרה לתחילת העמוד הצג את כרטיס החבר של TheOne חפש הודעות אחרות של TheOne בקר בדף הבית של TheOne
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 18 December 2007 בשעה 21:50 | IP רשוּם
ציטוט אלצ'קו

"בכל פעם" - לא. כפרמטר לפונקציה - כן.
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
TheOne
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 18 December 2007 בשעה 22:48 | IP רשוּם
ציטוט TheOne

סליחה שאני מטריד אותך

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

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

הריצה במחסנית וערימה או משהו כזה שלא הבנתי אתה יכול להסביר לי?

ועד שאלה חוץ מsizeof יש עוד משהו שזה לא עובד בו? 

חזרה לתחילת העמוד הצג את כרטיס החבר של TheOne חפש הודעות אחרות של TheOne בקר בדף הבית של TheOne
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 19 December 2007 בשעה 13:16 | IP רשוּם
ציטוט אלצ'קו

כמובן:
קוד:
#include <iostream>

void f(char arr[]) {
    arr = "fghij";
}

int main() {
    char array[] = "abcde";

    array = "fghij";

    f(array);

    return 0;
}


השורה של ההשמה למערך לא תתקמפל, כי מערך הוא לא "modifiable lvalue". לעומת זאת, ההשמה בתוך הפונקציה חוקית לחלוטין, כי מותר לבצע השמה למצביעים.
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
TheOne
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 19 December 2007 בשעה 21:08 | IP רשוּם
ציטוט TheOne

זה אמור לשנות את המערך מחוץ לפונקציה?

מה לגבי המחסנית והערימה הזאת?

חיפשתי לגבי הsizeof בכל הפורומים שראיתי כתוב שזה אופרטור של "זמן קימפול" אתה יכול לעזור להבין את זה?

"sizeof is a compile-time operator that returns the size, in bytes, of the variable or parenthesized type-specifier that it precedes"

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

חזרה לתחילת העמוד הצג את כרטיס החבר של TheOne חפש הודעות אחרות של TheOne בקר בדף הבית של TheOne
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 19 December 2007 בשעה 21:47 | IP רשוּם
ציטוט אלצ'קו

לא, זה לא אמור. נתחיל מהשאלה לגבי sizeof: המשמעות של "אופרטור זמן קימפול" היא שהתוצאה של השימוש ב-sizeof נקבעת בזמן הקימפול, וערך קבוע נכנס לתוך הבינארי שלך. כשאתה כותב:
קוד:
size_t size = sizeof(identifier);

בזמן קימפול המהדר בודק מהו הטיפוס של identifier, ויוצר קוד מכונה שעושה MOV של ערך קבוע (שמחושב בזמן הקומפילציה) לתוך הכתובת שמיוצגת על ידי שם המשתנה size.

לגבי הקוד האחרון מלמעלה: הוא לא אמור לשנות את ערך המערך מחוץ לפונקציה. נעבור על קדוש שורה-שורה:
קוד:
void f(char arr[]);

כאן יש לנו פונקציה שלא מחזירה ערך, ומקבלת מצביע ל-char. כשכתוב ברשימת הפרמטרים של פונקציה שיש "מערך" (כלומר, כתוב type identifier[]‎) בעצם הכוונה היא למצביע ולא למערך.
קוד:
char array[] = "abcde";

מוגדר מערך בשם array בגודל 6 בתים שמכיל את התווים 'a', 'b', 'c', 'd', 'e', '\0'. המיקום של המערך איננו ידוע (יותר מידע על כך בהמשך).
קוד:
f(array);

כאן קוראים לפונקציה f שהוזכרה קודם. כשמערכים מועברים לפונקציות, בעצם מועבר מצביע לאיבר הראשון שלהם, כך שהקריאה הזו שקולה לקריאה:
קוד:
f(&array[0]);

ועכשיו לפונקציה עצמה:
קוד:
void f(*char arr) {
    arr = "fghij";
}

יש לנו פונקציה שמקבלת מצביע ל-char. הפונקציה משנה את ערך המצביע כך שיצביע למחרוזת "fghij". זה לא משנה שום דבר מחוץ לפונקציה. הפונקציה שינתה משתנה פנימי שלה, כך שיצביע למקום אחד במקום למקום אחר. לעומת זאת, אם הפונקציה הייתה משנה את המקום אליו מצביע המצביע, זה היה נראה מחוץ לפונקציה. לדוגמה:
קוד:
void f(char arr[]) {   
    *arr='f';
}

הקוד הזה עשוי לשנות את 'a' מתחילת המחרוזת ל-'f', כך שכעת המחרוזת תהיה "fbcde", או:
קוד:
void f(char arr[]) {   
    strcpy(arr, "fghij");
}

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

עכשיו לגבי סוגי זיכרון, ובפרט, המחסנית והערימה. הזיכרון מחולק לכל מיני אזורים, ברמת המעבד וברמת מערכת ההפעלה. שני מיקומי זיכרון שמקובל לדבר עליהם הם המחסנית והערימה.
  • המחסנית היא אזור הזיכרון בו נמצאים כל המשתנים של פונקציה וכל הארגומנטים שהיא מקבלת. לאחר הקריאה לפונקציה הם נמחקים משם. הגישה המקובלת היא שדוחפים למחסנית (ממש כמו למבנה הנתונים מחסנית) את הארגומנטים שהפונקציה אמורה לקבל, ואז מבצעים קריאה לפונקציה. הקריאה לפונקציה דוחפת את כתובת החזרה מהפונקציה למחסנית, ואז "קופצת" אל הפונקציה עצמה. הפונקציה דוחפת למחסנית את המשתנים שלה, ובמידה והיא רוצה לקרוא לעוד פונקציה דוחפת את הפרמטרים שלה וקוראת לה. כשהפונקציה חוזרת, היא מוציאה את כל המשתנים שלה מהמחסנית, ואז מבצעת את פעולה החזרה מפונקציה. הפעולה הזו מוציאה מהמחסנית את ערך החזרה שהוכנס לשם בקריאה, וקופצת אליו.
  • הערימה היא המון זיכרון שניתן לבקש חלקים ממנו לצרכים שונים, וצריך לשחרר אותו כשמסיימים לעבוד איתו. בניגוד למשתנים על המחסנית, משתנים על הערימה לא משוחררים אוטומטית. כשאתה רוצה לקבל מקום על הערימה אתה משתמש באחת מפונקציות ה-xalloc, ומקבל מצביע למקום שמוקצה לך על הערימה. בסוף עליך לשחרר אותו באמצעות free.
ישנם עוד מספרי אזורי זיכרון מקובלים. לדוגמה:
  • בלוק ה-CODE, לתוכו נטען הקוד של התוכנית שלך.
  • בלוק ה-DATA שמכיל קבועים.
שני הבלוקים הספציפיים הללו עשויים להיות מוגנים בפני כתיבה, לשם הגנה. זה מחזיר אותנו למה שהזכרתי למעלה. אם הפונקציה f תשנה לשנות את המידע אליו מצביע הפרמטר שהיא קיבלה, התוכנה עלולה לקרוס. המערך array עשוי להיות מוקצה באזור ה-DATA, או באזור אחר שניתן רק לקרוא ממנו (זה נכון לגבי כל הקבועים בתוכנה שלך, בין אם מספריים, ובין אם מחרוזות, כמו "abcde" ו-"fghij" מהקוד למעלה). ברגע שתנסה לכתוב לאזור הזה, מערכת ההפעלה תגיד לתוכנה שלך שלום, ותסגור אותה.
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
TheOne
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 21 December 2007 בשעה 00:17 | IP רשוּם
ציטוט TheOne

ואוו תודה רבה רבה אלצ'קו.

אחרי שהסברת ממש ממש טוב הבנתי את זה. 

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

במקרה של sizeof זה לא הופך לפויינטר בגלל שזה אופרטור של זמן קימפול שיודע לפני

הריצה כמה גודל ביקשו לכל מערך.

ואוו תודה.

חזרה לתחילת העמוד הצג את כרטיס החבר של TheOne חפש הודעות אחרות של TheOne בקר בדף הבית של TheOne
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 21 December 2007 בשעה 09:19 | IP רשוּם
ציטוט אלצ'קו

אין שום קשר ל"אופרטורים של זמן קימפול". תקרא שוב את הקוד מלמעלה:
קוד:
#include <iostream>

void f(char* arr) {
    arr = "fghij";
}

int main() {
    char array[] = "abcde";

    array = "fghij";

    f(array);

    return 0;
}

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

אם ברצונך להגיב לנושא זה עליך קודם להתחבר
אם אינך רשום/ה כבר עליך להרשם

  שליחת תגובהשליחת נושא חדש
גרסת הדפסה גרסת הדפסה

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