אשמח לדעת מדוע הפלט המתקבל מהקוד הבא הוא : 3 2 1

selalerer

New member
תפוס את מי שכתב את הקוד הזה וזרוק אותו מצוק

&nbsp
זה מסתמך על זה שיש תו NUL בסוף המחרוזת ושערכו הוא אפס ושתנאים ב-C מחשיבים 0 כ-false ולכן מסתיימת הלולאה.
 

BravoMan

Active member
לפני שהולכים למתודולוגית פיתוח דעאש, כדאי לבדוק מה אומר תקן

השפה:
1. תו נועל של מחרוזת ב-C אינו NULL אלא "תו אפס" 0\
ואלה דברים שונים.
NULL הוא define תלוי ארכיטקטורה שמשמעותו "מצביע ריק" ואכן יכול להיות משהו שאינו 0 (קראתי שיש ארכיטקטורות שם זו כתובת נמוכה כגון 0x00000020).
&nbsp
אבל 0\ תמיד יהיה בעל ערך 0.
&nbsp
2. התקן של C אינו מגדיר טיפוס boolean ואינו מגדיר ערך false כערך עצמאי.
(זה נוסף בתקן 99, אבל עדיין תואם אוחרנית בצורה מלאה והשימוש מצריך include, כך שזו לא ממש "תוספת אינטגרלית של טיפוס חדש" כפי שקיים בשפות אחרות דוגמת Java)
&nbsp
במקום זה הוא קובע שערך 0 הוא false.
אני מניח שזו החלטה שנובעת מפקודות JMP שזמינות למימוש תנאים (הרי מפתחי C רצו שהיא תהיה כמה שיותר קרובה לברזלים)
&nbsp
3. הדבר היחיד שלא הייתי בטוח לגביו אם הוא בתקן או לא, זה האם הקומפיילר חייב לשים תו 0\ בסוף string literal.
&nbsp
גיגול מהיר מראה שאכן חובה:
http://en.cppreference.com/w/cpp/language/string_literal
ואני יודע שקומפיילרים גדולים כגון gcc ו-vc עושים זאת.
 

Javali

New member
תיקונים

שלושה תיקונים קלים:
1. התו שבו כל הביטים 0 נקרא null character.
2. המקרו NULL מוגדר בסטנדרט ככזה שערכו הוא ה-null pointer constant. ההגדרה של null pointer constant היא ביטוי קבוע שערכו 0, או כזה ביטוי שמומר ל-* void. זה נכון שערך הביטים של NULL לא חייב להיות 0, אבל השוואה של NULL ל-0 צריכה להחזיר ערך לוגי true.
3. מפתחי C לא רצו שהיא תהיה כמה שיותר קרובה לברזלים. הם רצו שפה יותר רחוקה מהברזלים מאשר מה שהיה להם קודם, ומה שיצא זה C.

התמונות מתוך אחת הטיוטות של C99. ההדגשה שלי.



 

BravoMan

Active member
הצדק איתך ועם Javali, התבלבלתי במונחים.

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

BravoMan

Active member
כי יש 4 תווים במחרוזת...

כדי להבין את הקוד הזה, צריך לדעת כמה דברים:
1. ב-C, ערך 0 הוא false וכל ערך אחר הוא true.
2. כל מחרוזת חוקית ב-C חייבת להסתיים בתו נועל 0.
3. כאשר כותבים string literal (מגדירים מחרוזת בקוד עם גרשיים), הקומפיילר מוסיף תו 0 אוטומטית.
4. מחרוזת ב-C היא מערך תווים.
5. מערכים ב-C מיוצגים ע"י מצביע לאיבר הראשון, ונשמרים בזיכרון ברצף כך שניתן לעבור על כל תא במערך ע"י הזזת המצביעה (חשבון מצביעים).
6. אופרטור * ב-C פירושו "תתייחס לערך שבכתובת", כלומר הוא עושה מה שנקרא dereference למצביע.
&nbsp
אם הבנת את כל אחד מהסעיפים הנ"ל, אתה אמור להבין מה הקוד עושה ואיך הוא עושה את זה.
 

פרסאוס

New member
שאלה טובה.

לא קוד שהייתי רוצה לראות בישום אמיתי, אבל השאלה נחמדה.
ראשית, המחרוזת מבלבלת. אם תחליף את התוכן ב"1234" תקבל את אותו הדבר.
שנית, נסה עם כמה מחרוזות: "1234", "123456" וכו. רואה את ההבדל?
הלאה. מחרוזת היא מערך. שם המחרוזת הוא מצביע והתא האחרון שווה NULL.
הלולאה הזו רצה בעצם על המחרוזת עד התו האחרון, זה הכל.
תוכן המחרוזת נועד כדי לבלבל ותו לא.
 
למעלה