ABA


"פונקציית ++c שמקבלת מספר כלשהו של משתנים"
גירסת הדפסה        
קבוצות דיון פיתוח, תיכנות ובניית אתרים נושא #5336 מנהל    סגן המנהל    מפקח   Winner    צל"ש   מומחה  
אשכול מספר 5336
liranr

   16:00   10.03.03   
אל הפורום  
  פונקציית ++c שמקבלת מספר כלשהו של משתנים  
 
   נגיד אני רוצה לכתוב פונקציה שמחשבת ממוצע של המספרים שהיא מקבלת.
הבעיה היא שאני רוצה שכל הקריאות הבאות יהיו חוקיות

average(5,6);
average(1,2,3,7);
average(1,2,3,4,5,6,7,8);
...

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


                                שתף        
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד

  האשכול     מחבר     תאריך כתיבה     מספר  
  תנסה עם מערך של aruguments שרון אורן  10.03.03 16:12 1
     מודה ומתוודה שלא הבנתי liranr 10.03.03 16:16 2
         אני לא יודע C++ אני רק יודע שבמקרים כאלה שרון אורן  10.03.03 16:35 4
  עם רשימה אפשר לעשות את זה Cisse 10.03.03 16:26 3
     זה לא ממש מה שרציתי liranr 10.03.03 17:19 5
         בבקשה avi885 10.03.03 18:45 6
             תודה רבה liranr 10.03.03 21:29 7
                 אלו פונקציות מאקרו שכלולות ב- ANSI C. Dudenland 10.03.03 22:10 8
                     תודה רבה על ההסבר liranr 11.03.03 15:21 9
                         אם אתה זוכר בפונקציית הprintf אתה מעביר yoash 11.03.03 20:35 13
             int main AlexKarpman 11.03.03 18:10 10
                 אתה מוסיף את זה כל פעם שאתה רואה liranr 11.03.03 18:42 11
                     אם כולם יכתבו לפי התקן העולם יהיה יפה יותר dryice 11.03.03 20:04 12
                         הרגע גיליתי משהו מוזר liranr 11.03.03 20:58 14
                             printf מיוחד, אבל לא ממש dryice 11.03.03 21:57 15
                                 OK, הבנתי (פחות או יותר) liranr 12.03.03 13:41 16

       
שרון אורן 
חבר מתאריך 27.5.02
259 הודעות
   16:12   10.03.03   
אל הפורום  
  1. תנסה עם מערך של aruguments  
בתגובה להודעה מספר 0
 
  

פתיחת אייפונים נעולים לסים פרי
https://www.unlock-it.co.il


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
liranr

   16:16   10.03.03   
אל הפורום  
  2. מודה ומתוודה שלא הבנתי  
בתגובה להודעה מספר 1
 
   מה הכוונה במערך של arguments?
הכי טוב יהיה אם תוכל לכתוב קטע קצר של קוד (הרי זאת לא פונקציה
מסובכת) שאני יראה מה הכוונה
תודה רבה


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
שרון אורן 
חבר מתאריך 27.5.02
259 הודעות
   16:35   10.03.03   
אל הפורום  
  4. אני לא יודע C++ אני רק יודע שבמקרים כאלה  
בתגובה להודעה מספר 2
 
   ובשפות דומות זה עם arguments

פתיחת אייפונים נעולים לסים פרי
https://www.unlock-it.co.il


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Cisse

   16:26   10.03.03   
אל הפורום  
  3. עם רשימה אפשר לעשות את זה  
בתגובה להודעה מספר 0
 
   אם אתה יודע מה זה...

תכניס את כל המספרים לרשימה ושלח תרשימה


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
liranr

   17:19   10.03.03   
אל הפורום  
  5. זה לא ממש מה שרציתי  
בתגובה להודעה מספר 3
 
   ברור שאפשר לעשות את זה עם רשימה, אבל ככה השליחה לפונקציה הופכת
להיות ארוכה בצורה שלא תאמן - להכניס את כל המספרים לרשימה ואז לשלוח
את הרשימה.

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


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
avi885

   18:45   10.03.03   
אל הפורום  
  6. בבקשה  
בתגובה להודעה מספר 5
 
   עבר עריכה לאחרונה בתאריך 10.03.03 בשעה 19:01
 
זוהי הדרך בה גם מיושמת PRINTF


#include <stdio.h>
#include <stdarg.h>
int average( int first, ... )
{
int count = 0, sum = 0, i = first;
va_list marker;

va_start( marker, first );
while( i != -1 )
{
sum += i;
count++;
i = va_arg( marker, int);
}
va_end( marker );
return( sum ? (sum / count) : 0 );
}

void main()
{
int p;
p = average (2,4,6,-1);
printf("average is %d",p);
}

בכל מקרה חייב להיות פרמטר אחד, ב PRINTF זה מחרוזת בהתחלה
כאן זה 1- בסוף
ניתן לשנות למשל שהראשון יהיה מספר האברים.


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
liranr

   21:29   10.03.03   
אל הפורום  
  7. תודה רבה  
בתגובה להודעה מספר 6
 
   אתה מוכן להסביר טיפה את הקוד. לא נתקלתי מעולם בספרייה stdarg,
ולא הבנתי בדיוק מה עושות va_start,va_arg,va_end


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
Dudenland

   22:10   10.03.03   
אל הפורום  
  8. אלו פונקציות מאקרו שכלולות ב- ANSI C.  
בתגובה להודעה מספר 7
 
   va_list הוא כביכול משתנה של הרשימה, המיועד להכיל את רשימץ הארגומנטים שהועברו לפונקציה.

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

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

va_end מאתחל את הרשימה, אתחול "ניקוי". מה שקורה בפועל, זה שחרור הזיכרון שהוקצה עבור הפוינטר הנ"ל.

יש לזכור כי שימוש בפונקציה מסוג זה, מהווה חור אבטחה (פירצה אפשרית) בתוכנית...כלומר יכול להיגרם Buffer-OverFlow (תוך מילוי המחסנית)...

Dudenland


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
liranr

   15:21   11.03.03   
אל הפורום  
  9. תודה רבה על ההסבר  
בתגובה להודעה מספר 8
 
   אני לא רוצה להיות נודניק, אבל משהו בכל זאת לא מסתדר לי
ב printf אתה מכניס את המחרוזת ואחריה רשימה של משתנים. מספר המשתנים
אינו מוגבל ולא מכניסים שום סימן מיוחד בסוף הקריאה.
אתה יכול (או מישהו) אחר להדגים איך זה יכול לעבוד?
לא ההדפסה עצמה, רק הקטע של הקריאה של המשתנים


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
yoash

   20:35   11.03.03   
אל הפורום  
  13. אם אתה זוכר בפונקציית הprintf אתה מעביר  
בתגובה להודעה מספר 9
 
   אם אתה זוכר בפונקציית הprintf אתה מעביר מחרוזת שכוללת תווי בקרה
אם תספור את תווי הבקה d% וכו' תוכל לדעת כמה משתנים אתה צריך לחפש.

תודה על החומר נושא מעניין שלא הכרתי.


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
AlexKarpman

   18:10   11.03.03   
אל הפורום  
  10. int main  
בתגובה להודעה מספר 6
 
  


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
liranr

   18:42   11.03.03   
אל הפורום  
  11. אתה מוסיף את זה כל פעם שאתה רואה  
בתגובה להודעה מספר 10
 
   void main???
זה כמובן נכון, אבל מזה לא קשור...


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
dryice

   20:04   11.03.03   
אל הפורום  
  12. אם כולם יכתבו לפי התקן העולם יהיה יפה יותר  
בתגובה להודעה מספר 11
 
  


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
liranr

   20:58   11.03.03   
אל הפורום  
  14. הרגע גיליתי משהו מוזר  
בתגובה להודעה מספר 12
 
   בנוסף לפונקציה printf קיימת פונקצייה vprintf (גם בתקן ANSI),
שהתיעוד שלה אומר שהיא עובדת כמו printf רק עם argument list, וזה
אומר ש printf עובדת בדרך אחרת.
אז שוב נשאלת השאלה איך printf עובדת?
(זה לא באמת עד כדי כך חשוב לי, אני סתם סקרן)


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
dryice

   21:57   11.03.03   
אל הפורום  
  15. printf מיוחד, אבל לא ממש  
בתגובה להודעה מספר 14
 
   הC calling convention אומר שפרמטרים לפונקציה מועברים על המחסנית
ע"י הפונקציה הקוראת, זאת כאשר הפרמטר שמופיע אחרון(הכי ימינה)
בהגדרת הפונקציה נדחף ראשון והפרמטר הראשון נדחף אחרון.
(בפסקל זה הפוך)

לאחר שנדחפים הפרמטרים מתבצעת פקודת call שדוחפת את כתובת החזרה
ומבצעת קפיצה לפונקציה.
הדבר הראשון שהפונקציה מבצעת זה לדחוף את הBP על המחסנית ולהעתיק
על גבי הישן את SP
כך יש לנו בBP מצביע לתחילת הstack frame של הפונקציה הנוכחית.
אם נסתכל בBP+2 (כאשר עושים חשבון עם מצביעים 1 זה גודל מילה)
נמצא את הפרמטר הראשון של הפונקציה, עם הפרמטר הראשון הזה הוא במקרה
מחרוזת שמספרת לנו בדיוק כמה פרמטרים יש לפונקציה ומאיזה סוג הם,
וודאי נוכל להסתכל עוד מעלה במחסנית (מחסנית גדלה למטה באינטל) ולמצוא
את כל הפרמטרים.


DRYICE


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
liranr

   13:41   12.03.03   
אל הפורום  
  16. OK, הבנתי (פחות או יותר)  
בתגובה להודעה מספר 15
 
   תודה רבה על ההסבר


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד

תגובה מהירה  למכתב מספר: 
 
___________________________________________________________________

___________________________________________________________________
למנהלים:  נעל | תייק בארכיון | מחק | העבר לפורום אחר | מחק תגובות | עגן אשכול
       



© כל הזכויות שמורות ל-רוטר.נט בע"מ rotter.net