עבור לתוכן

שאלה קצת מביכה ב-C++

Featured Replies

פורסם

אני יודע שזה בסיסי אבל זה פשוט עף לי מהראש :\

אם אני בודק שני תנאים כך:

if(table[i][j]==true && checkT(i,j,table))

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

ועוד דבר לא מזמן עברתי לVisual C++ ואני זוכר שבקומפיילרים מודרניים אחרים (כמו ECLIPSE בשביל JAVA) הייתה אפשרות שכאשר פותחים סוגר מסולסל ועוברים שורה הסוגר השני ייווצר אוטומטית. האם יש דרך לעשות את זה בVISUAL C++ 2005?

תודה

פורסם

אם התנאי הראשון הוא FALSE, התנאי השני לא יבדק.

כדי שהוא יבדוק גם את התנאי השני(כדי שהוא יקרא לפונקציה, אתה צריך לרשום:

if(table[i][j]==true & checkT(i,j,table))

אשר, למעשה, פועל על הביטים, ומחייר ששני הביטויים יחושבו לפני פעולת האופרטור.

פורסם

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

פורסם

אתם בטוחים שזה מאפיין של השפה (שכתוב בספיקציה שלה), ולא פשוט אופטימזציה של הקומפיילר הספציפי?

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

פורסם
  • מחבר

אתם בטוחים שזה מאפיין של השפה (שכתוב בספיקציה שלה), ולא פשוט אופטימזציה של הקומפיילר הספציפי?

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

במקרה השני אני צריך לשעות עוד if שיבדוק את תוצאת ההחזרה(+צריך להחזיר לאנשהו את התוצאה) אחרת יש לי if אחד ושורת RETURN אחת. נראה לי שזה גם חוסך שורות וגם משתנים. מה הכוונה ב"מכוער" ?

פורסם

לא התכוונתי לפיתרון שלך - שעל פניו נראה בסדר גמור.

התכוונתי לבעיה החדשה שהציג UnsignedInteger.

פורסם

כל עוד אתה לא מעמיס את האופרטור, כך הוא יפעל.

פורסם

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

פורסם

למה שפשוט לא יהפוך את התנאים :

if(checkT(i,j,table) && table[i][j]==true)

וככה הפונקציה תפעל.

או שאולי הפונקציה checkT משנה משהו במערך table ?

פורסם

אתם בטוחים שזה מאפיין של השפה (שכתוב בספיקציה שלה), ולא פשוט אופטימזציה של הקומפיילר הספציפי?

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

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

זה מאפיין של השפה (ועוד הרבה שפות אחרות), ודי סטנדרטי. שימוש נפוץ לזה הוא (לדוגמה):

if (obj != null && obj->isValid())

(כאשר obj הוא מצביע לאובייקט מטיפוס שיש לו פונקציה isValid, כמובן).

אתה מסתמך על זה שאם obj == null, אז החלק השני לא ירוץ (אם כן, הוא היה מעיף שגיאה).

זה חוסך קריאה לשני if (גם יותר יעיל, וגם יותר קריא).

במקרה השני אני צריך לשעות עוד if שיבדוק את תוצאת ההחזרה(+צריך להחזיר לאנשהו את התוצאה) אחרת יש לי if אחד ושורת RETURN אחת. נראה לי שזה גם חוסך שורות וגם משתנים. מה הכוונה ב"מכוער" ?

bool a = table[i][j];
bool b = checkT(i,j,table);
if (a && b)

נשארת עם if אחד. בדוגמה הזו כמובן יכלת גם לחסוך את a, סתם הבאתי אותו כדוגמה.

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

הסיבה שהקוד הוא "מכוער":

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

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

פורסם

ואפשר, פשוט, להשתמש באופרטור פסיק.

פורסם

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

פורסם

התרומה שלי לנושא:

1) לתכונה שעליה דיברנו קוראים לפעמים Lazy Evaluation (אם כי בשפות אחרות יש לזה משמעות קצת אחרת), וקוראים לה גם short circuiting. היא פועלת גם על || וגם על &&. היא בפירוש חלק מהסטנדרט.

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


if ( x > 0 && y++ < MAX_Y ) // Problem! Side effect in short circuited expression
{
// ....
}

3) אני מתחנן, Unsigned Integer, אל תחנך פה דור חדש לכל מני hack-ים שיגרמו לנו אחרי זה צרות בתחזוקה. קודם שישתמשו נכון בדברים הרגילים. עדיף לא להשתמש ב-& ו-| (שהם פעולות על ביטים) עבור boolean evaluation. כנ"ל פסיקים. ו-duff's device.

C היא שפה כיפית, וחשוב להכיר את הפינות שלה ואת הטריקים שלה. אבל לפני שעושים את זה, קודם חשוב שידעו לכתוב קוד נכון, קריא ובריא.

4) אפשר לעשות כל מני דברים מטורפים עם פסיקים, לדוגמא:


if ( a >= 0 && ( x[a] = y, y > 5 ) ) // Horrible hack! Just say "no"!
{
// ...
}

פורסם

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

אז? יש ה-מ-ו-ן דוגמאות של פלט שונה או אי-קומפוליציה בין GCC לVS לINTEL COMPILER...

בנוסף עצה לכל קוראי הדיון, נדירים המקרים שבו כדי בIF לקרוא לפונקציה שעשויה לשנות ערכים. זה לא קריא בעליל. זה לא דיזיין נכון, וזה לא יעבור CODE REVIEW.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים