לוגו אתר Fresh          
 
 
  אפשרות תפריט  ראשי     אפשרות תפריט  צ'אט     אפשרות תפריט  מבזקים     אפשרות תפריט  צור קשר     חץ שמאלה ‎print ‎"Hello World!"; if‎ ‎not rules.‎know ‎then rules.‎read(); חץ ימינה  

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



  #1  
ישן 07-02-2009, 13:02
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
מחרוזת ל int ושאלת מצביעים

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

כך שלמשל אם נכניס את המספר 254 תחת הסריקה שמאחסנת את המספר בתור char, נקבל בחזרה את המספר 11 בתור הסכום.

מה שכתבתי עד כה:





קוד PHP:
 #include <stdio.h>
 
int sum_digits(char *numstr) {
 
 
 
/*now I need to make the str character turn into an integer*/
 
    /* how do I turn a string of number into an integer?*/ 
 
 
 
    
if ( !numstr )
 
         return *
numstr;
 
         else
 
             return (
numstr%10)+sum_diginumstr/10 ); 
 
 
 
 
 
}
 
int main()
 

 
 
 
char str[10];
 
scanf("%s",str);
 
 
 
printf("The sum of digits of number is %d\n",sum_digits(str));
 
getch();
 
return 
0;
 





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

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



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

int sum_digits(char *numstr). לא כתבתי את ההכרזה והפונקציית מיין, היא ניתנה ככה
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #3  
ישן 07-02-2009, 13:38
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 1 שנכתבה על ידי *~.Shush.~* שמתחילה ב "מחרוזת ל int ושאלת מצביעים"

כמה שאלות.
1. מה הכוונה 'מקבלים את המספר כ char'? טיפוס char הוא תו בודד. את לא יכולה לסרוק "245" לתוך char בודד אלא לתוך מחרוזת של charים, או כתו אשר הקוד ה ASCII שלו הוא 245 (ולא, את לא יכולה לסרוק תווים בטווח שבין 128-255 באמצעות המקלדת עד כמה שידוע לי... זו טבלת ASCII מורחבת.

2. כדי להמיר מתו למספר אנחנו צריכים להבין מה בדיוק אנחנו רוצים להמיר. את הייצוג ה INTי של המספר שסרקנו (נניח סרקנו "5" בתור תו), או את הערך ה ASCII של התו שסרקנו (נניח סרקנו "5", אז הערך ה ASCIIי שלו הוא 53).

יש לי פונקציה שבניתי לפרוייקט שאני בדיוק עובד עליו עכשיו, הממירה ממחרוזת למספר INT, ובודקת על הדרך שמה שהוכנס זה רק מספרים ולא תווים אחרים:
קוד PHP:
 long check_int(charstr)
{
    
long result 0;
    for (
int i str[i] != '\0' i++)
    {
        if (
str[i] < '0' || str[i] > '9')
            return 
0;
        
result result 10 + (str[i] - 48);
    }
    return 
result;


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

תנאי הלולאה (הרקורסיבית) -> כל עוד המחרוזת שונה מ '0\'.
מה הרקורסיה מחזירה -> סכום הספרות עד כה.
(כתבתי קוד קרורסיבי שסוכם מספרים במחרוזת, אבל זה ממש פשוט, תנסי לבד לפני שתסתכלי איך אני עשיתי את זה. בנוסף, הקוד לא בודק תקינות קלט. אם זה חשוב לך לבדוק, את צריכה להוסיף תנאי קטן):
זהירות - ספויילר!


לא הבנתי מה הבעיה עם המצביעים... איפה בדיוק את תקועה?

בעריכה: ראיתי שהפונקציה שלך צריכה לקבל רק מחרוזת בלי משתני עזר, אז צריך להגדיר את מה שאני שלחתי כ static כדי שלא ישתנה בין ה'איטרציות':
זהירות - ספויילר!
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com


נערך לאחרונה ע"י Narxx בתאריך 07-02-2009 בשעה 13:51.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #8  
ישן 07-02-2009, 15:25
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 5 שנכתבה על ידי Gumble שמתחילה ב "הפונקציה שלה מקבל פוינטר, שלך..."

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

זהירות - ספויילר!


תוכל אולי להסביר ממש בשלבים מה קורה בכל צעד בפונקציה? מבלבל אותי עניין המערכים והמצביעים ואני ממש רוצה להבין אותו.
כשנכנסים לפונקציה שמחשבת את הסכום מגדירים משתנה שנקרא numstr אבל יש לפניו כוכבית אז מה זה בעצם אומר? אנחנו מכניסים לו את הערך של המשתנה str בפונקציית המיין או ש numstr מכוון לכתובת של המשתנה str ?
ומה בעצם קורה (בהסבר הכי איטי שיש..) בשורה האחרונה של הפונקציה מבחינת מצביעים ומערכים?
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #9  
ישן 07-02-2009, 16:16
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 8 שנכתבה על ידי *~.Shush.~* שמתחילה ב "[QUOTE=Gumble]הפונקציה שלה..."

התוכנית פשוטה מאוד.
את מקבלת מצביע מסוג char (ולכן מוגדר char* numstr).
הפונקציה תחזיר את הערך של התא הנוכחי, ולכן אם הגעת לסוף המחרוזת את מחזירה 0 (שזה למעשה יוסיף 0 לסכום שקיבלת עד עכשיו).
אם את לא בס"א (באקסלש אפס), אז את מבקשת לקבל את הערך של התא הבא במחרוזת.
כאשר כתוב numstr* זה אומר "הערך ש numstr מצביע עליו". לכן את בודקת לא האם numstr שווה לבס"א אלא הערך שלו (כי המצביע עצמו שווה לכתובת מסויימת בזיכרון).
באותו האופן את מחשבת את הסכום של הערך שיש בתא בחרוזת:
numstr-48* כי את רוצה לעשות 48- לערך שיש בתא במחרוזת.
אם היית כותבת numstr-48 בלי הכוכבית, היית למעשה הולכת 48 בתים אחורה בזיכרון מהכתובת ש numstr מצביע על.

בשורה:
return *numstr-48+sum_digits(numstr+1);
מה שהתוכנית עושה היא לוקחת את הערך של התא הנוכחי, ומוסיפה לו את הערך של התא הבא.
זה ירוץ בלולאה (ריקורסיבית) עד שתגיעי לתא שהוא בס"א. ברגע שהגעת לתא הזה, הסתיים החישוב והפונקציה תצא מעצמה שוב ושוב ושוב עד שתגיע לקריאה הראשונה שלה, ותסתיים.
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #10  
ישן 07-02-2009, 20:39
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 9 שנכתבה על ידי Narxx שמתחילה ב "התוכנית פשוטה מאוד. את מקבלת..."

ציטוט:
במקור נכתב על ידי Narxx
התוכנית פשוטה מאוד.
את מקבלת מצביע מסוג char (ולכן מוגדר char* numstr).
הפונקציה תחזיר את הערך של התא הנוכחי, ולכן אם הגעת לסוף המחרוזת את מחזירה 0 (שזה למעשה יוסיף 0 לסכום שקיבלת עד עכשיו).
אם את לא בס"א (באקסלש אפס), אז את מבקשת לקבל את הערך של התא הבא במחרוזת.
כאשר כתוב numstr* זה אומר "הערך ש numstr מצביע עליו". לכן את בודקת לא האם numstr שווה לבס"א אלא הערך שלו (כי המצביע עצמו שווה לכתובת מסויימת בזיכרון).
באותו האופן את מחשבת את הסכום של הערך שיש בתא בחרוזת:
numstr-48* כי את רוצה לעשות 48- לערך שיש בתא במחרוזת.
אם היית כותבת numstr-48 בלי הכוכבית, היית למעשה הולכת 48 בתים אחורה בזיכרון מהכתובת ש numstr מצביע על.

בשורה:
return *numstr-48+sum_digits(numstr+1);
מה שהתוכנית עושה היא לוקחת את הערך של התא הנוכחי, ומוסיפה לו את הערך של התא הבא.
זה ירוץ בלולאה (ריקורסיבית) עד שתגיעי לתא שהוא בס"א. ברגע שהגעת לתא הזה, הסתיים החישוב והפונקציה תצא מעצמה שוב ושוב ושוב עד שתגיע לקריאה הראשונה שלה, ותסתיים.


ומה היה קורה אם הייתי מגדירה את הפונקציה בתור numstr ולא *numstr ?

ושאלה נוספת לא קשורה
מתוך סקרנות כי ראיתי את זה באחד מהמבחנים בשנים שעברו.. איך אפשר לכתוב פונקציה שמקבל מספר טבעי שלם (מן הסתם..) ומחזירה אותו בסטרינג? (מותר שימוש בפונקציות)
אפילו על אלגוריתם לא ממש הצלחתי לחשוב, כי אני לא יודעת אם אפשר "לאסוף" צ'רים לתוך סטרינג אחד איכשהו
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #11  
ישן 08-02-2009, 01:56
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 10 שנכתבה על ידי *~.Shush.~* שמתחילה ב "[QUOTE=Narxx]התוכנית פשוטה..."

את מתכוונת אם היית מקבלת לפונצקיה numstr ולא numstr*?
אם היית מקבלת לפונקציה משתנה מסוג char, אז היית מקבלת תו בודד ולא היית יכולה לעשות איתו יותר מדי.
כשאת שולחת לפונקציה משתנים, את למעשה בונה אותם מחדש בתוך הפונקציה. יש יחידה בנאית שדואגת ליצור לך את המשתנים החדשים בפונקציה, ולהעביר אליהם בהעתקה את הערכים ששלחת.
לדוגמא:
קוד PHP:
 int main()
{
    
int temp 3;
    
num power (temp);
    
printf ("num is: %d"num);
}

int power (int num)
{
    return 
num num;


את רואה שבתוך הפונקציה את מקבלת int num, אבל אין שום קשר בין המשתנה הזה, לבין המשתנה שבתוך ה main שלך (אפילו שהערכים שלהם זהים). מה שקורה בפועל זה שיש יחידה שדואגת ליצור לך את המשתנה num החדש, להקצות לו מקום כלשהו בזיכרון ולהעתיק אליו את הערך "3", כפי שהיה במשתנה num המקורי ב main.

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

נהוג להתייחס למערך כאל מצביע לתא הראשון.
זאת אומרת, כשאני אצור מערך [int arr[30, וארצה לגשת לתא כלשהו (נגיד התא ה 17) ואכתוב: [num = arr[17, אני למעשה אלך 17 תאים מהתא הראשון (מבחינה פיסית, אם int תופס 4 בתים, אני אתקדם 4*17 בתים החל מהכתובת בזיכרון של התא הראשון. כך שאם הכתובת של התא הראשון היא "300", כדי לקבל את הערך שבתא ה 17, אני אלך ישר לכתובת 368).

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

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

עריכה: בנוגע לשאלה שלך עם איך להמיר מספר שלם למחרוזת, זה די פשוט. את צריכה בכל פעם להפריד את המספר הגדול ביותר של ה int ולשים אותו בתחילת המחרוזת.
הבעיה היא שאת לא תמיד יודעת את גודל המספר (כמה ספרות) ולכן להתחיל לחלק ב 10, 100, 1000 יכול להיות טיפה בעייתי, אבל יש דווקא פתרון יותר מגניב לבעיה (למה מגניב? כי אם מורה / מרצה רואה ביצוע שימוש במבנה-נתונים מהסוג הזה, הוא מיד מתלהב) - שימוש במחסנית.

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

אם קיבלת לפונקציה את המספר "12345", את תפעילי בהתחלה מודולו 10, ותקבלי את התוצאה "5". תשימי את המספר הזה במחרוזת ותחלקי את המספר ב 10.
המספר החדש יהיה "1234", ושוב תעשי לו מודולו 10, ותקבלי "4". שוב תשימי את ה "4" הזה במקום המתאים במערך וכן הלאה עד שיגמר המספר (זאת אומרת, שאחרי החלוקה ב 10 נשארת עם אפס [בנקודה הזו חשוב מאוד לשים בס"א בסוף המחרוזת כדי שנסמן את הסוף שלה כמו שצריך], ואז תהיה לך מחרוזת "54321". עכשיו את צריכה ליצור מחרוזת חדשה ולשים את 1 בתא הראשון, את 2 בתא השני, את 3 בתא השלישי וכן הלאה.
קוד PHP:
 for (0strlen (str)-strlen(str) ; i++, j--)
      
str1[i] = str[j]; 

וזהו, הפכת את כל התווים שבמחרוזת str והתוצאה שמורה ב str1.
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com


נערך לאחרונה ע"י Narxx בתאריך 08-02-2009 בשעה 02:17.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #12  
ישן 08-02-2009, 09:57
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 11 שנכתבה על ידי Narxx שמתחילה ב "את מתכוונת אם היית..."

ציטוט:
במקור נכתב על ידי Narxx
את מתכוונת אם היית מקבלת לפונצקיה numstr ולא numstr*?
אם היית מקבלת לפונקציה משתנה מסוג char, אז היית מקבלת תו בודד ולא היית יכולה לעשות איתו יותר מדי.
כשאת שולחת לפונקציה משתנים, את למעשה בונה אותם מחדש בתוך הפונקציה. יש יחידה בנאית שדואגת ליצור לך את המשתנים החדשים בפונקציה, ולהעביר אליהם בהעתקה את הערכים ששלחת.
לדוגמא:
קוד PHP:
 int main()
{
    
int temp 3;
    
num power (temp);
    
printf ("num is: %d"num);
}
 
int power (int num)
{
    return 
num num;


את רואה שבתוך הפונקציה את מקבלת int num, אבל אין שום קשר בין המשתנה הזה, לבין המשתנה שבתוך ה main שלך (אפילו שהערכים שלהם זהים). מה שקורה בפועל זה שיש יחידה שדואגת ליצור לך את המשתנה num החדש, להקצות לו מקום כלשהו בזיכרון ולהעתיק אליו את הערך "3", כפי שהיה במשתנה num המקורי ב main.

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

נהוג להתייחס למערך כאל מצביע לתא הראשון.
זאת אומרת, כשאני אצור מערך [int arr[30, וארצה לגשת לתא כלשהו (נגיד התא ה 17) ואכתוב: [num = arr[17, אני למעשה אלך 17 תאים מהתא הראשון (מבחינה פיסית, אם int תופס 4 בתים, אני אתקדם 4*17 בתים החל מהכתובת בזיכרון של התא הראשון. כך שאם הכתובת של התא הראשון היא "300", כדי לקבל את הערך שבתא ה 17, אני אלך ישר לכתובת 368).

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

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

עריכה: בנוגע לשאלה שלך עם איך להמיר מספר שלם למחרוזת, זה די פשוט. את צריכה בכל פעם להפריד את המספר הגדול ביותר של ה int ולשים אותו בתחילת המחרוזת.
הבעיה היא שאת לא תמיד יודעת את גודל המספר (כמה ספרות) ולכן להתחיל לחלק ב 10, 100, 1000 יכול להיות טיפה בעייתי, אבל יש דווקא פתרון יותר מגניב לבעיה (למה מגניב? כי אם מורה / מרצה רואה ביצוע שימוש במבנה-נתונים מהסוג הזה, הוא מיד מתלהב) - שימוש במחסנית.

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

אם קיבלת לפונקציה את המספר "12345", את תפעילי בהתחלה מודולו 10, ותקבלי את התוצאה "5". תשימי את המספר הזה במחרוזת ותחלקי את המספר ב 10.
המספר החדש יהיה "1234", ושוב תעשי לו מודולו 10, ותקבלי "4". שוב תשימי את ה "4" הזה במקום המתאים במערך וכן הלאה עד שיגמר המספר (זאת אומרת, שאחרי החלוקה ב 10 נשארת עם אפס [בנקודה הזו חשוב מאוד לשים בס"א בסוף המחרוזת כדי שנסמן את הסוף שלה כמו שצריך], ואז תהיה לך מחרוזת "54321". עכשיו את צריכה ליצור מחרוזת חדשה ולשים את 1 בתא הראשון, את 2 בתא השני, את 3 בתא השלישי וכן הלאה.
קוד PHP:
 for (0strlen (str)-strlen(str) ; i++, j--)
     
str1[i] = str[j]; 

וזהו, הפכת את כל התווים שבמחרוזת str והתוצאה שמורה ב str1.


ממש לא חפרת
סליחה על הבורות אבל.. מה זה מודולו ואיך נראה הסימון שלו ב C?
מה strlen(str) מייצג?

נערך לאחרונה ע"י *~.Shush.~* בתאריך 08-02-2009 בשעה 10:05.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #16  
ישן 08-02-2009, 11:53
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 14 שנכתבה על ידי *~.Shush.~* שמתחילה ב "[QUOTE=Gumble]מודולו - %..."

מודולו זה למעשה "שארית החלוקה" של המספר הראשון במספר השני.
x = 5
y = 7
עכשיו, שארית החלוקה של 7 ב 5 (זאת אומרת שבע חלקי חמש) זה 2 (יש שלם 1 ועוד 2 חמישיות בשארית).
שארית החלוקה של 5 ב 7 (זאת אומרת חמש חלקי שבע) זה 5 (אין אף שלם, ויש 5 שביעיות שארית).

כשאנחנו מפרידים את הספרה האחרונה אנחנו תמיד עושים מודולו של 10, כי חלוקת מספר ב 10 נותנת בדיוק את הספרה האחרונה בשארית.
256 חלקי 10 זה 25 עם שארית 6...

מימוש של strlen כתבתי לך למטה.
יהיה מגניב אם תשתמשי ממש בשם הזה (strlen) כי באמת יש פונקציה כזו, ואפילו שאסור לך להשתמש ב string.h, את כאילו כן משתמשת בה

עריכה: בעעע, אני וגאמבל מספימים באותו הזמן ויש פה דאבל פוסטינג מטורף
אני אשאיר לגאמבל לסגור לך ת'פינה הזו... עוד שעתיים יש מבחן במערכות קבצים ואולי הגיע הזמן ללמוד אליו קצת
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com


נערך לאחרונה ע"י Narxx בתאריך 08-02-2009 בשעה 11:57.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #17  
ישן 08-02-2009, 15:08
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 16 שנכתבה על ידי Narxx שמתחילה ב "מודולו זה למעשה "שארית..."

ציטוט:
במקור נכתב על ידי Narxx
מודולו זה למעשה "שארית החלוקה" של המספר הראשון במספר השני.
x = 5
y = 7
עכשיו, שארית החלוקה של 7 ב 5 (זאת אומרת שבע חלקי חמש) זה 2 (יש שלם 1 ועוד 2 חמישיות בשארית).
שארית החלוקה של 5 ב 7 (זאת אומרת חמש חלקי שבע) זה 5 (אין אף שלם, ויש 5 שביעיות שארית).

כשאנחנו מפרידים את הספרה האחרונה אנחנו תמיד עושים מודולו של 10, כי חלוקת מספר ב 10 נותנת בדיוק את הספרה האחרונה בשארית.
256 חלקי 10 זה 25 עם שארית 6...

מימוש של strlen כתבתי לך למטה.
יהיה מגניב אם תשתמשי ממש בשם הזה (strlen) כי באמת יש פונקציה כזו, ואפילו שאסור לך להשתמש ב string.h, את כאילו כן משתמשת בה

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


בהצלחה במבחן!
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #18  
ישן 08-02-2009, 11:41
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 12 שנכתבה על ידי *~.Shush.~* שמתחילה ב "[QUOTE=Narxx]את מתכוונת אם..."

שימוש במודולו:
קוד PHP:
 int x 12345;
char str[6];
str[0] = x%10// str[0] = 5
x/10// x = 1234
...
str[6] = '\0'

כמו שגאמבל אמר, הפונקציה strlen מחזירה את גודל המחרוזת (החל מהתא הראשון ועד לבס"א (לא כולל הבס"א)) שבסוגריים
אם אכתוב:
קוד PHP:
 x strlen (str); 

המשתנה x יקבל את הערך "5" כי יש 5 תאים מהתא הראשון ([str[0) ועד לתא בו יש בס"א.
למעשה, כשחושבים על זה, הוא פשוט מחזיר את האינדקס שבו נמצא הבס"א
דרך מהירה לספור כמה ארוכה המחרוזת שלך.
אם אסור לך להשתמש ב string.h, את יכולה לבנות פונקציה שתחשב את זה.
תבני לולאה שרצה על המחרוזת ובודקת האם התא הנוכחי הוא בס"א. כל עוד לא בס"א, תמשיכי קדימה לתא הבא. ברגע שהגעת לבס"א - תחזירי את האינדקס שלו (כ int כמובן).
אם אין בס"א במחרוזת, את מסתכנת בגלישה אל מעבר לגבולות המחרוזת ולכן צריך לוודא שאת לא קוראת לפונקציה כשאין בס"א במחרוזת אחרת התוכנית שלך יכולה לקרוס. אם את שמה איברים במחרוזת בצורה ידנית (תא אחרי תא), חשוב לזכור לשים בסוף בס"א.
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #19  
ישן 08-02-2009, 15:22
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 18 שנכתבה על ידי Narxx שמתחילה ב "שימוש במודולו: [php] int x =..."

ציטוט:
במקור נכתב על ידי Narxx
שימוש במודולו:
קוד PHP:
 int x 12345;
char str[6];
str[0] = x%10// str[0] = 5
x/10// x = 1234
...
str[6] = '\0'

כמו שגאמבל אמר, הפונקציה strlen מחזירה את גודל המחרוזת (החל מהתא הראשון ועד לבס"א (לא כולל הבס"א)) שבסוגריים
אם אכתוב:
קוד PHP:
 x strlen (str); 

המשתנה x יקבל את הערך "5" כי יש 5 תאים מהתא הראשון ([str[0) ועד לתא בו יש בס"א.
למעשה, כשחושבים על זה, הוא פשוט מחזיר את האינדקס שבו נמצא הבס"א
דרך מהירה לספור כמה ארוכה המחרוזת שלך.
אם אסור לך להשתמש ב string.h, את יכולה לבנות פונקציה שתחשב את זה.
תבני לולאה שרצה על המחרוזת ובודקת האם התא הנוכחי הוא בס"א. כל עוד לא בס"א, תמשיכי קדימה לתא הבא. ברגע שהגעת לבס"א - תחזירי את האינדקס שלו (כ int כמובן).
אם אין בס"א במחרוזת, את מסתכנת בגלישה אל מעבר לגבולות המחרוזת ולכן צריך לוודא שאת לא קוראת לפונקציה כשאין בס"א במחרוזת אחרת התוכנית שלך יכולה לקרוס. אם את שמה איברים במחרוזת בצורה ידנית (תא אחרי תא), חשוב לזכור לשים בסוף בס"א.


איך זה בתור מימוש ללולאה שתחזיר את מספר האינדקס?
קוד PHP:
 while (Str[i] != '\0')
        {
 
             if (
Str[i] != '\0'
             {
                 
count++;
             }
             else
index=+count
             

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #23  
ישן 07-02-2009, 16:49
צלמית המשתמש של Gumble
  משתמש זכר Gumble Gumble אינו מחובר  
 
חבר מתאריך: 27.06.08
הודעות: 3,441
בתגובה להודעה מספר 8 שנכתבה על ידי *~.Shush.~* שמתחילה ב "[QUOTE=Gumble]הפונקציה שלה..."

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

בפונקציה הזאת שואלים כמה אנשים יש בשולחן ועוד כמה יש בשולחנות הבאים ע"י כך שאומרים למלצר שהוא אחראי על מספר שולחן הנוכחי +1 ושואלים שוב כמה אנשים יושבים שם.
כך המלצר יעבור על כל השולחנות בסדרה על לשולחן שבו יש \0 (סוף מחרוזת) בכל פעם הוא יהיה אחראי על השולחן הבא בתור ויספור כמה אנשים יושבים בו.
_____________________________________


תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #24  
ישן 07-02-2009, 20:40
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 23 שנכתבה על ידי Gumble שמתחילה ב "בואי נגיד שמצביע הוא מלצר..."

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

בפונקציה הזאת שואלים כמה אנשים יש בשולחן ועוד כמה יש בשולחנות הבאים ע"י כך שאומרים למלצר שהוא אחראי על מספר שולחן הנוכחי +1 ושואלים שוב כמה אנשים יושבים שם.
כך המלצר יעבור על כל השולחנות בסדרה על לשולחן שבו יש \0 (סוף מחרוזת) בכל פעם הוא יהיה אחראי על השולחן הבא בתור ויספור כמה אנשים יושבים בו.


ובגלל זה מגדירים אותו בתור *numstr ולא סתם numstr בלי כוכבית? כי בלי כוכבית זה יתן לי את המספר של השולחן ולא את מספר הסועדים?
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #26  
ישן 08-02-2009, 01:37
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 25 שנכתבה על ידי Tankado שמתחילה ב "לא הבנתי את ההקבלה למלצר..."

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

דוגמא:
קוד PHP:
 int x, *temp// making new vars. An integer and a pointer to an integer.
temp = &x;  // the pointer will hold the address of x
/* temp = x;    <-- this is wrong!! A pointer assumes having an address */
20;
printf ("the number in x is: %d"x); // this will show the data stored in x
printf ("the number stored in temp is: %d", *temp); // note that now we are looking for the value that is stored in temp. Not the address of which it points at.
printf ("temp is pointing at %d"temp); // I'm not even sure it's okay to write it like that, but it's suppose to give you the physical memory address of which temp points at 

מקווה שהיה ברור למרות השימוש באנגלית (זה די בלתי נמנע).
כשמשתמשים בכוכבית, אנחנו מדברים על הערך שנמצא בכתובת עליה המצביע מצביע.
כשלא משתמשים בכוכבית, אנחנו מקבלים את הערך של המשתנה עצמו (במקרה של מצביעים, הם מחזיקים כתובת ולכן אם נדפיס את המצביעים עצמם - נקבל כתובת ולא את הערך שנמצא בכתובת הזו).
זה כמו למעשה לכתוב:
קוד PHP:
 int x;
printf ("x is address: %d",&x); 

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

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

בהצלחה...
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #28  
ישן 08-02-2009, 19:12
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 27 שנכתבה על ידי *~.Shush.~* שמתחילה ב "אז.. אם נגיד אני מגדירה..."

חידוד:
אם את רוצה לתת למצביע את הכתובת של מחרוזת (או כל מערך שהוא) את יכולה פשוט לתת לו את השם של המערך (כיוון שמערך הוא למעשה מצביע לתא הראשון, כפי שכבר נאמר קודם לכן באשכול):
קוד PHP:
 chartemp;
char string[50];
temp string 

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

אם את רוצה להדפיס אחד אחד את התווים במחרוזת אז את יכולה להשתמש בלולאה:
קוד PHP:
 for (i=string[i] != '\0' i++)
printf ("%c",string[i]); 

אבל למה לעשות את זה אם את יכולה פשוט להדפיס עם s% בפונקציה printf?
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #29  
ישן 08-02-2009, 19:56
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 28 שנכתבה על ידי Narxx שמתחילה ב "חידוד: אם את רוצה לתת למצביע..."

ציטוט:
במקור נכתב על ידי Narxx
חידוד:
אם את רוצה לתת למצביע את הכתובת של מחרוזת (או כל מערך שהוא) את יכולה פשוט לתת לו את השם של המערך (כיוון שמערך הוא למעשה מצביע לתא הראשון, כפי שכבר נאמר קודם לכן באשכול):
קוד PHP:
 chartemp;
char string[50];
temp string 

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

אם את רוצה להדפיס אחד אחד את התווים במחרוזת אז את יכולה להשתמש בלולאה:
קוד PHP:
 for (i=string[i] != '\0' i++)
printf ("%c",string[i]); 

אבל למה לעשות את זה אם את יכולה פשוט להדפיס עם s% בפונקציה printf?


אני סתם זורקת שאלות באוויר כדי להפנים את המערכים/מצביעים. אתה מאד עוזר דרך אגב !
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #30  
ישן 09-02-2009, 14:43
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 1 שנכתבה על ידי *~.Shush.~* שמתחילה ב "מחרוזת ל int ושאלת מצביעים"

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

קוד PHP:
 #include <stdio.h>
void num2str(int numchar *str) {
     
int i=0;
     
int k=0;
     
int l=0;
     
int j=0;
     
char str1[6];
     
for (
i=0num >=1;i++){
    
str[i]=((num%10)+48);
    
num=(num/10);
}
    
str[i]=;       
while (
str[k] != '\0')
        {
 
k++;
  }
k;
     for (
0= (l-1) ; l++, j--)
     
str1[l] = str[j];    
     
str1[l+1]=0;     
           
return *
str1;     
          
           
           
     }
           
           
int main()
{
 
int numres;
 
char str[6];
 
scanf("%d",&num);
 
num2str(numstr);
 
printf("The number is %s\n",str);
 
getch();
 return 
0;


ה int main נתון כמו שהוא ואסור לי לגעת בו.
* מוזר לי שהפונקציה מוגדרת בתור void שאסור לי לשנות אותו. זה גם כותב הערה על כך בקימפול
* בהכרזה של הפונקציה:
void num2str(int num, char *str)
למה בעצם str הוא פוינטר?
* כמו שבטח ניחשתם, הפונקציה לא עובדת. היא עוברת קימפול ב DEV C אבל לא בטורבו סי, ובהרצה היא כותבת שגיאה שלא הצלחתי לעלות עליה כי זה נראה לי די הגיוני מה שכתבתי.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #34  
ישן 09-02-2009, 20:57
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 33 שנכתבה על ידי Gumble שמתחילה ב "אהה, OK אז למה שלו תמלאי את..."

ציטוט:
במקור נכתב על ידי Gumble
אהה, OK אז למה שלו תמלאי את המחרוזת str1 במספר ההפוך ואז את str במספר המסודר.
אני חושב שהבעיה בקומפילציה היא בגלל שיש לך פונקציה void שלו מחזירה דבר, וכתבת return *str1 שלא נחוץ.


קוד PHP:
 #include <stdio.h>
void num2str(int numchar *str) {
     
int i=0;
     
int k=0;
     
int l=0;
     
int j=0;
     
char str1[6];
     
for (
i=0num >=1;i++){
    
str1[i]=((num%10)+48);
    
num=(num/10);
}
    
str1[i]=;       
while (
str1[k] != '\0')
        {
 
k++;
  }
k;
     for (
0= (l-1) ; l++, j--)
     
str[l] = str1[j];    
     
str[l+1]=0;     
              
          
           
           
     }
           
           
int main()
{
 
int numres;
 
char str[6];
 
scanf("%d",&num);
 
num2str(numstr);
 
printf("The number is %s\n",str);
 
getch();
 return 
0;



לאחר השינוי ^
אתה יכול להסביר למה ה return לא נחוץ?
ומשום מה ה getch() לא עוצר את הפונקציה אז אחרי ההרצה זה נסגר ישר כשאני מכניסה מספר. אני זוכרת שהיתה ספרייה שהיה אפשר להשתמש בה במן פונקצית pause.. מכיר במקרה?
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #37  
ישן 09-02-2009, 23:06
צלמית המשתמש של Gumble
  משתמש זכר Gumble Gumble אינו מחובר  
 
חבר מתאריך: 27.06.08
הודעות: 3,441
בתגובה להודעה מספר 36 שנכתבה על ידי *~.Shush.~* שמתחילה ב "[QUOTE=Gumble]getch() נמצאת..."

ציטוט:
במקור נכתב על ידי *~.Shush.~*
קורס מבוא לשפת C..
אתה רציני? :\ זה דווקא נראה לי די הגיוני. זה אפילו עובד עד לשלב של החלפת הסדר במחרוזת, כלומר עד לולאת ה while


גם אני, תאמת שכבר נגמר הסמסטר, נראה איך ילך בבחינה.

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


תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #40  
ישן 10-02-2009, 10:24
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 39 שנכתבה על ידי *~.Shush.~* שמתחילה ב "הסבר יותר מפורט למה שרציתי..."

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

שאלה - למה אחרי ששמת את כל הספרות במחרוזת str1, אחרי הלולאה שמת 0 בתא האחרון ולא בס"א? זה בכוונה או שהתבלבלת?
כנראה שזו הסיבה שאת נזרקת מהתוכנית... הלולאת while שלך תעצור כשתגיע לבס"א, אבל כנראה שהיא לא מגיעה לבס"א לפני שהיא חורגת מגבולות המערך ומתחילה לעשות בלאגנים...
נסי לתקן את ההשמה מאפס לבס"א.
גם מתחת ל for השני שמת שם השמה לאפס... למה?
עוד אני לא מבין למה ההשמה לאפס (או בס"א) ב for השני הוא עבור האיבר ה l+1?
הרי, יצאת מהלולאה כאשר l עשה כבר ++ ולכן הערך שלו הוא תא אחד יותר מהתא האחרון שעבר בלולאה.

בעריכה: טעות שלי, הלולאה הראשונה שלך היא לא כמו strlen.
את בטוחה שאת צריכה לעשות כל עוד num>=1? נראה לי שרק כשאת מגיעה לאפס אז המספר נגמר...
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com


נערך לאחרונה ע"י Narxx בתאריך 10-02-2009 בשעה 10:38.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #41  
ישן 10-02-2009, 14:36
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 40 שנכתבה על ידי Narxx שמתחילה ב "אז לולאת ה for שלך למעשה..."

ציטוט:
במקור נכתב על ידי Narxx
אז לולאת ה for שלך למעשה סופרת את גודל המחרוזת (שזה המימוש למעשה של strlen - אני ממליץ לך לממש את הפונקציה strlen בצורה דומה למה שמימשתי קודם, ולהשתמש בפונקציה כדי שתתחילי להתרגל לזה) ואז את רוצה ב while לשים את התווים.
זה אפשרי, אבל אם את כבר יודעת את גודל המחרוזת, את יודעת את מספר האיטרציות שאת צריכה ולכן כבר עדיף להשתמש בלולאת for כדי לעשות את ההחלפה של התווים.

שאלה - למה אחרי ששמת את כל הספרות במחרוזת str1, אחרי הלולאה שמת 0 בתא האחרון ולא בס"א? זה בכוונה או שהתבלבלת?
כנראה שזו הסיבה שאת נזרקת מהתוכנית... הלולאת while שלך תעצור כשתגיע לבס"א, אבל כנראה שהיא לא מגיעה לבס"א לפני שהיא חורגת מגבולות המערך ומתחילה לעשות בלאגנים...
נסי לתקן את ההשמה מאפס לבס"א.
גם מתחת ל for השני שמת שם השמה לאפס... למה?
עוד אני לא מבין למה ההשמה לאפס (או בס"א) ב for השני הוא עבור האיבר ה l+1?
הרי, יצאת מהלולאה כאשר l עשה כבר ++ ולכן הערך שלו הוא תא אחד יותר מהתא האחרון שעבר בלולאה.

בעריכה: טעות שלי, הלולאה הראשונה שלך היא לא כמו strlen.
את בטוחה שאת צריכה לעשות כל עוד num>=1? נראה לי שרק כשאת מגיעה לאפס אז המספר נגמר...


ויתרתי על הלולאת while, היא לא היתה הכרחית
שיניתי את זה לבס"א בחזרה אבל אמרו לי שאם שמים 0 זה לא משנה.. וזה מוזר, כי זה באמת תיפקד כאילו זה לא משנה.
תיקנתי גם את ההשמה לאפס עבור 1+ אחרי שראיתי שזה מחזיר לי את המספר + שטות
num>=1 או גדול מאפס אני לא חושבת שזה משנה כי זה נשמר בתור int ואז בכל מקרה זה לא יכול להיות שבר
הצלחתי בסוף לגרום לזה לפעול! אם זה מעניין אותך אני אכתוב את הגרסא הסופית

עכשיו אני עומדת בפני שאלה גדולה יותר שמותר להעזר בה גם בפונקציה הזאת וגם בפונקציה שסוכמת מחרוזות (צריכה לכתוב פונקציה רקורסיבית כשמותר להשתמש בפונקציות הנ"ל, שבודקת ללא שימוש בחילוק כפל ומודולו אם מספר מתחלק ב- 3. אני אשתמש בתכונה שאם סכום הספרות של מספר מתחלק ב -3 אז גם המספר מתחלק בו.. כרגע אני רק חושבת על דרך פיתרון. כשאני אגיד נואש אני אחזור לכאן )
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #43  
ישן 11-02-2009, 14:09
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 1 שנכתבה על ידי *~.Shush.~* שמתחילה ב "מחרוזת ל int ושאלת מצביעים"

קפצתי לביקור :-)

אני צריכה לכתוב פונקציה רקורסיבית שמקבלת מחרוזת בה רשום מספר שלם חיובי ומחזירה 1 אם המספר מתחלק ב-3, ו-0 אם לא. המספר יכול להיות מאד ארוך ולחרוג מתחום long int.
הנחיות:
אסור להשתמש בלולאות
אסור להשתמש בכפל, חילוק ומודולו
רצוי להשתמש בתכונת החלוקה של 3 הבאה: מספר מתחלק ב 3 אם סכום ספרותיו מתחלק ב 3.
ניתן ורצוי להשתמש בפונקציות 1 ו-2 כאשר פונקציה 1: void num2str(int n, char *str) מקבלת מספר טבעי והופכת אותו למחרוזת המיצגת אותו מספר בפורמט עשרוני
פונקציה 2: פונקציה רקורסיבית int sum_digits(char *numstr); שמקבלת מחרוזת בה מספר חיובי ושלם ומחזירה את סכום ספרותיה .
יש להניח כי סכום הספרות אינו עולה על 10000
מותר להניח כי הקלט תקין

ה"שלד" של הפונקציה יראה כך:


קוד PHP:


#include <stdio.h>

void num2str(int num, char *str); /*function1: natural number to string, use as if was given */
int sum_digits(char *numstr); /*function2: sums up a string, use as if was given */
int div_by3(char *numstr) {

// Code here //


}
int main(){ //cannot be changed//
int num, res;
char str[20];
printf("please enter a number:");
scanf("%s",str);
res = div_by3(str);
if(
res)
printf("The number can be divided by 3\n");
else
printf("The number cannot be divided by 3\n");
getch();
return
0;
}






שאלות:
* מה זה אומר שהוא יכול לחרוג מתחום long int ?

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

קוד PHP:


void num2str(int num, char *str); /*function1: natural number to string, use as if was given */


int sum_digits(char *numstr); /*function2: sums up a string, use as if was given */

int div_by3(char *numstr) {
char buff[10];
int r=sum_digits(numstr);

if(
r>=10){
/* what do i do in this case? */

}

/* handle case r in [0, 9]

*/
switch(r)
{
case
0:
case
3:
case
6:
case
9:
return
1; /* true */
}
return
0; /* false */
}




אבל מה אני יכולה לעשות במקרים של r>=0 ?
[התמונה הבאה מגיעה מקישור שלא מתחיל ב https ולכן לא הוטמעה בדף כדי לשמור על https תקין: http://www.fxp.co.il/images/smilies2/disgust.gif]

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

נערך לאחרונה ע"י *~.Shush.~* בתאריך 11-02-2009 בשעה 14:17.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #46  
ישן 12-02-2009, 07:25
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 45 שנכתבה על ידי Narxx שמתחילה ב "כדי להשתמש בפונקציית קוד php..."

תודה Narxx

ועכשיו באשר לשאלה, רציתי לכתוב את הפונקציה השלישית כך:



קוד PHP:
 int div_by3(char *numstr)
{
int sum=sum_digits(numstr);
if (
sum 10)

switch(
sum)
{
case 
0:
case 
3:
case 
6:
case 
9:
return 
1/* true */
}
return 
0/* false */
}
}
else
{
num2str(sumnumstr);
return (
div_by3(numstr));
}


כאשר הקוד המלא יראה:

קוד PHP:
 #include <stdio.h>
void num2str(int numchar *str) {
     
int i=0;
     
int j=0;
     
int p=0;
     
char str1[6];
     
for (
i=0num >=1;i++){
    
str1[i]=((num%10)+48);
    
num=(num/10);
}
    
str1[i]='\0' ;        
 
     for (
0= (i-1/*2*/ p++, j--)
     
str[p] = str1[j];  
     
str[p]=0;   
       
return 
str1;           
           
     }
int sum_digits(char *numstr){
if (*
numstr=='\0')  return 0;
return *
numstr-48+sum_digits(numstr+1);
}  
int div_by3(char *numstr)
{
int sum=sum_digits(numstr);
if (
sum 10)

switch(
sum)
{
case 
0:
case 
3:
case 
6:
case 
9:
return 
1/* true */
}
return 
0/* false */
}
}
else
{
num2str(sumnumstr);
return (
div_by3(numstr));
}
}
int main(){ //cannot be changed//
int numres;
char str[20];
printf("please enter a number:");
scanf("%s",str);
res div_by3(str);
if(
res)
printf("The number can be divided by 3\n");
else
printf("The number cannot be divided by 3\n");
getch();
return 
0;



הבעיה היא שאני אפילו לא יכולה לראות אם זה עובד כי כתובה לי הודעת שגיאה בפונקציה הראשונה בשורה בה כתוב
קוד PHP:
 return str1

ואני לא מבינה למה, כי כשהפונקציה עמדה בפני עצמה היא פעלה מצויין..
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #49  
ישן 12-02-2009, 14:19
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 48 שנכתבה על ידי *~.Shush.~* שמתחילה ב "[QUOTE=EventHorizon]במבט..."

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

בשביל להבין איך זה עובד, את צריכה להבין איך מצביעים באמת עובדים.
קוד PHP:
 #include <stdio.h>

void func1 (intxinty);

int main ()
{
    
int x=0;
    
int y=0;
    
printf ("x is: %d, and y is: %d \n",x,y);        // x is: 0, and y is: 0
    
func1 (&x, &y);
    
printf ("x is: %d, and y is: %d \n",x,y);        // x is: 1, and y is: 2
}

void func1 (intxinty)
{
    
1;
    
2;


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

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


נערך לאחרונה ע"י Narxx בתאריך 12-02-2009 בשעה 14:23. סיבה: שגיאות קליד בטירוף.. :|
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #50  
ישן 12-02-2009, 14:54
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 49 שנכתבה על ידי Narxx שמתחילה ב "כי את מקבלת משתנים לתוך..."

ציטוט:
במקור נכתב על ידי Narxx
כי את מקבלת משתנים לתוך הפונקציה בשיטה שנקראית "by reference".
זאת אומרת, את צודקת, את באמת לא יכולה 'להחזיר' שום דבר מהפונקציה כי מוגדר לך שהיא צריכה להחזיר void (שזה אומר שהיא לא מחזירה כלום), אבל, כיוון שאת לומדת לעבוד עם מצביעים, פתאום את מגלה שאת יכולה למעשה להחזיר כל ערך שאת רוצה ויותר מזה - את אפילו לא מוגבלת בכמות ההחזרות שלך.
כשאת עובדת עם מצביעים, את יכולה להחזיר אינסוף משתנים לתוכנית ה main (או הפונקציה האחרת שקראה לפונקציה הזו).

בשביל להבין איך זה עובד, את צריכה להבין איך מצביעים באמת עובדים.
קוד PHP:
 #include <stdio.h>
 
void func1 (intxinty);
 
int main ()
{
    
int x=0;
    
int y=0;
    
printf ("x is: %d, and y is: %d \n",x,y);        // x is: 0, and y is: 0
    
func1 (&x, &y);
    
printf ("x is: %d, and y is: %d \n",x,y);        // x is: 1, and y is: 2
}
 
void func1 (intxinty)
{
    
1;
    
2;


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

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


מצטערת, אבל בהקשר של התכנית שלי אני פשוט לא מבינה מה אני יכולה לעשות. אני לא יכולה לשנות את 2 הפונקציות הראשונות, כי הן עובדות בפני עצמן ובדקתי את זה. אני לא יכולה לשנות את פונקציית ה main. רק את div_by3.
חשבתי לשנות אותה ולכתוב בצורה הזאת:

קוד PHP:
 int div_by3(char *numstr) {
    
char buff[10];
    
int r=sum_digits(numstr);
    if( 
r>=10){
    
num2str(/*int*/ r/* * */ str);
    return 
div_by3(/* char *num*/str);
    }
     
/* handle case r in [0, 9]
     * would you accept something like:
     */
     
switch(r)
     {
         case 
0:
         case 
3:
         case 
6:
         case 
9:
                 return 
1/* true */
    
}
    return 
0/* false */



וזה לא ממש משנה את זה שהקימפול מראה שגיאה ב num2str
כשאתה כותב את זה בדוגמאות פשוטות זה ברור, עכשיו זה לא.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #51  
ישן 12-02-2009, 15:16
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 50 שנכתבה על ידי *~.Shush.~* שמתחילה ב "[QUOTE=Narxx]כי את מקבלת..."

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

קחי את הדוגמא שלי, ותשליכי את ההשמה שלה - במקרה שלך.
הבעיה שלך היא עם פונקציה num2str אשר מקבלת מספר ומחרוזת (רמז רמז, מחרוזת זה מערך ומערך זה מצביע) וצריכה לשנות את המספר למחרוזת.
כל שינוי שתבצעי במחרוזת שקיבלת, 'ישמר' גם עבור הפונקציות האחרות (להבדיל מ str1 שהיא מקומית כי יצרת אותה בתוך num2str).
זאת אומרת, שבשורה התחתונה, כל מה שאת צריכה לעשות, זה פשוט להעתיק את str1 לתוך str ע"י פונקציית strcpy (ואם אסור לך להשתמש ב string.h אז פשוט תעתיקי בלולאה או שיותר טוב מזה - את הקוד שלך תשני בצורה כזו שתקבלי את התוצאה הסופית ב str במקום ב str1) - וזהו.. סיימת.
יש לך ב str את המספר שלך, ותראי איזה קסם - אפילו לא היית צריכה לעשות שום return
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com


נערך לאחרונה ע"י Narxx בתאריך 12-02-2009 בשעה 15:21.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #52  
ישן 12-02-2009, 16:47
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 51 שנכתבה על ידי Narxx שמתחילה ב "כמו שאיב (כפרע-עליה, למה היא..."

ציטוט:
במקור נכתב על ידי Narxx
כמו שאיב (כפרע-עליה, למה היא לא מזמינה אותי לבקר בבית שלה מתישהו?) אמרה למעלה, את מנסה להחזיר int מתוך פונקציה שמוגדרת להחזיר void.
אני ניסיתי לתת לך להבין בדוגמא שלי שאת לא צריכה לעשות שום return בפונקציה שמחזירה void כדי לשנות ערכים של משתנים שנמצאים ב main (או בכל פונקציה אחרת).

קחי את הדוגמא שלי, ותשליכי את ההשמה שלה - במקרה שלך.
הבעיה שלך היא עם פונקציה num2str אשר מקבלת מספר ומחרוזת (רמז רמז, מחרוזת זה מערך ומערך זה מצביע) וצריכה לשנות את המספר למחרוזת.
כל שינוי שתבצעי במחרוזת שקיבלת, 'ישמר' גם עבור הפונקציות האחרות (להבדיל מ str1 שהיא מקומית כי יצרת אותה בתוך num2str).
זאת אומרת, שבשורה התחתונה, כל מה שאת צריכה לעשות, זה פשוט להעתיק את str1 לתוך str ע"י פונקציית strcpy (ואם אסור לך להשתמש ב string.h אז פשוט תעתיקי בלולאה או שיותר טוב מזה - את הקוד שלך תשני בצורה כזו שתקבלי את התוצאה הסופית ב str במקום ב str1) - וזהו.. סיימת.
יש לך ב str את המספר שלך, ותראי איזה קסם - אפילו לא היית צריכה לעשות שום return


אז איך אתה מסביר את זה ששמתי } אחד יותר מדי בפונקצית div3 וברגע שהורדתי אותו ולא שיניתי שום דבר אחר הכל עבד כמו שצריך?
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #54  
ישן 13-02-2009, 09:37
צלמית המשתמש של *~.Shush.~*
  משתמשת נקבה *~.Shush.~* *~.Shush.~* אינו מחובר  
 
חבר מתאריך: 10.10.06
הודעות: 64
בתגובה להודעה מספר 53 שנכתבה על ידי Narxx שמתחילה ב "אני לא לגמרי עוקב. תכתבי מחדש..."

אם הבנתי נכון, אני יכולה לשנות ערך של משתנה בפונקציה אחת דרך פונקצית void בעזרת מצביע, כך שלא צריך return.
כך שאם למשל יש לי משתנה num שהוא integer ומכיל מספר למשל 123, ותוך כדי פונקציה כלשהי אני רוצה לשלוח אותו לפונקצית void הראשונה (שהופכת מספר אינטגר למחרוזת) אז אני שולחת אותו מהפונקציה שאני נמצאת בה עכשיו בתור מצביע לפונקציה הראשונה (void), ואז כש- num יחזור הוא יהיה מחרוזת שמכילה את 123 או שהמחרוזת 123 תהיה תחת משתנה אחר נגיד numstr?

בכל מקרה, זה לא מסתדר לי כי הפונקציה שעובדת נראית כך:
קוד PHP:
 int div_by3(char *numstr)
{
int sum=sum_digits(numstr);
if (
sum 10)

switch(
sum)
{
case 
0:
case 
3:
case 
6:
case 
9:
return 
1/* true */
}
return 
0/* false */
}
else
{
num2str(sumnumstr);
return (
div_by3(numstr));
}



בשורה לפני האחרונה:
num2str(sum, numstr);
אני שולחת את sum שהוא מכיל מספר כלשהו גדול מ-10 לפונקציה הראשונה שתחזיר אותו בתור מחרוזת תחת השם numstr.. מאד מבלבל כל הקטע של המשתנים.
אולי תוכל לכתוב לי 'דוגמא' שאומרת שלב שלב עבור מספר כלשהו שנקלט בפונקציית מיין

קוד PHP:
 scanf("%s",str);
res div_by3(str); 

מה קורה למחרוזת ותחת איזה שם היא?
למשל אם אני קולטת את המספר 123 תחת str, ואת str שולחת לפונקציה שבודקת אם מתחלק ב-3. הפונקציה שבודקת חלוקה ב-3 מוגדרת כך:
קוד PHP:
 int div_by3(char *numstr

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

אממ אני מקווה שהבנת למה אני מתכוונת, אני חושבת שאולי מן הסבר שהוא "סיפור" של המחרוזת מרגע הקליטה עד הפליטה יבהיר עניינים והערת ביניים, כל הסיפור הזה של המצביעים נראה לי כמו פאשלה אחת גדולה ביצירה של שפת C. סתם מבלבל.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #55  
ישן 13-02-2009, 21:04
  Tankado Tankado אינו מחובר  
 
חבר מתאריך: 24.01.09
הודעות: 58
בתגובה להודעה מספר 54 שנכתבה על ידי *~.Shush.~* שמתחילה ב "אם הבנתי נכון, אני יכולה..."

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

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

ובקשר להערה של מצביעים, שפת C מאפשרת לך גישה למצביעים זה לא אומר שהם לא קימיים בכל השפות האחרות בשביל לרדת לעומק העניין ולהבין יותר איך הכל עובד את צריכה ללומד דברים יותר מורכבים ממה שאת יודעת, עדיף שתנסי בהתחלה לפשט לך את הדברים במקום לנסות לרדת לעומק
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #56  
ישן 13-02-2009, 21:54
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 55 שנכתבה על ידי Tankado שמתחילה ב "אני אמנם לא מי שמשקיע ועונה..."

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

שוש, אני אנסה לעשות לך קצת סדר כי הלכת לאיבוד לגמרי.
את לא יכולה לשנות טיפוס של משתנה. אם יצרת משתנה מסוג int, את לא יכולה לשנות אותו שיהיה פתאום מחרוזת. זה לא עובד ככה.
מה שאת כן יכולה לשנות, זה את הערך שלו. זאת אומרת שאם יצרת משתנה int, לדוגמא בשם num, ושלחת אותו לפונקציה, את יכולה לשנות את הערך המספרי של המשתנה.
דוגמא לשינוי הערך בשליחה רגילה (by value):
קוד PHP:
 int num 5;
num power(num);
...
int power (int num)
{
    return 
num num;


שימי לב כי לא באמת שינית את הערך של num בתוך הפונקציה. את בפועל העתקת את הערך "5" לתוך משתנה חדש בשם num שנמצא מקומית בתוך הפונקציה power והחזרת את התוצאה של החישוב.
לא שיניתי את num כי אם הייתי כותב:
;(num2 = power (num
אז המשתנה num היה נשאר 5 ואילו num2 היה מקבל את הערך 25.

אם הייתי רוצה באמת לשנות את הערך של num, הייתי שולח את הכתובת שלו לפונקציה (by reference):
קוד PHP:
 int num 5;
power (&num)
...
void power (intnum)
{
num num num;


שימי לב שאין לי שום צורך להחזיר משהו מהפונקציה (אם כי יכלתי.. אני לא חייב שהפונקציה תהיה void, יכלתי גם לעשות איזה return 1) כי ברגע ששיניתי את num, אני שיניתי את הערך שהיה בכתובת שקיבלתי.

תחשבי על כל העסק הזה, כעל דף תרגילים שאת מעתיקה מחברה... אם היא תתן לך את הדף שלה, ואת תרצי לבצע שינויים, את לא תשני שום דבר בדף שלה... את תעתיקי את הכל אליך ואז תבצעי איזה שינויים שאת רוצה בדף שלך. את תקבלי דף אחר (תוצאה שונה) והדף שלה ישאר כמו שהוא. זה נקרא "הבאת משתנים by value". למה by value? כי את מעתיקה את הערכים (values) שהיו במשתנים המקוריים לתוך משתנים חדשים ואת מבצעת את העבודה על המשתנים החדשים שלך.

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

דוגמא שאולי תעזור לך להבין את ההבדלים:
קוד PHP:
 #include <stdio.h>
#include <conio.h>

void power (int*);
int power (int);

int main ()
{
    
int x 5;
    
printf ("x is in address: %d, and its value is: %d\n\n",&xx);
    
// send x by value (5)
    
power (x);
    
5;
    
// send x by reference (address)
    
power (&x);
    
printf ("x is in address: %d, and its value is: %d\n\n",&xx);
    
getch();
}
// this function recieves x by value (value is x=5)
int power (int x)
{
    
printf ("x is in address: %d, and its value is: %d\n\n",&xx);    
    return 
x;
}
// this function recieves x by reference (reference is address of x)
void power (intx)
{
    
printf ("x is in address: %d, and its value is: %d\n\n",x, *x);
    (*
x) = (*x)*(*x);


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

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

מתי אפשר להשתמש במצביעים כדי להקל על כתיבת קוד?
נניח שיש לנו פונקציה שצריכה "להחזיר" כמה משתנים...
יש לנו x, y, z, ו- sum, כולם מטיפוס int ואנחנו צריכים להחזיר את כל המשתנים האלה.
אבל, אי אפשר לעשות:
return x
return y
return z
return sum ...
אפשר לעשות רק return אחד בלבד... אז איך אני מחזיר את כל המשתנים הללו?
קוד PHP:
 #include <stdio.h>
#include <conio.h>

void func1 (intxintyintzintsum);

int main ()
{
    
int x 5;
    
int y 0;
    
int z 3;
    
int sum 0;
    
func1 (&x, &y, &z, &sum);
    
getch();
}

void func1 (intxintyintzintsum)
{
    (*
x) = 1;
    (*
y) = 2;
    (*
z) = (*x)+(*y);
    (*
sum) = (*x)+(*y)+(*z);


מעביר אותם by reference ע"י מצביעים, וכך אני משנה את כל הערכים שלהם למה שבא לי, ובסוף אני אפילו לא צריך להחזיר ולו משתנה אחד, אם כי זה אפשרי (שוב, שלא תגידי שאני אמרתי שאת חייבת void או משהו... ממש לא).
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com


נערך לאחרונה ע"י Narxx בתאריך 13-02-2009 בשעה 21:59.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #59  
ישן 15-02-2009, 13:21
צלמית המשתמש של Narxx
  משתמש זכר Narxx Narxx אינו מחובר  
 
חבר מתאריך: 21.12.04
הודעות: 30,021
בתגובה להודעה מספר 58 שנכתבה על ידי Dragonion שמתחילה ב "אם המשתנה שלך הוא מלכתחילה..."

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

הדוגמא של Dragonion מבהירה את זה בצורה מצויינת. את יכולה לראות שהוא יכול פשוט לשלוח מצביע, או לשלוח כתובת של משתנה שאינו מצביע.
הבעיה עם הדוגמא שלו היא שאת לא יכולה להגיד למצביע שרק נוצר, שהערך במקום אליו הוא מצביע שווה למשהו (כיוון שאת לא יודעת לאן הוא מצביע.. יש בפנים זבל.. אולי זה מתפרש כמקום בזיכרון שכבר תפוס?).
קוד PHP:
 int x 2;
int *y;
= &x;
*
3;

power (&x);
power (y); 

עכשיו זה בסדר
_____________________________________
בברכה, מתן.
www.MatanNarkiss.com

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
תגובה

כלי אשכול חפש באשכול זה
חפש באשכול זה:

חיפוש מתקדם
מצבי תצוגה דרג אשכול זה
דרג אשכול זה:

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

קוד vB פעיל
קוד [IMG] פעיל
קוד HTML כבוי
מעבר לפורום



כל הזמנים המוצגים בדף זה הם לפי איזור זמן GMT +2. השעה כעת היא 23:12

הדף נוצר ב 0.26 שניות עם 10 שאילתות

הפורום מבוסס על vBulletin, גירסא 3.0.6
כל הזכויות לתוכנת הפורומים שמורות © 2024 - 2000 לחברת Jelsoft Enterprises.
כל הזכויות שמורות ל Fresh.co.il ©

צור קשר | תקנון האתר