Search code examples
c++goto

Is using goto a legitimate way to break out of two loops?


I am solving problem 9 on the Project Euler. In my solution I use a "goto" statement to break out of two for loops. The Problem is the following:

A Pythagorean triplet is a set of three natural numbers, a b c, for which,

a^2 + b^2 = c^2

For example, 3^2 + 4^2 = 9 + 16 = 25 = 52.

There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product abc.

My solution is in c++:

int a,b,c;
const int sum = 1000;
int result = -1;
for (a = 1; a<sum; a++){
    for (b = 1; b < sum; b++){
            c = sum-a-b;
            if (a*a+b*b == c*c){
                result = a*b*c;
                goto found;
            }
    }   
}
found:
std::cout << "a:" << a << std::endl;
std::cout << "b:" << b << std::endl;
std::cout << "c:" << c << std::endl;
std::cout <<"Result:" << result << std::endl;

Since "goto" statements are not very popular among c++ programmers, i would like to know, if this could be considered a reasonable use of "goto". Or if there is a better solution for the problem that doesn't need "goto". By that I don't mean a solution which just avoids "goto", but which avoids "goto" in a way that improves the algorithm.


Solution

  • return is a "structured" goto which many programmers find more acceptable! So:

    static int findit(int sum, int* pa, int* pb, int* pc)
    {
        for (int a = 1; a<sum; a++) {
            for (int b = 1; b < sum; b++) {
                int c = sum-a-b;
                if (a*a+b*b == c*c) {
                    *pa = a; *pb = b; *pc = c;
                    return a*b*c;
            }
        }
        return -1;    
    }
    
    int main() {
        int a, b, c;
        const int sum = 1000;
        int result = findit(sum, &a, &b, &c);
        if (result == -1) {
            std::cout << "No result!" << std::endl;
            return 1;
        }
        std::cout << "a:" << a << std::endl;
        std::cout << "b:" << b << std::endl;
        std::cout << "c:" << c << std::endl;
        std::cout <<"Result:" << result << std::endl;
        return 0;
    }