לא מחשב נכון מטריצה בC++-בית קולנוע - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

לא מחשב נכון מטריצה בC++-בית קולנוע


MrAlex

Recommended Posts

אני אמור לעשות בית עם מושבים

0 מסמל מושב ריק

1 מושב תפוס

כך בית הקולנוע ניראה בהתחלה

0 0 0 0

0 0 0 0

0 0 0 0

0 0 0 0

וככה הוא אמור להיראות אחרי ש2 אנשים ביקשו כרטיס

0 0 1 1

0 0 0 0

0 0 0 0

0 0 0 0

מה שקורה הוא מדפיס יותר מדי אפסים וכו

ולא מחליף באחד הנה הקוד:

MAIN


#include "cinema.h"
using namespace std;

int main()
{
cinema p1,start;
start.startshow();
int z;
cout<<'\n';
cout<<"put in number of people\n";
cin>>z;
p1.z;
cin.ignore(z);
system("cls");
p1.arr();
cin.get();
return 0;
}

הנה המחלקה


struct cinema{
int z;
int x[4][4];
void print();
void counter();
void arr();
void check (int p,int o);
void change(int j);
void startshow();
};
void cinema :: arr() //initiallisasion
{
int i,j;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
x[j][i]=0;

}
counter();
}
void cinema :: counter() //counter free spaces
{
int i,j,sum;
sum=0;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
if(x[j][i]=0)
sum=sum++;
}
check(sum,j);
}
}
void cinema :: check(int p,int o) //check free spaces more than damand
{
int j;
j=o;
{
if(z<=p)
{
change(j);
}
}
}


void cinema :: change(int j) //change free to catched spaces
{
int i,sum=0;
for(i=0;i<4;i++)
{
if(sum<=z)
if(x[j][i]==0)
{
x[j][i]=1;
sum=sum++;
}
}
print();
}
void cinema :: print() //print
{
int i,j;
for(j=0;j<4;j++)
{
cout<<'\n';
for(i=0;i<4;i++)
{
cout.width(5);
cout<<x[j][i];
}
}
}
void cinema :: startshow() //print the cinema at start
{
int i,j;
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
x[j][i]=0;

}

for(j=0;j<4;j++)
{
cout<<'\n';
for(i=0;i<4;i++)
{
cout.width(5);
cout<<x[j][i];
}
}
}

קישור לתוכן
שתף באתרים אחרים

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

ב. מה אמורה לעשות השורה הזו שמופיעה כמה פעמים בקוד?

sum=sum++;

כדאי שתלמד איך משתמשים באופרטור ++.

קישור לתוכן
שתף באתרים אחרים

אני אסביר את אופן התוכנית,

זה בטח בגלל שאין שמות למשתנים :P

פונקצייה ARR מאתחלת את המערך באפסים

הפוקנצייה CHECK בודקת את המקומות הפנויים(מקום פנוי מקבל את הערך 0)

בפונקצייה CHECK המשתנה SUM אמור לקדם את עצמו ב1 ולספור את המקומות הפנויים באותה שורה

משם לקרוא לפונקצייה CHECK ושולחת לפונקצייה את מספר השורה(הערך J) ואת SUM

והפונקצייה CHECK בודקת אם המקמות הפנויים מספיקים למספר המקומות המבוקשים,

משם היא קוראת לפוקנצייה CHANGE

שסורקת את השורה ובודקת איפה שיש 0 ומחליפה אותו באחד

מקדמת את SUM ב1 (כאן SUM נוצר כדי לוודא שלא יתחלפו יותר מדי מקומות פנוים ל1).

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

מובן יותר ><"?

קישור לתוכן
שתף באתרים אחרים

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

זה בטח בגלל שאין שמות למשתנים :P

אז תן להם שמות נורמליים. מה זה בכלל z? למה הוא משמש? איפה אתה בכלל מאתחל אותו? לא ברור בעליל.

פונקצייה ARR מאתחלת את המערך באפסים

אז למה קוראים לה arr? למה שלא תקרא בשם "אתחול" או "ניקוי" או משהו כזה (באנגלית כמובן)?

הפוקנצייה CHECK בודקת את המקומות הפנויים(מקום פנוי מקבל את הערך 0)

מה זאת אומרת "בודקת את המקומות הפנויים"? מה היא הבדיקה? מה התוצאה של הפונקציה?

מה עם הפונקציות counter ו-change? למה הפונקציה change בכלל קוראת ל-print (מה הקשר ביניהן)?

למה הפונקציה startshow גם מאפסת וגם מדפיסה את המערך? ואם כבר, אז למה היא לא פשוט קוראת לפונקציות arr ו-print בשביל לעשות את זה?

למה יש לך שני אובייקטים של (p1 ו-start)?

מה אמורות לעשות שלוש השורות הבאות? אין בהן שום הגיון:


cin>>z;
p1.z;
cin.ignore(z);

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

כמה טיפים:

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

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

קישור לתוכן
שתף באתרים אחרים

עוד טיפ לגבי החלוקה לפונקציות - תשתמש בתכנון top down. הכוונה היא שלפני שאתה כותב את המחלקה, תשתמש בה.

למשל, הבנאי של המחלקה מן הסתם יאתחל את הטבלה לאפסים. אח"כ אם צריך לאפס את הטבלה שוב, תקרא לפונקציה clean\initialize (עוד לפני שמימשת אותן!). אתה צריך למצוא מקום פנוי? תקרא לפונקציה getEmptySpot למשל.

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

כשקיימת פונקצייה בשם check - מה היא בודקת?

כשאני רואה פונקצייה עם check בשם, אני מצפה לפונקצייה שמחזירה ערך בוליאני. אם אתה מצפה לערך אחר, תשתמש במילה get למשל.

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

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

שהיא תפסה או האם היה מקום פנוי שנתפס או לא.

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

ואחרים שמייצגים למשל מספר שורה ומספר טור.

קישור לתוכן
שתף באתרים אחרים

טוב הנה הקוד החדש

יש אותם בעיות+-

MAIN


#include "cinema.h"
using namespace std;
int main()
{
int numberPeople;
cout<<"write number of people\n";
cin>>numberPeople;
cinema people;
people.numberPeople;
people.init();
people.getEmptySpot();
cin.ignore(numberPeople,'\n');
cin.get();
return 0;

}

CLASS CINEMA


#include <iostream>
#include <Windows.h>
using namespace std;
class cinema{
int x[4][4];
int numberOfPeople;
public:
int numberPeople;
void init();
void print();
void getEmptySpot();
void changeEmptySpot(int row);

};
void cinema :: init()
{
int column,row;
numberOfPeople=numberPeople;
for(row=0;row<4;row++)
{
for(column=0;column<4;column++)
{
x[row][column]=0;
}
}
print();

}
void cinema :: print()
{
int row,column;
for(row=0;row<4;row++)
{
cout<<'\n';
for(column=0;column<4;column++)
{
cout.width(5);
cout<<x[row][column];
}
}
cout<<'\n';
}
void cinema :: getEmptySpot()
{
int column,row,sum=0;
for(row=0;row<4;row++)
{
for(column=0;column<4;column++)
{
if(x[row][column]==0)
sum++;
}
changeEmptySpot(row);
}
}
void cinema :: changeEmptySpot(int row)
{
int column,sum=0;
for(column=0;column<4;column++)
{
if(numberOfPeople<=sum)
if(x[row][column]==0)
x[row][column]=1;
sum++;
}
print();
}

זה מדפיס לי כמה פעמים את הקולנוע

ולא מחליף את ה0 ב1 לפי הנידרש

קישור לתוכן
שתף באתרים אחרים

שוב התוכנית שלך מוזרה. המטרה שלך היא לקלוט מספר אנשים ולמלא את האולם בהתאם?

אתה יודע מה ההבדל בין class ל-struct ובכלל את עקרונות התכנות מונחה העצמים?

מה זה למשל cinema.people? למה החלטת שכל הפונקציות שלך לא צריכות להחזיר שום ערך (כלומר, void)?

קישור לתוכן
שתף באתרים אחרים

אני יודע מושגים אני יכול להגיד לך עכשיו כל דבר.

הנה:

STRUCT זהו קלאס שכל המתשנים פונקציות שלו הם מסוג PUBLIC

STRUCT גם יכול להיקרא מבנה כאשר יש בו רק משתנים.(לפחות לפי הספר "C++ כשפת אם")

אתה רוצה אני אענהגם על השאר :P

מה שאני מנסה לעשות פה זה לעשות פונקצייה קוראת לפונקצייה

ולא לקרוא מMAIN כל פעם לפונקצייה אחרת זה לפחות מה שאני הבנתי ממה שאתה הצעת או "שניצל").

קישור לתוכן
שתף באתרים אחרים

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

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

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

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

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

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

כאן תמצא ספר לא רע ללמוד ממנו בסיס לפני שאתה בכלל ניגש לOOP

http://www.hadassah.ac.il/cs/staff/danizobin/modprog1/Material.html

קישור לתוכן
שתף באתרים אחרים

ארכיון

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

×
  • צור חדש...