Should I use global or local declaration on variables ?

I was wondering which is a better option to use global or local declarations when it comes to a lot of functions ? I have here code and let's only focus on lines 18th and 19th. Should I declare them to be global to make "main" a little bit less filled with things or no? My functions use these values in 12,13 and 14th lines. Second question if I declare them global is there any way I can have fewer variables in my void functions ? I believe that there are a little bit too many variables for a single function. (14th line)
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
#include <iostream>
#include <fstream>
#include <cmath>
#include <iomanip>

using namespace std;
//
const char duom[] = "d.txt";
const char rez[] = "r.txt";
const int size = 30;
//
void skaityti(int U[], int &n);
void spausdinti(double klvid, double mvid, double vvid, int v, int m);
void vidurkis(int U[], int &n, double &klvid, double &mvid, double &vvid, int &v, int &m);
//
int main()
{
    int U[size], n, klsum, klmsum, klvsum, v = 0, m = 0;
    double klvid = 0, mvid = 0, vvid = 0;
    skaityti(U, n);
    vidurkis(U, n, klvid, mvid, vvid, v, m);
    spausdinti(klvid, mvid, vvid, v, m);
    return 0;
}
//
void skaityti(int U[], int &n)
{
    ifstream in(duom);
    in >> n;
    for(int i = 0; i != n; i++)
    {
        in >> U[i];
    }
    in.close();
}
//
void vidurkis(int U[], int &n, double &klvid, double &mvid, double &vvid, int &v, int &m)
{
    int klsum = 0, klmsum = 0, klvsum = 0;
    klvid, mvid, vvid, m, v;
    for(int i = 0; i != n; i++)
    {
        klsum += abs(U[i]);
        if(U[i] > 0)
        {
            klmsum += U[i];
            m++;
        }
        else
        {
            v++;
            klvsum += abs(U[i]);
        }
    }
    klvid = (double)klsum / n;
    mvid = (double)klmsum / m;
    vvid = (double)klvsum / v;
}
//
void spausdinti(double klvid, double mvid, double vvid, int v, int m)
{
    ofstream out(rez);
    out << "Klases vidutinis ugis yra: " << fixed << setprecision(1) << klvid << endl;
    out << "Klases merginu vidutinis ugis yra: " << fixed << setprecision(2) << mvid << endl;
    out << "Klases vaikinu vidutinis ugis yra: " << fixed << setprecision(2) << vvid << endl;
    if(v > 7 && vvid >= 175) out << "Vaikinu komanda galima sudaryti" << endl;
    else out << "Vaikinu komandos negalima sudaryti" << endl;
    if(m > 7 && mvid >= 175) out << "Merginu komanda galima sudaryti" << endl;
    else out << "Merginu komandos negalima sudaryti" << endl;
    out.close();
}
Last edited on
By the way, I've seen that people actually write functions immediately before main and not below like I did. Is it more appropriate to write them instead of making the code longer ?
And one more question. You can see 1 of my codes above. This is the same but using global variables and writing above functions. It seems to be way shorter. Is this acceptable way to do so?

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
#include <iostream>
#include <fstream>
#include <cmath>
#include <iomanip>
//
using namespace std;
//
const char duom[] = "d.txt";
const char rez[] = "r.txt";
const int size = 30;
//
int U[size], n, klsum, klmsum, klvsum, v = 0, m = 0;
double klvid = 0, mvid = 0, vvid = 0;
//
void skaityti()
{
    ifstream in(duom);
    in >> n;
    for(int i = 0; i != n; i++)
    {
        in >> U[i];
    }
    in.close();
}
//
void spausdinti()
{
    ofstream out(rez);
    out << "Klases vidutinis ugis yra: " << fixed << setprecision(1) << klvid << endl;
    out << "Klases merginu vidutinis ugis yra: " << fixed << setprecision(2) << mvid << endl;
    out << "Klases vaikinu vidutinis ugis yra: " << fixed << setprecision(2) << vvid << endl;
    if(v > 7 && vvid >= 175) out << "Vaikinu komanda galima sudaryti" << endl;
    else out << "Vaikinu komandos negalima sudaryti" << endl;
    if(m > 7 && mvid >= 175) out << "Merginu komanda galima sudaryti" << endl;
    else out << "Merginu komandos negalima sudaryti" << endl;
    out.close();
}
//
void vidurkis()
{
    int klsum = 0, klmsum = 0, klvsum = 0;
    klvid, mvid, vvid, m, v;
    for(int i = 0; i != n; i++)
    {
        klsum += abs(U[i]);
        if(U[i] > 0)
        {
            klmsum += U[i];
            m++;
        }
        else
        {
            v++;
            klvsum += abs(U[i]);
        }
    }
    klvid = (double)klsum / n;
    mvid = (double)klmsum / m;
    vvid = (double)klvsum / v;
}
//
int main()
{
    skaityti();
    vidurkis();
    spausdinti();
    return 0;
}
Last edited on
Make variables as local as possible.

Sometimes it makes sense to group multiple related variables in a struct (or a class). This way you only have to pass one argument which contains everything that you need, and it often makes the code easier to think about. Now I don't understand what the names in your code mean so I cannot say if this is appropriate for your code but to give an example, if you have a function that takes x and y coordinates as argument.
 
void draw(int x, int y);
You might instead want to change the code so that you pass an object that contains the x and y coordinates.
1
2
3
4
5
6
7
struct Point
{
	int x;
	int y;
};

void draw(Point p);
Now instead of two arguments you just have to pass one.
1
2
3
4
5
int x = 324;
int y = 5465;
Point p{324, 5465};
draw(x, y);
draw(p);
Last edited on
As you said make variables as local as possible. But what if all variables are going to be used for functions. So I make them global right ? What about the other questions I asked. Is it completely okay to start a function above main ? Instead of declaring what values I'm going to use for the function and then do it below. Besides that, it saves me from headache adding each new variable each time I need to the functions. Especially when it comes to printing the answer.
for example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
include <iostream>
//
using namespace std;
//
void print(int a, int b, int c, int d, int e);
//
int main()
{
    int a, b, c, d, e;
    print(a, b, c, d, e);
    return 0;
}
//
void print(int a, int b, int c, int d, int e)
{
    cout << a << b << c << d << e;
}


I'd rather have

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
include <iostream>
//
using namespace std;
//
int a, b, c, d, e;
//
void print()
{
    cout << a << b << c << d << e;
}
//
int main()
{
    print();
    return 0;
}

closed account (z05DSL3A)
The easiest thing to do is Google "why not use global variables" and have a read.
> But what if all variables are going to be used for functions. So I make them global right ?

Depends on how big the program is, how many different components it has.

In a small program, with a couple of hundred lines or so, all in one file, it is fine if they are all globals. A good programmer is, over and above everything else, a pragmatic programmer.


> Is it completely okay to start a function above main ?
> Instead of declaring what values I'm going to use for the function and then do it below.

Yes, again. If the program is small enough.
https://www.learncpp.com/cpp-tutorial/4-2a-why-global-variables-are-evil/

Avoid use of non-const global variables if at all possible! If you do have to use them, use them sensibly and cautiously.

Const global variables (symbolic constants) are fine to use, so long as you use proper naming conventions.

In other cases, favor local variables. Pass those local variables to the functions that need them.


Question: What’s the best naming prefix for a global variable?

Answer: //
globals aside, main at the top or bottom is style. I put main at the bottom and the functions on top of it. Whether I need prototypes or not is governed by the program's size, but I do it that way regardless. Partly because if I want to leave them off for small programs, this works, and partly because its easier to find main by scrolling to the bottom than to weed thru includes and comments and protos up top to get to it (or open a search dialog).

but c++ is very forgiving. You can do whatever is efficient for you.
globals have a bad reputation... for good reasons, but c++ offers multiple ways to do globals more safely. You can namespace them, and you can make them static class members in a global variable class, for 2 ways to have a 'safer' global. Multi-threading global bugs are extremely 'exciting' to fix, for one extreme example of why doing this is a bad habit. As soon as you take something that was working single threaded and kick it up a notch ... and the problems set in... you will be cured of using globals.

Topic archived. No new replies allowed.