1

I have started to use C++ programming language as a complete beginner. With the aim of becoming a better programmer for my STEM degree and with the goal of competitive programming in mind. I have started Functions and Loops in C++ recently and there was a problem I was not sure how to approach.

The probelem: "Write a function to check whether a number is prime"

My Approach:

-> I wanted to implement it on my own so I didn't want to copy paste code online where others have used functions with return type bool.

-> Here is the final version of my code that works:

void prime(int k){
    for(int k1=2;k1<k;k++){
        if(k%k1==0){
            cout<<"int is not prime"<<endl;
            break;
        }
        else{
            cout<<"int is prime"<<endl;
            break;
        }

    }
}

->I would then call this in int Main() and get the user to input integers and so on.

-> The above code was due to many trial-and-errors on my part and my thought process was as follows: 1)if i don't include the "break;" statement my code results in an infinite loop 2)I needed a way to stop my code from going toward an infinite loop 3) I remember a topic covered in the functions segment of this website , where we can use it to terminate a loop at will. Thats why i incorporated it into my code to produce the final version

My Question:

  1. Can someone explain how the break; statement is working in the context of my code? I know it produces my desired effect but I still haven't gotten an intuition as to how this would do my work.

  2. Many online resources just cite the break statement as something that does so and so and then gives examples. Without going through the code mechanics. Like how a loop would be going through its conditions and then when it encounters the break; statement what does it do? and as a consequence of that what does it do to help my code?

Any advice would be helpful. I still couldn't wrap my head around this the first time I encountered it.

F.N.
  • 13
  • 5
  • 3
    Does this really work? Have you passed a non-even non-prime to this function, like e.g. 9? (`9 % 2 = 1`, so your function would consider 9 a prime) In this case I'd expect a loop doing some checks and an `if` statement after the end of the loop... – fabian Jun 19 '21 at 06:35
  • This is a great time to grab a debugger and go through the code line by line with it. That will show exactly how the code behaves, what the `break` does etc. – Sami Kuhmonen Jun 19 '21 at 06:46
  • @fabian i did test it, the problem I was solving had some examples and i checked. Mine worked for those like 43,59,113,...these are all prime no?. Although I will test it now seeing your comment. I will print off all primes between 1 and 200 using this function and match it with published results then – F.N. Jun 19 '21 at 07:52
  • @fabian oh thank you for pointing this. I checked just now, it doesn't hold. Any advice as to how i can fine tune this further? It seems my function fails at odd integers. How can i improve my code? – F.N. Jun 19 '21 at 08:05
  • @fabian i think i know what happened, my function stops the loop right after k1=2 when k=9, because then 9%2=1!=0 and the else statement gets executed. Its like my loop does not check the other subsequent values. even though there are a lot of values k1 can take afterwards. Any advice as to how to remedy this? – F.N. Jun 19 '21 at 08:36
  • Since you've got a `break;` statement on every execution path in the loop body, the loop at most does one iteration. If you found a divisor, you can stop checking, if not you need to continue with the loop. You need some way of storing the result so that it's accessible after the loop which could be done with a bool variable; alternatively you could declare the loop variable outside of the loop and check, if the first divisor is equal to `k`; Don't forget to consider the special cases of 1 (not a prime). – fabian Jun 19 '21 at 09:57
  • @fabian oh so that's why many of the online implementations I saw used a bool type. Alright I will get to it right away. – F.N. Jun 19 '21 at 10:22
  • `k++` is moving the goal post, you probably wanted to increment the indexer `k1`. – Eljay Jun 19 '21 at 11:46
  • @Eljay can you please modify my code with what you have said? Intuitively I understand, but due to my limited experience I still cant use it yet. – F.N. Jun 19 '21 at 14:29
  • @fabian how about this ~~~ void prime(int k){ for(int k1=2;k1 – F.N. Jun 22 '21 at 14:35
  • @F.N. try `bool maybePrime = (k >= 2); for (int i = 2; maybePrime && i != k; ++i) { if (divisor found) maybePrime = false; } cout << (maybePrime ? "..." : "...");` You could of course add a break to the body of the first `if`, but without a break you just get the same effect with imho better code: there's no logic in the loop body after the `if` and the next time the loop condition is checked, it's false exiting the loop similar to the way `break;` would. – fabian Jun 22 '21 at 16:11
  • @fabian ohh i see. Thank you for your patience, it helped a lot. – F.N. Jun 25 '21 at 06:43

2 Answers2

2

In your case if k % k1 does not show that the k1 being a factor of the k, the loop is broken after the print statement. If the k % k1 does show that the k1 being a factor of the k, it also breaks out of the loop.

So, either of the break statements leads to the loop termination on the first iteration here. If you test for whether a number is being a prime, it does not work.

In essence, you don't need either of the break statements here. They are mostly forced here. Take a look at the following approach:

#include <iostream>
#include <cmath>

bool prime(unsigned k){
    if (k != 2) { // Direct check, so to remain similar to the OP's structure of the code 
        unsigned up_to = sqrt(k) + 1; // Calculate the limit up to which to check
        for (unsigned i = 2; i < up_to; ++i) {
            if (k % i == 0) {
                std::cout << "Is not prime" << std::endl;
                return false;
            }
            else std::cout << "Checking..." << std::endl;
        }
    }
    std::cout << "Is prime" << std::endl;
    return true;
}
// Note, we can check just up to the square root of a k

A note on the behavior of the break

The fact that it breaks out the the closest loop to it - has crucial nature for nested loops (all of them: for, while, and do while):

while (/* condition 1 */) // Outer loop
    while (/* condition 2 */) // Inner loop
        if (/* condition 3 */) break;

Here if the condition 3 is satisfied, the break will lead to break out of the Inner loop but the Outer loop will still continue to iterate.

For more, you may be interested in "How to exit nested loops?" thread. It addresses your second question.

rawrex
  • 4,044
  • 2
  • 8
  • 24
  • so is it something like this: the loop goes through k1 and does k%k1, in the event that k%1==0, it prints "not prime" and then the loop is terminated right?. then it just goes to the next block in int main() right? similarly, when the if condition doesnt hold, the else statement gets run, and after printing the loop termiinates right? – F.N. Jun 19 '21 at 06:36
  • @F.N. the loop will be essentially terminated as soon, as either clause of the `if` is evaluated. Means at the very first iteration. – rawrex Jun 19 '21 at 06:38
  • 1
    @rawrex, Your new function still says that the number 2 is not a prime number, which is wrong. The mathematical world states that 2 is a prime number. Here is the wiki info: https://en.wikipedia.org/wiki/List_of_prime_numbers You can also google for more answers about the fact that 2 is a prime number. – Job_September_2020 Jun 19 '21 at 06:49
  • @Job_September_2020 thanks! Will correct it shortly. Got too excited for the `break` part. – rawrex Jun 19 '21 at 06:52
  • @rawrex, You are welcome. I am glad you find my comment and link useful. :-) – Job_September_2020 Jun 19 '21 at 06:55
  • @rawrex 2 is the only even number which is prime, so in my opinion, it requires a special case inside the `prime` function – DeBARtha Jun 19 '21 at 07:06
  • 1
    @DebarthaPaul yeah, makes sense! We also could skip out all the even values of `i` in the loop. which will also aid a lot. But the question was about the `break`, so none of the optimizations matter much in this thread. – rawrex Jun 19 '21 at 07:09
  • @F.N. do you have any questions, comments? – rawrex Jun 19 '21 at 07:11
  • @rawrex okay okay that clears up a lot for me. Thank you. Oh right now I dont have questions, if I do I will comment here regarding this. Thank you. – F.N. Jun 19 '21 at 07:56
  • @rawrex oh yea there were many additions to this. I just wanted to stick to break because I was starting out recently and came across break first.. and I am not that confident to use a new approach yet. – F.N. Jun 19 '21 at 07:58
  • @F.N. got you! Also please don't forget to mark an answer as accepted if you consider one as such. – rawrex Jun 19 '21 at 08:05
  • @rawrex yea sure, I was just finishing up my code with some input from earlier comments, once its all done i will make sure to do so! – F.N. Jun 19 '21 at 08:07
0

Analogy... I found it in the last place I looked... like always!

Looking for your keys is the LOOP you are in... when you find them... you BREAK out and move on to another task... like maybe getting into your car...

SO if you are IN your car and know your car is where you left your keys... then you are in the PROCESS of getting prepared to drive away... BUT that process requires keys... THUS you change modes/focus and begin a cyclic process of looking for keys... when found to BREAK that searching process IMMEDIATLY and resume what your were doing.

MANY people would make use of the RETURN instrucion in your code pattern... in place of the break! Both do the same thing... however the RETURN is more descriptive english... and one should be concerned with the programmer behind him... Also a bit of digging might show how one is more efficient than the other...

Bob Logan
  • 36
  • 2
  • 1
    NOTE: Watch the use of return when in nested loops... For return will break you out of ALL loops in that function. SO one might want to break a middle loop and return from the innermost... etc. – Bob Logan Jun 19 '21 at 06:45
  • I see. I had not thought of return statement. Nice analogy though. Thank you. Although i am still starting out, it shouldnt be long from now when I can use these freely in my code. – F.N. Jun 19 '21 at 07:54