pointers practice

Jan 2, 2015 at 11:45am
hello im practicing pointers im not good at using it yet.
1. am i doing it right?
2. isnt it good to put char selection to local scope instead of making it variable parameter?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iostream>
void miniShop(char&);
void drinks(char,std::string*,int&,int*);
void foods(char,std::string*,int&,int*);
void desserts(char,std::string*,int&,int*);
void sale(char,std::string*,int&,int*);
int main() {
        char selection = '\0';
        std::string items = " ";
        int money = 500;
        int price = 0;
        miniShop(selection);
        switch ( selection ) {
                case '1':  drinks(selection , &items , price, &money); break;
                case '2':  foods(selection , &items , price, &money);break;
                case '3':  desserts(selection , &items , price, &money);break;
        }
        sale(selection , &items , price, &money);std::cout<< "Your money is "<< money;
}
void miniShop( char &select ) {
              do {
              std::cout << "\t\t\tWELCOME TO MY MINISHOP" << std::endl
                        << "\t\t\t[1]Drinks" << std::endl
                        << "\t\t\t[2]Foods" << std::endl
                        << "\t\t\t[3]Desserts" << std::endl;
              std::cin >> select;
              } while ( select != '1' && select != '2' && select!='3' );
}
void drinks( char select , std::string *i_ptr , int &price ,int* m_ptr ) {
            do {
            std::cout << "[1]Coffee = $15" << std::endl
                      << "[2]Soft Drinks = $25" << std::endl
                      << "[3]Alcohol = $65" << std::endl;
            std::cin >> select;
            } while ( select != '1' && select != '2' && select !='3' );
            switch ( select ) {
                    case '1': if ( *m_ptr >= 15 ) { *i_ptr = "Coffee"; price = 15; } else std::cout << "You dont have enough money thank you"; break;
                    case '2': if ( *m_ptr >= 25 ) { *i_ptr = "Soft Drinks"; price = 25; } else std::cout << "You dont have enough money thank you"; break;
                    case '3': if ( *m_ptr >= 65 ) { *i_ptr = "Alcohol"; price = 65; } else std::cout << "You dont have enough money thank you"; break;
            }
}
void foods( char select , std::string *i_ptr , int &price , int* m_ptr ) {
            do {
            std::cout << "[1]French fries = $125" << std::endl
                      << "[2]Sizzling = $150" << std::endl
                      << "[3]Chicken Curry = $175" << std::endl;
            std::cin >> select;
            } while ( select!= '1' && select != '2' && select !='3' );
            switch ( select ) {
                    case '1': if ( *m_ptr >= 125 ) { *i_ptr = "French Fries"; price = 125; } else std::cout << "You dont have enough money thank you"; break;
                    case '2': if ( *m_ptr >= 150 ) { *i_ptr = "Sizzling"; price = 150; } else std::cout << "You dont have enough money thank you"; break;
                    case '3': if ( *m_ptr >= 175 ) { *i_ptr = "Chicken Curry"; price = 175; } else std::cout << "You dont have enough money thank you"; break;
            }
}
void desserts( char select , std::string *i_ptr , int &price , int* m_ptr ) {
         do {
            std::cout << "[1]Ice Cream = $225" << std::endl
                      << "[2]Fruit Salad = $250" << std::endl
                      << "[3]Bake Mac= $275" << std::endl;
            std::cin >> select;
            } while ( select != '1' && select != '2' && select !='3' );
            switch ( select ) {
                    case '1': if ( *m_ptr >= 125 ) { *i_ptr = "Ice Cream"; price = 225; } else std::cout << "You dont have enough money thank you"; break;
                    case '2': if ( *m_ptr >= 150 ) { *i_ptr = "Fruit Salad"; price = 250; } else std::cout << "You dont have enough money thank you"; break;
                    case '3': if ( *m_ptr >= 175 ) { *i_ptr = "Bake Mac"; price = 275; } else std::cout << "You dont have enough money thank you"; break;
            }

}
void sale( char selection , std::string*i_ptr , int &price ,int* m_ptr) {
         do {
           std::cout << "Are you sure you want to buy " << *i_ptr << "? Y/N " << std::endl;
           std::cin >> selection;
            }while ( selection != 'y' && selection != 'Y' && selection != 'N' && selection != 'n' );
            switch ( selection ) {
        case 'y':
        case 'Y': *m_ptr -= price; break;
        case 'n':
        case 'N': std::cout << "Bye"; break;
            }

}

Jan 2, 2015 at 2:52pm
> am i doing it right?
¿what are you trying to do?


> isnt it good to put char selection to local scope instead of making it variable parameter?
except for `minishop()' the value of the select/selection parameter is irrelevant for the functions.
Jan 2, 2015 at 3:47pm
I would have minishop() return the selection to the caller.
1
2
3
4
5
6
7
8
9
10
11
char miniShop() {
    char select;
    do {
           std::cout << "\t\t\tWELCOME TO MY MINISHOP" << std::endl
                          << "\t\t\t[1]Drinks" << std::endl
                          << "\t\t\t[2]Foods" << std::endl
                          << "\t\t\t[3]Desserts" << std::endl;
           std::cin >> select;
    } while ( select != '1' && select != '2' && select!='3' );
    return select;
}

Obviously with a real program, drinks(), foods() desserts() and sales() would take references instead of the pointer parameters, but I understand that you're doing this as an exercise.

I'll point out that you're making a common mistake of using lots of code when you can use data instead. By using data you make it easier to add/delete menu items. You can even store the menu is a separate file. It also cuts down on errors. For example, you prompt for "French Fries" but return "French fries". Much worse though: desserts() checks for the wrong price:
case '1': if ( *m_ptr >= 125 ) { *i_ptr = "Ice Cream"; price = 225; }
For all of these reasons it's a better idea to use data when the data changes and only use code when the processing changes::
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <iostream>

// Name and price of a menu item
struct Item {
    std::string name;
    int price;
};

void miniShop(char &);
void processFoodCategory(Item[], std::string *, int &, int *);
void sale(char, std::string *, int &, int *);


Item drinks[] = {
    { "Coffee", 15 },
    { "Soft Drinks", 25 },
    { "Alcohol", 65},
    { "", 0}                    // indicates end
};

Item foods[] = {
    { "French Fries", 125 },
    { "Sizzling", 150 },
    { "Chicken Curry", 175},
    { "", 0}                    // indicates end
};

Item desserts[] = {
    { "Ice Cream", 225 },
    { "Fruit Salad", 250 },
    { "Bake Mac", 275},
    { "", 0}                    // indicates end
};


int
main()
{
    char selection = '\0';
    std::string items = " ";
    int money = 500;
    int price = 0;
    miniShop(selection);
    switch (selection) {
    case '1':
        processFoodCategory(drinks, &items, price, &money);
        break;
    case '2':
        processFoodCategory(foods, &items, price, &money);
        break;
    case '3':
        processFoodCategory(desserts, &items, price, &money);
        break;
    }
    sale(selection, &items, price, &money);
    std::cout << "Your money is " << money;
}

void
miniShop(char &select)
{
    do {
        std::cout << "\t\t\tWELCOME TO MY MINISHOP" << std::endl
            << "\t\t\t[1]Drinks" << std::endl
            << "\t\t\t[2]Foods" << std::endl
            << "\t\t\t[3]Desserts" << std::endl;
        std::cin >> select;
    } while (select != '1' && select != '2' && select != '3');
}

// Given an array of items, print a menu of them and prompt for
// a selection.  If there is enough money then set the price and name.
void processFoodCategory(Item items[],
                         std::string * i_ptr,
                         int &price,
                         int *m_ptr)
{
    int select = 0;
    int i;
    do {
        for (i=0; items[i].name.size(); ++i) {
            std::cout << "[" << i+1 << "] "
                      << items[i].name << " = $" << items[i].price << '\n';
        }
        std::cin >> select;
    } while (select < 1 || select > i);

    // decrement select so it can be used as an index.
    --select;

    if (items[select].price <= *m_ptr) {
        price = items[select].price;
        *i_ptr = items[select].name;
    } else {
        std::cout << "You dont have enough money thank you\n";
    }
}

void
sale(char selection, std::string * i_ptr, int &price, int *m_ptr)
{
    do {
        std::
            cout << "Are you sure you want to buy " << *i_ptr << "? Y/N " <<
            std::endl;
        std::cin >> selection;
    } while (selection != 'y' && selection != 'Y' && selection != 'N'
             && selection != 'n');
    switch (selection) {
    case 'y':
    case 'Y':
        *m_ptr -= price;
        break;
    case 'n':
    case 'N':
        std::cout << "Bye";
        break;
    }
}
Jan 3, 2015 at 9:57am
¿what are you trying to do?

how is my use of pointers?
Jan 3, 2015 at 10:12am


void processFoodCategory(Item[], std::string *, int &, int *);
can you explain to me why use reference on 3rd parameter and pointer on 4th parameter?
i know the 2nd parameter uses pointer string because it would be bad if it makes a copy of a string ,using pass by value ,because strings takes much memory than all other data type
Last edited on Jan 3, 2015 at 2:38pm
Jan 4, 2015 at 4:34pm
can you explain to me why use reference on 3rd parameter and pointer on 4th parameter?

I was just mimicking the usage of your drinks(), foods() and desserts() functions. I thought you those functions this way as an exercise in using pointers and references. Otherwise I'd have coded it like this:
void processFoodCategory(Item[], std::string &, int &, int &);
and changed the implementation and calls to match.
Jan 5, 2015 at 4:04am
so coding a parameter like this (Item[], std::string *, int &, int *) is a waste?
Last edited on Jan 5, 2015 at 4:04am
Jan 5, 2015 at 3:34pm
It boils down to when to pass a pointer and when to pass a reference. If the value should never be null then pass a reference.
Jan 5, 2015 at 4:15pm
I see thank you, I really appreciate you help
Topic archived. No new replies allowed.