הרצאה 10 פונקציות עם מספר משתנה של פרמטרים

Slides:



Advertisements
Similar presentations
קבצים קרן כליף.
Advertisements

Pointers הרצאה קריטית. השאלות הפתוחות מה זה ה- & שמופיע ב scanf מדוע כשמעבירים מחרוזת ל scanf אין צורך ב & האם ניתן להכריז על מערך שגדלו אינו ידוע בתחילת.
תכנות תרגול 6 שבוע : חישוב e זוהי הנוסחא לחישוב e נראה כיצד לתרגם אותה לפונקציה n n.
תכנות תרגול 4 שבוע : לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
תכנות תרגול 2 שבוע : שבוע שעבר כתבו תוכנית המגדירה שלושה משתנים מאתחלת אותם ל 1 2 ו 3 ומדפיסה את המכפלה שלהם את ההפרש שלהם ואת הסכום שלהם.
מבוא לשפת C חידות ונקודות חשובות נכתב על-ידי יורי פקלני. © כל הזכויות שמורות לטכניון – מכון טכנולוגי לישראל.
11 Introduction to Programming in C תרגול
מבוא למדעי המחשב תרגול 8 - מחרוזות שעת קבלה : יום שני 11:00-12:00 דוא " ל :
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
מבוא למדעי המחשב © אריק פרידמן 1 מצביעים כמערכים דוגמה.
תכנות תרגול 6 שבוע : תרגיל שורש של מספר מחושב לפי הסדרה הבאה : root 0 = 1 root n = root n-1 + a / root n-1 2 כאשר האיבר ה n של הסדרה הוא קירוב.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
תכנות תרגול 6 שבוע : הגדרת פונקציות return-value-type function-name(parameter1, parameter2, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
תכנות תרגול 5 שבוע : לולאות for לולאות for for (counter=1 ;counter
תכנות תרגול 14 שבוע : רשימות מקושרות ישנו מבנה נתונים אשר מאפשר ישנו מבנה נתונים אשר מאפשר לנו לבצע את הוספת האיברים בצורה נוחה יותר. מבנה זה.
מבוא כללי למדעי המחשב תרגול 3. לולאות while לולאות while while (condition) { loop body } במקרה של קיום התנאי מתבצע גוף הלולאה ברגע שהתנאי לא מתקיים נצא.
קורס תכנות – סימסטר ב ' תשס " ח שיעור שישי: מערכים
מבוא כללי למדעי המחשב תרגול 5. חישוב e זוהי הנוסחא לחישוב e נראה כיצד לתרגם אותה לפונקציה n n.
מבוא למדעי המחשב תרגול 6 - מערכים שעת קבלה : יום שני 11:00-12:00 דוא " ל :
תכנות תרגול 5 שבוע : הגדרת פונקציות return-value-type function-name(parameter1, parameter2, …) הגדרת סוג הערכים שהפונקציה מחזירה שם הפונקציהרשימת.
מערכים עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר int grade1, grade2, …, grade20; int grade1, grade2, …, grade20;
עקרון ההכלה וההדחה.
תכנות תרגול 4 שבוע : לולאות for לולאות for for (counter=1 ;counter
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב' Templates תבניות.
מבוא למדעי המחשב תרגול 3 שעת קבלה : יום שני 11:00-12:00 דוא " ל :
1 מבוא למדעי המחשב סיבוכיות. 2 סיבוכיות - מוטיבציה סידרת פיבונאצ'י: long fibonacci (int n) { if (n == 1 || n == 2) return 1; else return (fibonacci(n-1)
Sscanf example #include int main () { char sentence []="Rudolph is 12 years old"; char str [20]; int i; sscanf (sentence,"%s %*s %d",str,&i); printf ("%s.
Structure. מה לומדים היום ? דרך לבנות מבנה נתונים בסיסי – Structure מייצר " טיפוס " חדש מתאים כאשר רוצים לאגד כמה משתנים יחד דוגמאות : עובד : שם, טלפון,
הגדרת משתנים יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר 2015 יום שישי 18 ספטמבר.
Variable Argument Lists CS 112 (slides from Marc Lihan)
Void*, pointer to functions, variadic functions קרן כליף.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 12. ספריות.
סיביות קרן כליף. © Keren Kalif 2 ביחידה זו נלמד:  מוטיבציה  אופרטורים לעבודה עם סיביות:  &  |  ^  ~  >> 
מבנים קרן כליף. ביחידה זו נלמד :  מהו מבנה (struct)  איתחול מבנה  השמת מבנים  השוואת מבנים  העברת מבנה לפונקציה  מבנה בתוך מבנה  מערך של מבנים.
1 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
© Keren Kalif JDBC קרן כליף.
מספרים אקראיים ניתן לייצר מספרים אקראיים ע"י הפונקציה int rand(void);
C Programming.
Programming Arrays.
מבני נתונים רשימה מקושרת, מחסנית ותור
מבוא למדעי המחשב לתעשייה וניהול
תכנות מכוון עצמים ו- C++ יחידה 11 תבניות - templates
מבוא למדעי המחשב סיבוכיות.
הקצאות דינאמיות בשילוב מבנים
מ- JAVA ל- C קרן כליף.
מיונים וחיפושים קרן כליף.
מחרוזות קרן כליף.
מצביעים קרן כליף.
תירגול 14: מבני נתונים דינאמיים
הרצאה 06 רשימות מקושרות קרן כליף.
תכנות מכוון עצמים ושפת JAVA
קבצים קרן כליף.
הקצאות דינאמיות קרן כליף.
פונקציות קרן כליף.
מבנים קרן כליף.
פונקציות קרן כליף.
תכנות מכוון עצמים בשפת JAVA
שיעור שישי: מחרוזות, מצביעים
הרצאה 08 פרמטרים ל- main קרן כליף.
מצביעים קרן כליף.
פונקציות קרן כליף.
שאלה 1.
ניתוח מערכות מידע תכנות ב C#
מבוא כללי למדעי המחשב תרגול 4
תכנות מכוון עצמים ושפת JAVA
כתיבת מאקרו הפקודה assert מצביעים לפונקציות
סוגי משתנים קרן כליף.
מחרוזות קרן כליף.
מבוא לתכנות ב- Java תרגול 10 - רשימות מקושרות.
Strings #include <stdio.h>
Presentation transcript:

הרצאה 10 פונקציות עם מספר משתנה של פרמטרים קרן כליף

ביחידה זו נלמד: מהי Variadic Function השימוש ב- va_list va_start va_arg va_end © Keren Kalif

Variadic Function עד היום ראינו כי בהגדרת הפונקציה יש להגדיר את כמות הפרמטרים שעליה לקבל, ויש לשלוח לה בדיוק כמות זו ארגומנטים Variadic Function היא פונקציה היכולה לקבל מספר משתנה של פרמטרים בכל פעם: variable argument list למשל, נוכל לכתוב פונקציה המחשבת ממוצע, ופעם נעביר לה 4 מספרים, ופעם 8, עם אותו קוד, ובלי להעמיס על המשתמש לייצר עבורנו מערך (הפרמטר הראשון הוא כמות המספרים המועברים): calcAverage(4,3,4,7,2); calcAverage(8,3,4,7,2,8,2,3,4); דוגמא ל- Variadic Function שאנחנו מכירים: printf, scanf © Keren Kalif

כלים למימוש Variadic Function בספריה stdarg.h ישנם המאקרו הבאים הנדרשים לכתיבת Variadic Function: va_list – טיפוס חדש שיכיל את רשימת הפרמטרים המשתנה שהועברה לפונקציה va_start – מאקרו שתפקידו לאתחל את הרשימה הנ"ל החל מפרמטר מסויים כל Variadic Function צריכה לקבל לפחות פרמטר אחד va_arg – מאקרו שתפקידו להביא את האיבר הבא מהרשימה va_end - מאקרו שתפקידו לשחרר את איברי הרשימה שהוקצתה ע"י va_list © Keren Kalif

דוגמא למימוש Variadic Function #include <stdio.h> #include <stdarg.h> double calcAverage(int count, ...) { va_list numbers; int sum=0, i; va_start(numbers, count); for(i=0 ; i < count; i++) sum += va_arg(numbers, int); va_end(numbers); return (float)sum/count; void main() } float avg; avg = calcAverage(4,3,4,7,2); printf("Average is %.3f\n", avg); avg = calcAverage(8,3,4,7,2,8,2,3,4); ציון שפה יכולה לבוא כל כמות של ארגומנטים דוגמא למימוש Variadic Function הגדרת משתנה עבור רשימת הפרמטרים אתחול רשימת הפרמטרים מהפרמטר אחרי הפרמטר count קבלת האיבר הבא מהרשימה וציון מטיפוס שלו שחרור הרשימה © Keren Kalif

דוגמא נוספת – הדפסת משפט #include <stdio.h> #include <stdarg.h> void printSentence(char* word, ...) { va_list allWords; char* currentWord; va_start(allWords, word); currentWord = word; while (currentWord != NULL) printf("%s ", currentWord); currentWord = va_arg(allWords, char*); printf("\n"); va_end(allWords); void main() } printSentence("This", "is", "a", "nice", "feature", "in", "C", NULL); דוגמא נוספת – הדפסת משפט © Keren Kalif

דוגמא למימוש כך שכל פרמטר מטיפוס שונה #include <stdio.h> #include <stdarg.h> void printGrades(char* className, char* name, ...) } va_list params; char* currentName; int currentGrade; printf("The stuedents' grades in class %s\n", className); va_start(params, name); currentName = name; while (currentName != NULL) currentGrade = va_arg(params, int); printf("%-10s -->%d\n", currentName, currentGrade); currentName = va_arg(params, char*); { va_end(params); void main() printGrades("Advanced C", "gogo", 100, "momo", 95, "yoyo", 97, NULL); דוגמא למימוש כך שכל פרמטר מטיפוס שונה © Keren Kalif

נשים לב שהציון מוגדר כ- double #include <stdio.h> #include <stdarg.h> void printGrades(char* className, char* name, ...) } va_list params; char* currentName; int currentGrade; printf("The stuedents' grades in class %s\n", className); va_start(params, name); currentName = name; while (currentName != NULL) currentGrade = va_arg(params, int); printf("%-10s -->%d\n", currentName, currentGrade); currentName = va_arg(params, char*); { va_end(params); void main() printGrades("Advanced C", "gogo", 100, "momo", 95.7, "yoyo", 97, NULL); casting לא נכון בדוגמא זו התוכנית תעוף כי הקומפיילר לא מצליח לקרוא את הנתון מהטיפוס המבוקש ולכן נכשל בקריאה נשים לב שהציון מוגדר כ- double © Keren Kalif

המימוש של printf #include <stdio.h> #include <stdarg.h> #define MAX_DIGITS 10 void myPrints(const char *string); void myPrinti(int num); void myPrintf(const char *format, ...); void main() { int num = 12, num2 = -95; char ch = 'A'; myPrintf("%d %c hello %s %d\n", num, ch, "keren", num2); void myPrints(const char *string) for ( ; *string != '\0' ; ++string) putchar(*string); © Keren Kalif

המימוש של printf (2) void myPrintf(const char *format, ...) } va_list params; va_start(params, format); for ( ; *format != '\0' ; ++format) if (*format == '%') ++format; switch (*format) case 's': { char *s = va_arg(params, char*); myPrints(s); break; case 'd': } int num = va_arg(params, int); myPrinti(num); break; { case 'c': char ch = va_arg(params, char); putchar(ch); } // case else putchar(*format); { // for va_end(params); © Keren Kalif

המימוש של printf (3) // print a number to screen without 'printf' command void myPrinti(int num) } char printBuf[MAX_DIGITS]; char *s; int digit, isNegative = 0; unsigned int u = num; if (num == 0) putchar('0'); return; { if (num < 0) isNegative = 1; u = -num; s = printBuf + MAX_DIGITS - 1; *s = '\0'; while (u) } digit = u % 10; *--s = digit + '0'; u /= 10; { if (isNegative) *--s = '-'; myPrints(s); © Keren Kalif

דוגמא בשילוב void* כתוב פונקציה המקבלת את הפרמטרים הבאים: מחרוזת המייצגת שם של טיפוס (int, char, double) int* שהפונקציה תעדכן בו אורך של מערך מספר אינו ידוע של מערכים מהטיפוס שהתקבל. האיבר האחרון צריך להיות NULL הפונקציה תייצר מערך חדש באורך כמות המערכים שהתקבלו, ותשים בכל איבר את האיבר הראשון מהמערך המתאים ברשימה דוגמא: int arr1[]={1,2,3}, arr2[]={6,3,7,8,2}, arr3[]={8,7,6,5}; int* newArr = createArrayFromFirstElem("int", &size, arr1, arr2, arr3, NULL);  יווצר מערך מטיפוס int עם 3 איברים: 1, 6, 8 © Keren Kalif

va_start(arrays, size); if (strcmp(type, "int") == 0) { newArr = (int*)malloc(*size*sizeof(int)); for (i=0 ; i < *size ; i++) ((int*)newArr)[i] = va_arg(arrays, int*)[0]; } else if (strcmp(type, "char") == 0) { newArr = (char*)malloc(*size*sizeof(char)); ((char*)newArr)[i] = va_arg(arrays, char*)[0]; else if (strcmp(type, "double") == 0) { newArr = (double*)malloc(*size*sizeof(double)); ((double*)newArr)[i] = va_arg(arrays, double*)[0]; else // invalid array type.. newArr = NULL; va_end(arrays); return newArr; } // createArrayFromFirstElem #include <stdio.h> #include <stdarg.h> #include <string.h> #include <stdlib.h> void* createArrayFromFirstElem( char* type, int* size, void* arr, ...) { int i, arrType; void* currentArr, *newArr; va_list arrays; // count number of arrays va_start(arrays, arr); currentArr = arr; *size = 0; do } (*size)++; currentArr = va_arg(arrays, void*); } while (currentArr != NULL); va_end(arrays); type = strlwr(type); © Keren Kalif

int arr1[]={1,2,3}, arr2[]={6,3,7,8,2}, arr3[]={8,7,6,5}; int size, i; void main() } int arr1[]={1,2,3}, arr2[]={6,3,7,8,2}, arr3[]={8,7,6,5}; int size, i; int* newArr = createArrayFromFirstElem("int", &size, arr1, arr2, arr3, NULL); for (i=0 ; i < size ; i++) printf("%d ", newArr[i]); printf("\n"); free(newArr); { char str1[]="Gogo", str2[]="Ooops!", str3[]="Orange", str4[]="Ding-Dong!"; char* newArr = createArrayFromFirstElem("char", &size, str1, str2, str3, str4, NULL); printf("%c ", newArr[i]); © Keren Kalif

דוגמא משולבת כתוב פונקציה המקבלת זוגות של מחרוזת ומספר. המחרוזת מכילה שם של קובץ בינארי המכיל מספרים והמספר מכיל מיקום של מספר בקובץ (ניתן להניח כי האינדקס אכן קיים בקובץ). עבור כל קובץ הפונקציה תיגש בגישה ישירה למספר באינדקס הנתון, ותוסיף אותו לסכום המצטבר שתחזיר. סיום הפרמטרים יהיה באמצעות NULL. © Keren Kalif

פתרון int getSumFromFiles(const char* fileName, ...) } int sum = 0; const char* currentFileName = fileName; va_list params; va_start(params, fileName); while (currentFileName != NULL) int temp; int currentIndex = va_arg(params, int); FILE* theFile = openAndCheckFile(currentFileName, "rb"); fseek(theFile, currentIndex*sizeof(int), SEEK_SET); fread(&temp, sizeof(int), 1, theFile); printf("The %d'th value from the file %s is %d\n", currentIndex, currentFileName, temp); sum += temp; fclose(theFile); currentFileName = va_arg(params, const char*); { va_end(params); return sum; פתרון © Keren Kalif

ביחידה זו למדנו: מהי Variadic Function השימוש ב- va_list va_start va_arg va_end © Keren Kalif