שיחה:שפת C/מצביעים

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

מצביע לפונקציה ומצביע ל-void[עריכה]

למשל:

void sort (void *array, int nelem, int width, int *(func(void *,void *)));

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

  1. מצביע ל-void שמתאר את המערך (מצביע ל-void יכול להצביע להכול, לכן אי אפשר לעשות בו פעולות חשבוניות ללא המרה (דרך אגב, למה אין בספר הזה על המרה?))
  2. שני משתנים מסוג int אשר קובעים מה האורך של המערך ומה הגודל של כל איבר שבתוכו
  3. מצביע לפונקציה שמקבלת שני מצביעים מסוג void ומחזירה int, ועל פיה המערך ממוין. (למצביע במקרה הזה קוראים func)

87.69.216.112 09:16, 19 בספטמבר 2006 (IDT)

זה הוסף לדף החדש שפת C/מצביעים, מערכים, ופונקציות. Thedsadude 20:20, 20 בדצמבר 2007 (IST)
> למה אין בספר הזה על המרה?
הכוונה לזה? https://he.wikibooks.org/wiki/שפת_C/מצביעים,_מערכים,_ופונקציות#המרת_מצביע_לתו

int* can be confusing[עריכה]

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

int* pointer, i_think_its_a_pointer_coz_im_n00b_but_i'm_mistaken;

אני חושב שיש מקום להוסיף איזה good programming habit קטן בפסקה המדוברת.

גם אני חושב כמוך, אך יש על כך וויכוחים מכאן ועד הודעה חדשה. אין קונצנזוס לgood programming habit בנושא (אם כי, שוב, דעתי כדעתך בנקודה). Thedsadude 07:24, 29 בנובמבר 2007 (IST)
הוספתי נושא על עניינים סגנוניים, ואציג את הטענות לכאן ולכאן.Thedsadude 11:36, 30 בנובמבר 2007 (IST)

הקשר בין מערכים למצביעים[עריכה]

בנושא יש אמירה ששמו של מערך הוא משתנה שמכיל את כתובת תחילת המערך. אינני חושב כך. שמו של מערך הוא 'קבוע שמכיל את כתובת תחילת המערך.Thedsadude 11:36, 30 בנובמבר 2007 (IST)

שיניתי. Thedsadude 12:47, 11 בדצמבר 2007 (IST)

פיצול הפרק[עריכה]

הפרק לדעתי ארוך מדי. ארכו חורג מזה של שאר הפרקים, יש המון חומר עד לתרגיל הראשון, הוא מכיל חומר ברמות מגוונות (לדוגמה, מצביעים לפונקציות הוא נושא מבלבל למתחילים), וכו'. לדעתי יש לפצל את הפרק. הצעות? תגובות? Thedsadude 12:47, 11 בדצמבר 2007 (IST)

מסכים איתך בעניין. אני חושב שהמקום להתעסק במצביעים לפונקציות (ואולי גם ל-void) צריך להיות בפרק מתקדם הרבה יותר, כחלק מהנושא של (הנסיון ל-)תכנות מונחה עצמים ב-c. כדאי, סתם לשם הנוחות, לקצץ את הפרק לשניים או שלושה חלקים. Johnny Zoo 14:04, 14 בדצמבר 2007 (IST)
יופי. הוספתי עוד פרקון בנוגע למחסנית הזיכרון, ואני מקווה למלא את תוכנו בשבוע הקרוב. נראה לי נכון לפצל את הפרק כך שחשבון מצביעים, מצביעים ומערכים, מצביעים קבועים, מצביעים לvoid, ומצביעים לפונקציות יעברו לפרק אחר. זו לא החלוקה ההגיונית היחידה, אבל נראה לי שללא הנושאים הללו, אפשר לבנות פרק עם רעיון מרכזי קוהרנטי, אורך נורמאלי, וכמות חומר סבירה עד לתרגיל הראשון. בפרק האחר יהיו שני רעיונות מרכזיים: הקשר בין מצביעים למערכים, וגמישות ביחס לפונקציות (מצביעים לפונקציות ומצביעים לvoid שניהם עוסקים בכך בעיקר). נראה לי להשאיר דגל "שקול לדלג" על החצי השני של הפרק הבא. הצעות ותגובות יתקבלו כרגיל בשמחה, בפרט על שם הפרק החדש. אגב, סחתיין על ספר הJava.
Thedsadude 15:30, 14 בדצמבר 2007 (IST)
טוב, אז זה עבר לשפת C/מצביעים, מערכים, ופונקציות. Thedsadude 10:54, 16 בדצמבר 2007 (IST)

תוספת ביאור[עריכה]

"הסיבה לכך שנכשלנו היא שהשתמשנו בcall by value, כלומר שיטת העברת נתונים לפוקנציות בה מעתיקים ערכי משתנים לארגומנטים של הפונקציה."

המשפט לא מובן (אמנם המעיין אח"כ יבין אבל עדיין נראה שצריך פירוט מעט יותר גם בשלב זה), מדוע לא הוחלפו הערכים?

אליהו52ק 14:58, 13 בדצמבר 2007 (IST)

ניסחתי מחדש, מקווה שעכשיו זה ברור יותר. Johnny Zoo 17:12, 13 בדצמבר 2007 (IST)
תודה רבה! באמת ברור מאוד!


יש לי עוד שתי שאלות:


  1. ציטוט:


כדי להשתמש בקבוע NULL, אפשר לרשום בראשי הקבצים המשתמשים בו:<include <stddef.h#


לא הבנתי האם צריך לרשום או לא? מה ישתנה אם אני ירשום? (בסביבת פיתוח שלי DEY C ++ לא הצלחתי למצוא שינוי).


  1. ציטוט:


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


האם זאת מגבלת תקן או מגבלה בעצם השפה? (המהדר שלי (סביבת פיתוח DEY C++) לא מודיע על שגיאה, וכן התוכנית רצה יפה,
יכול להיות שיש בעיה נסתרת רק שאני לא יודע עליה).


תודה מראש אליהו52ק 11:36, 16 בדצמבר 2007 (IST)
שלום,
  1. הספריות הסטנדרטיות אומרותשאם אתה כותב <include <stddef.h#, אז אתה יכול להשתמש בNULL. אם אתה לא כותב זאת, זה משתנה בין סביבה לסביבה. בפרט, יכול להיות שזה יהודר מצויין במחשב שלך, אבל שלי יתלונן.
  2. אתה צודק - צריך למצוא דוגמה אחרת.
  3. אנא נסה להתבונן בסימני העריכה כאן, והשתמש בהם כדי לשמור על דף שיחה קוהרנטי. כמו כן, נראה לי שהיה עליך לפתוח נושא חדש כאן.
Thedsadude 11:46, 16 בדצמבר 2007 (IST)

הקצאת זיכרון בגודל לא ידוע מראש[עריכה]

איך הזמנים משתנים... מסתבר שהשפה שונתה, וכעת אפשר להקצות מערכים בגודל לא ידוע מראש על המחסנית. כפי שצויין בשיחה הקודמת, הקוד שמוסבר שלא יתקמפל, דוקא כן מתקמפל, וזה חוקי לחלוטין. צריך למצוא דוגמה אחרת לחלוטין. Thedsadude 12:54, 16 בדצמבר 2007 (IST)

רגע רגע... מה??? לא שמעתי על דבר כזה (ולא מצאתי עכשיו באינטרנט). אתם מדברים על משהו כמו זה?
void f(int n)
{
    int myarr[n];
    int i;
    for(i = 0; i < n; i++)
        scanf("%d", &myarr[i]);

    for(i = n; i--;)
        printf("%d ", myarr[i]);
}
לפי הידוע לי, הדבר לא היה מאז ומעולם. הסיבה היא בעיה של המימוש של זה. אם אצל מישהו זה מתקמפל (אצלי לא) שישלח לי את קוד האסמבלי של הפונקציה, תודה.
ybungalobill 20:36, 20 בדצמבר 2007 (IST)
גם אני הופתעתי, אבל זה שונה בתקן C99. אגב, אצלי על האובונטו, gcc 4.1.3 מקמפל את זה ומריץ בלי בעיה. ראה גם את זה http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
Thedsadude 21:38, 20 בדצמבר 2007 (IST)

בעיה בתוכנית[עריכה]

שלום. כתבתי את התוכנית של המצביעים ב- VS12 והוא לא מאפשר לי להדר את התוכנית.


הפונקצייה:

#include <stdio.h>

int main()
{
	
	char a = 'a', b = 'b';
 
swap(&a,&b); // פה יש בעיה (הפונקצייה מקבלת מצביע של תו במקום מצביע של int)
 
printf("%c %c\n", a, b);

	 getchar(); 
     return 0;
}

void swap(int *px, int *py)
{
  int temp = *px;
  *px = *py;
  *py = temp;
}

Matanel11111 - שיחה 17:40, 5 באוגוסט 2013 (IDT)