pointers practice

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;
            }

}

> 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.
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;
    }
}
¿what are you trying to do?

how is my use of pointers?


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
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.
so coding a parameter like this (Item[], std::string *, int &, int *) is a waste?
Last edited on
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.
I see thank you, I really appreciate you help
Topic archived. No new replies allowed.