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

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



  #2  
ישן 22-03-2010, 00:12
  Dark Knight Dark Knight אינו מחובר  
 
חבר מתאריך: 30.07.05
הודעות: 949
שלח הודעה דרך ICQ אל Dark Knight
בתגובה להודעה מספר 1 שנכתבה על ידי adi:-) שמתחילה ב "הי אני חדשה פה...!"

כעקרון כן - קוד של C אמור להתקמפל עם מהדר ++C עם כמות שינויים מינימאלית, אז לשאלה אם זה אפשרי התשובה היא: כן

אבל ניתן לשאול גם שאלה נגדית: למה לך לעשות דבר כזה?
איזה יתרון את רואה בשימוש ב-void* על פני שימוש בפולימורפיזם (שנובע מירושה) ו-templates?

כעקרון את צריכה משהו כזה:
קוד PHP:
 class generic_list
{
public: 
// Definitions
    
typedef voidelement;
public: 
// Interface
    
generic_list() : head(NULL), tail(NULL), iterator(NULL), size(0) {}

    ~
generic_list() 
    {
        while(!
Node::IsFinished(head))
        {
            
Node *help head;
            
head head->GetNext();
            
delete help;
        }
    }

    
void push_back(element d)
    {
        
Node *= new Node(dNULLtail);
        
tail n;
        if (
head == NULL) { // First element in the list
            
head tail;
        }
        ++
size;
    }

    
void push_front(element d)
    {
        
Node *= new Node(dheadNULL);
        
head n;
        if (
tail == NULL) { // First element in the list
            
tail head;
        }
        ++
size;
    }

    const 
element IterateFromStart()
    {
        
iterator head;
        return 
GetCurrent();
    }

    const 
element IterateFromEnd()
    {
        
iterator tail;
        return 
GetCurrent();
    }

    const 
element GetCurrent() const
    {
        if (!
Node::IsFinished(iterator)) {
            return 
iterator->GetData();
        } else {
            return 
NULL// In proper implementation - a throw would be better...
        
}
    }

    
bool IterateNext()
    {
        if (!
Node::IsFinished(iterator)) {
            
iterator iterator->GetNext();
            return 
true;
        }  else { 
// In proper implementation, a throw for else would be in order...
            
return false;
        }
    }

    
bool IteratePrev()
    {
        if (!
Node::IsFinished(iterator)) {
            
iterator iterator->GetPrev();
            return 
true;
        }  else { 
// In proper implementation, a throw for else would be in order...
            
return false;
        }
    }

    
bool IteratorDone() const
    {
        return 
Node::IsFinished(iterator);
    }

    
void InsertAfterCurr(element d)
    {
        
iterator->InsertNext(d);
    }

    
void InsertBeforeCurr(element d)
    {
        
iterator->InsertPrev(d);
    }

    
void DeleteCurr(bool next true// the input means the direction to advance - next or prev
    
{
        if (
Node::IsFinished(iterator)) { // No point in doing anything if finished...
            
return; // Or throw, for proper implementation
        

        if (
iterator == headhead iterator->GetNext();
        if (
iterator == tailtail iterator->GetPrev();
        
Node *help iterator;
        
iterator = (next) ? iterator->GetNext() : iterator->GetPrev();
        
delete help;
        --
size;
    }
private: 
// Helper classes
    
class Node
    
{
    public: 
// Interface
        
Node(element dNode *NULLNode *NULL) : data(d), next(n), prev(p) { }

        ~
Node()
        {
            if (
prev) { // If prev not NULL => there is a previous node
                
prev->next next// maintain connection
            
}
            if (
next) { // If next not NULL => there is a next node
                
next->prev prev// maintain connection
            
}
            if (
datadelete data// If data isn't NULL => release resources
        
}

        const 
element GetData() const { return data; }
    
        
Node *GetNext() const { return this->next); }

        
Node *GetPrev() const { return this->prev); }

        
void InsertNext(element data)
        {
            
Node *= new Node(datathis->nextthis);
            
this->next n;
        }

        
void InsertPrev(element data)
        {
            
Node *= new Node(datathisthis->prev);
            
this->prev n;
        }

        static 
bool IsFinished(Node *node) { return (node == NULL); }
    private: 
// Members
        
element data;
        
Node *next;
        
Node *prev;
    };
private: 
// Members
    
Node *head;
    
Node *tail;
    
Node *iterator;
    
size_t size;
}; 


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

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

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


נערך לאחרונה ע"י Dark Knight בתאריך 22-03-2010 בשעה 00:16.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #5  
ישן 22-03-2010, 22:14
  Dark Knight Dark Knight אינו מחובר  
 
חבר מתאריך: 30.07.05
הודעות: 949
שלח הודעה דרך ICQ אל Dark Knight
בתגובה להודעה מספר 4 שנכתבה על ידי adi:-) שמתחילה ב "וואו איזו מהירות!"

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

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

בכל מקרה, זה צריך להראות כמו משהו כזה:
קוד PHP:
 class LinkedList
{
public: 
// Definitions
    
typedef void *Element// Definition of the lists element unit
    // CopyFunction: receives an element and allocates a copy of it.
    
typedef Element (*CopyFunction)(Element source);
    
// FreeFunction: receives an element and releases all it's resources
    
typedef void (*FreeFunction)(Element elem);
    
// CompareFunction: receiving 2 elements and returning:
    //    Negative value if e1 < e2
    //    0 if e1 == e2
    //    Positive value if e1 > e2
    
typedef int (*CompareFunction)(Element e1Element e2);
    
    
// Result codes
    
typedef enum LIST_SUCCESSLIST_FAILURELIST_OUT_OF_MEMLIST_ELEMENT_NOT_FOUND Result;
public: 
// Interface
    
LinkedList(CopyFunction cpyFreeFunction delCompareFunction cmp) :
        
head(NULL), size(0), fCopy(cpy), fFree(del), fCompare(cmp) { }
    
    ~
LinkedList
    
{
        
Node *help(head);
        while (
head != NULL) {
            
head head->next;
            
fFree(help->data); // Release element's resources
            
delete help;    // Delete the node
        
}
    }
    
    
Result InsertNew(Element elem)
    {
        
Element e(fCopy(elem));
        
Node *n(new Node);
        
// In trueth, should test if allocation failed...
        
n->next head;
        
head->next n;
        ++
size;
    }
    
    
unsigned int GetSize() const { return size; }
private: 
// Helper objects
    
struct Node
    
{
        
Element data;
        
Node *next;
    };
private:
    
Node *head;
    
unsigned int size;
    
    
CopyFunction fCopy;
    
FreeFunction fFree;
    
CompareFunction fCompare;
}; 


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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #10  
ישן 23-03-2010, 15:04
  adi:-) adi:-) אינו מחובר  
 
חבר מתאריך: 21.03.10
הודעות: 13
LinkedList.h
בתגובה להודעה מספר 9 שנכתבה על ידי Dark Knight שמתחילה ב "תעלי את הקוד לכאן, אני אעיף..."

#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include<iostream>
usingnamespace std;

class LinkedList
{
public: // Definitions
typedefvoid* Element; // Definition of the lists element unit
// CopyFunction: receives an element and allocates a copy of it.
typedef Element (*CopyFunction)(Element source);
// FreeFunction: receives an element and releases all it's resources
typedefvoid (*FreeFunction)(Element elem);
// CompareFunction: receiving 2 elements and returning:
// Negative value if e1 < e2
// 0 if e1 == e2
// Positive value if e1 > e2
typedefint (*CompareFunction)(Element e1, Element e2);

// Result codes
typedefenum { LIST_SUCCESS, LIST_FAILURE, LIST_OUT_OF_MEM, LIST_ELEMENT_NOT_FOUND } Result;
private: // Helper objects
struct LinkedListObject
{
Element data;
LinkedListObject *next;
};
private:
LinkedListObject *head;
unsignedint size;

CopyFunction fCopy;
FreeFunction fFree;
CompareFunction fCompare;

public: // Interface
LinkedList(CopyFunction cpy, FreeFunction del, CompareFunction cmp) :
head(NULL), size(0), fCopy(cpy), fFree(del), fCompare(cmp){} //ctor
~LinkedList(); //dtor
Result InsertNew(Element elem);
unsignedint GetSize(); //return the number of elements
////////////****other functions I was asked to write for the program***************///////////////////////
//void deleteElement (Element elem); // delete the element elem
// Element findElemenet (int i); //find the i element
//Result ExistElement(Element elem, int j); //checks if an element is in the list starting j


};//end of class
#endif
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #15  
ישן 23-03-2010, 15:29
  adi:-) adi:-) אינו מחובר  
 
חבר מתאריך: 21.03.10
הודעות: 13
זה עבד! ירד ל4 שגיאות
בתגובה להודעה מספר 14 שנכתבה על ידי Dark Knight שמתחילה ב "א' - צרפי את השגיאות ב' - אני..."

רוצה להסביר לי למה זו כזו שורה מוזרה?
והנה השגיאות:
1>------ Build started: Project: class1, Configuration: Debug Win32 ------

1>Compiling...

1>LinkedList.cpp

1>c:\users\עדי\documents\visual studio 2008\projects\class1\class1\linkedlist.h(52) : error C3872: '0xa0': this character is not allowed in an identifier

1>c:\users\עדי\documents\visual studio 2008\projects\class1\class1\linkedlist.h(57) : error C2143: syntax error : missing ';' before '}'

1>c:\users\עדי\documents\visual studio 2008\projects\class1\class1\linkedlist.h(57) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

1>c:\users\עדי\documents\visual studio 2008\projects\class1\class1\linkedlist.cpp(24) : error C2511: 'unsigned int LinkedList::GetSize(void) const' : overloaded member function not found in 'LinkedList'

1> c:\users\עדי\documents\visual studio 2008\projects\class1\class1\linkedlist.h(7) : see declaration of 'LinkedList'

1>Build log was saved at "file://c:\Users\עדי\Documents\Visual Studio 2008\Projects\class1\class1\Debug\BuildLog.htm"

1>class1 - 4 error(s), 0 warning(s)

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #16  
ישן 23-03-2010, 15:34
  Dark Knight Dark Knight אינו מחובר  
 
חבר מתאריך: 30.07.05
הודעות: 949
שלח הודעה דרך ICQ אל Dark Knight
בתגובה להודעה מספר 15 שנכתבה על ידי adi:-) שמתחילה ב "זה עבד! ירד ל4 שגיאות"

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

זה בדיוק אותו המצב כמו עם המתודות - המתודות מוגדרות פנימית בתוך המחלקה ולכן השם שלהן אינו מוכר מחוצה לה - וצריך לציין במפורש שאתה מממשת את המתודה InsertNew של LinkedList וזה נעשה ע"י שימוש בשם המלא של המתודה: LinkedList::InsertNew.
הסיבה שלא צריך לעשות זאת כשאת משתמשת במתודות היא שהן מופעלות מתוך אובייקט שכבר ידוע הטיפוס שלו ולכן למעשה ההקשר לשם ברור: list.InsertNew - משתמשים ב-InsertNew של האובייקט list.

צרפי בבקשה את קובץ ה-h החדש שלך.. אצלי זה מתקמפל ואין בכלל שורה 52 בקובץ h.

ככה זה נראה אצלי:
קוד PHP:
 #ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include<iostream>

class LinkedList
{
public: 
// Definitions
    
typedef voidElement// Definition of the lists element unit
    // CopyFunction: receives an element and allocates a copy of it.
    
typedef Element (*CopyFunction)(Element source);
    
// FreeFunction: receives an element and releases all it's resources
    
typedef void (*FreeFunction)(Element elem);
    
// CompareFunction: receiving 2 elements and returning:
    // Negative value if e1 < e2
    // 0 if e1 == e2
    // Positive value if e1 > e2
    
typedef int (*CompareFunction)(Element e1Element e2);

    
// Result codes
    
typedef enum LIST_SUCCESSLIST_FAILURELIST_OUT_OF_MEMLIST_ELEMENT_NOT_FOUND Result;
private: 
// Helper objects
    
struct LinkedListObject
    
{
        
Element data;
        
LinkedListObject *next;
    };
private:
    
LinkedListObject *head;
    
unsigned int size;

    
CopyFunction fCopy;
    
FreeFunction fFree;
    
CompareFunction fCompare;

public: 
// Interface
    
LinkedList(CopyFunction cpyFreeFunction delCompareFunction cmp) :
        
head(NULL), size(0), fCopy(cpy), fFree(del), fCompare(cmp) {} //ctor
    
~LinkedList(); //dtor
    
Result InsertNew(Element elem);
    
unsigned int GetSize() const; //return the number of elements
    ////////////****other functions I was asked to write for the program***************///////////////////////
    //void deleteElement (Element elem); // delete the element elem
    // Element findElemenet (int i); //find the i element
    //Result ExistElement(Element elem, int j); //checks if an element is in the list starting j


};//end of class
#endif 
_____________________________________
חתימתכם הוסרה כיוון שלא עמדה בחוקי האתר. לפרטים נוספים לחצו כאן. תוכלו לקבל עזרה להתאמת החתימה לחוקים בפורום חתימות וצלמיות.


נערך לאחרונה ע"י Dark Knight בתאריך 23-03-2010 בשעה 15:38.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #18  
ישן 23-03-2010, 16:00
  Dark Knight Dark Knight אינו מחובר  
 
חבר מתאריך: 30.07.05
הודעות: 949
שלח הודעה דרך ICQ אל Dark Knight
בתגובה להודעה מספר 17 שנכתבה על ידי adi:-) שמתחילה ב "זה רץ!"

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

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

לסיכום אני אתן לך מימוש לדוגמא של איך 3 הפונקציות הללו צריכות להראות עבור int, למשל:

קוד PHP:
 LinkedList::Element CopyInt(LinkedList::Element source)
{
    return 
source;
}

void FreeInt(LinkedList::Element elem)
{
    return;
}

int CompareInt(LinkedList::Element e1LinkedList::Element e2)
{
    return ((int)
e1) - ((int)e2);



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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #20  
ישן 23-03-2010, 23:26
  Dark Knight Dark Knight אינו מחובר  
 
חבר מתאריך: 30.07.05
הודעות: 949
שלח הודעה דרך ICQ אל Dark Knight
בתגובה להודעה מספר 19 שנכתבה על ידי adi:-) שמתחילה ב "רק שאלה אחרונה--"

אה..
פה אני דוחף לראש הרשימה...
הפעם הרשימה היא חד-כיוונית ולכן ע"מ להוסיף איבר לסוף הרשימה צריך קודם ללכת אל סופה:
קוד PHP:
 LinkedList::Result  LinkedList::InsertNew(Element elem){
    
Element e(fCopy(elem));
    
LinkedListObject *n(new LinkedListObject);
    
// In trueth, should test if allocation failed...

    
if (head == NULL) { // List was empty, this is the first element
        
head n;
    } else {
        
LinkedListObject *it(head)
        for (; 
it->next != NULLit it->next); // find the last element of the list
        
        
it->next n// add the new element after it
    
}
    
    ++
size;
    return  
LIST_SUCCESS;

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

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #22  
ישן 24-03-2010, 11:18
  Dark Knight Dark Knight אינו מחובר  
 
חבר מתאריך: 30.07.05
הודעות: 949
שלח הודעה דרך ICQ אל Dark Knight
בתגובה להודעה מספר 21 שנכתבה על ידי adi:-) שמתחילה ב "סבבה אבל, איפה בא לידי ביטוי..."

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

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

מהבחינה הזו - את צודקת בדיוק:
השורה Element e(fCopy(elem)); יוצרת עותק חדש של elem.
השורה n->data = e שמשום מה חסרה (אופס...) אמורה הייתה להכניס את e להיות המידע שנשמר ב-n ובסופו של דבר מוצאים את סוף הרשימה ומשרשרים את n לתוכה.

תוסיפי בבקשה את השורה n->data = e בין הקצאת n ל-(if (head == NULL
_____________________________________
חתימתכם הוסרה כיוון שלא עמדה בחוקי האתר. לפרטים נוספים לחצו כאן. תוכלו לקבל עזרה להתאמת החתימה לחוקים בפורום חתימות וצלמיות.

תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
  #24  
ישן 24-03-2010, 14:16
  Dark Knight Dark Knight אינו מחובר  
 
חבר מתאריך: 30.07.05
הודעות: 949
שלח הודעה דרך ICQ אל Dark Knight
בתגובה להודעה מספר 23 שנכתבה על ידי adi:-) שמתחילה ב "סבבה ולמה השתמשת בit ? אי..."

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

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

עריכה: זה מה שקורה כשכותבים קוד מהר...
השורה Node *help(head); ב-dtor הייתה צריכה להיות בתוך הלולאה ולא מחוץ לה...
_____________________________________
חתימתכם הוסרה כיוון שלא עמדה בחוקי האתר. לפרטים נוספים לחצו כאן. תוכלו לקבל עזרה להתאמת החתימה לחוקים בפורום חתימות וצלמיות.


נערך לאחרונה ע"י Dark Knight בתאריך 24-03-2010 בשעה 14:23.
תגובה ללא ציטוט תגובה עם ציטוט חזרה לפורום
תגובה

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

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

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

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



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

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

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

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