Code efficiency and returning multiple values

Hi. I'm coming from Matlab to C++ and my head is twisting about itself.
I want to write a simple program for printing the solution of a quadratic equation, where the quadratic coefficients are given by user input. I'm a student of electronics engineering, so it would be dutiful of me to make my code as efficient as humanly possible. I have written the code, which seems to work wonders. The question is whether it is optimally efficient, and therefore uses less time and energy thus preserving the ice caps. :)

Main point: Returning multiple values using vectors.

My code is separated into three functions. I have omitted the main function and header files. solveQuadratic() is the only function which is called by main().

The first function calculates the determinant.
1
2
3
double determinant(double a, double b, double c) {
    return b*b-4*a*c;
}


This function queries the user to input the coefficients.
1
2
3
4
5
6
7
8
9
10
11
12
13
vector<double> queryCoefficients() {
            // Ask the user to input the quadratic coefficients
            // and return them in a vector.
        vector<double> coeffs(3);
        cout << "Enter coefficient A = ";
        cin >> coeffs[0];
        cout << "Enter coefficient B = ";
        cin >> coeffs[1];
        cout << "Enter coefficient C = ";
        cin >> coeffs[2];

    return coeffs;
}


This function is the meat of the program. The vector<double> is assigned the returned values from queryCoefficients(). From what I understand, having functions return multiple values using a vector is not efficient and invovles making several copies of values. What should I do to make this code more efficient?

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
void solveQuadratic() {
        // Initialize a vector and assign values by passing
        // the function queryCoefficients().
    vector<double> coeffs = queryCoefficients();
        // Initialize a, b and c to point to the coefficients
        // for convenience.
    double *a = &coeffs[0];
    double *b = &coeffs[1];
    double *c = &coeffs[2];
            // PRINT STUFF
            cout << endl << "Quadratic coefficients:" << endl;
            cout << "A = " << *a << "\tat adress " << a << endl;
            cout << "B = " << *b << "\tat adress " << b << endl;
            cout << "C = " << *c << "\tat adress " << c << endl;
        // Calculate the determinant from the coefficients.
    double D = determinant(*a, *b, *c);

    // PRINT MORE STUFF
    if (D < 0) {
        // Complex solution
        double real = -*b/2;
        double imag = sqrt(abs(D))/2;
        cout << endl << "Complex solutions: " << endl;
        cout << "z1 = " << real << " + i" << imag << endl;
        cout << "z2 = " << real << " - i" << imag << endl;
    }
    else if (D == 0) {
        // One real solution
        cout << endl << "One real solution." << endl << "x = " << -*b/2 << endl;
    }

    else {
        // Two real solutions
        double x1 = -*b/2 + sqrt(D)/2;
        double x2 = -*b/2 - sqrt(D)/2;
        cout << endl << "Two real solutions." << endl;
        cout << "x1 = " << x1 << endl;
        cout << "x2 = " << x2 << endl;
    }
}


Is the assignment of the doubles a, b and c as pointers to the memory location of the vector more efficient than writing the code below?

1
2
3
double a = coeffs[0];
double b = coeffs[1];
double c = coeffs[2];


?

Thanks in advance.
Last edited on
no. it just makes your code harder to read and more error prone.
in fact, if you want to to make it more efficient i wouldn't even bother with your queryCoefficients() function at all. (at least not at the moment).

just do:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void solveQuadratic() {
        // Initialize a vector and assign values by passing
        // the function queryCoefficients().
    vector<double> coeffs = queryCoefficients();
        // Initialize a, b and c to point to the coefficients
        // for convenience.
    double a(0.0);
    double b(0.0);
    double c(0.0);

        cout << "Enter coefficient A = ";
        cin >> a;
        cout << "Enter coefficient B = ";
        cin >>b;
        cout << "Enter coefficient C = ";
        cin >> c;


            // PRINT STUFF 


and do away with the pointer nonsense.

vectors are lovely because you can keep adding elements to them, but in your case you will always know you have three things to ask the user, so i wouldnt use a dynamically sizing collection like a vector to store them.
If you did want some kind of queryCoefficients() function you could even write a coefficients class or struct if you really wanted to, that contains 3 doubles to store you coefficients and return this from your function e.g. :

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
#include <iostream>

class Coeffients
{
public:

	Coeffients() : a(0.0), b(0.0), c(0.0) {}

	double a;
	double b;
	double c;


	void DebugPrint()
	{
		std::cout << "Coefficients: " << "(" << a << ", " << b << ", " << c << ")" << std::endl;
	}
};

// pass by reference 
void QueryCoefficients(Coeffients& coefficients) 
{
	std::cout << "Enter coefficient A = ";
	std::cin >> coefficients.a;
	std::cout << "Enter coefficient B = ";
	std::cin >> coefficients.b;
	std::cout << "Enter coefficient C = ";
	std::cin >> coefficients.c;
}

int main()
{
	Coeffients myCoeffs;
	QueryCoefficients(myCoeffs);
	myCoeffs.DebugPrint();

	return 0;
}
Last edited on
Thanks for the reply.

Using structs seems to make more sense, so I will stick to that. The queryCoefficients() function was written to break up the code into small chunks, but also as an attempt to force myself to learn how to pass values from functions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

struct getCoeffs() {
    struct coeffs {
        double a;
        double b;
        double c;
    };
    // Assign values to members of coeffs with user input.
    // cin >> stuff;
    // And so on.
    return coeffs;
};

struct coefficient = getCoeffs();


I'm getting some annoying complaints from the compiler, but not from this piece of code. Anyways, is this how I should go about this?
i've updated my post with an example.
Using structs seems to make more sense, so I will stick to that
Or you can use standard library facilities: as fast and neat, less writing:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
std::tuple<int, int, int> getCoeff()
{
    //read is my helper function I use often. Use any way you like here.
    double a = read<double>(""Enter coefficient A = "");
    double b = read<double>(""Enter coefficient B = "");
    double c = read<double>(""Enter coefficient C = "");
    return std::make_tuple(a, b, c);
}

//usage
auto coeff = getCoeff();
std::cout << std::get<0>(coeff) << "x^2 + " << std::get<1>(coeff) << "x + " << std::get<2>(coeff);
//Unpacking into separate variables:
double a, b, c;
std::tie(a, b, c) = getCoeff();

Topic archived. No new replies allowed.