The operation of the "for" function in this example

Thread Starter

richard3194

Joined Oct 18, 2011
193
Hi. I read that the for function is a loop function. But, in reading up about the types of defined functions, I've come across the use of the for function to determine whether a number is prime or not. Here is the code (from programiz.com):

Code:
#include <stdio.h>

void checkPrimeNumber();

int main()
{
    checkPrimeNumber();    // no argument is passed to prime()
    return 0;
}

// return type of the function is void because no value is returned from the function
void checkPrimeNumber()
{
    int n, i, flag=0;

    printf("Enter a positive integer: ");
    scanf("%d",&n);

    for(i=2; i <= n/2; ++i)
    {
        if(n%i == 0)
        {
            flag = 1;
        }
    }
    if (flag == 1)
        printf("%d is not a prime number.", n);
    else
        printf("%d is a prime number.", n);
}
What I'm not sure about is how the function works in this example - as to a loop action. If I set n to 12 (keyboard-in 12), then "i" initially will have the value of 2 I believe. In that case, "i" will be smaller than 6 (12/2) and the test turns out true. So, "i" is incremented to 3 and the code below the for function runs. When printf() right at the end executes, I believe the program goes back to main() at line 7. Which again calls the function checkPrimeNumber(). Of course, that sets things in motion again and again the program halts until an integer is entered in from the keyboard and Enter is pressed. I see that whatever "i" is, it gets reset to 2 again as the for function again executes.

So, it looks like as it is, the code that is below the for function only executes once after a keyboeard entry. But of course, "I" only got to the value of 3, so I'm wondering (not withstanding what I've just said) what stopped the for function continuing to run the code below it. I see that normally "I" would get to 7, at which point the test would result in false and stop the for function from running the code below it. I hope my thinking makes some sense. :) Thanks. Rich
 
Last edited:

dl324

Joined Mar 30, 2015
18,326
Code is easier to read if you use code tags with some decent style.
Code:
#include <stdio.h>

void checkPrimeNumber();

int main() {
  checkPrimeNumber();           // no argument is passed to prime()
  return 0;
}

// return type of the function is void because no value is returned from 12
function void checkPrimeNumber() {
  int n, i, flag = 0;

  printf("Enter a positive integer: ");
  scanf("%d", &n);

  for (i = 2; i <= n / 2; ++i) {
    if (n % i == 0) flag = 1;
  }
  if (flag == 1)
    printf("%d is not a prime number.", n);
  else
    printf("%d is a prime number.", n);
}
If I set n to 12 (keyboard-in 12), then "i" initially will have the value of 2 I believe. In that case, "i" will be smaller than 6 (12/2) and the test turns out true. So, "i" is incremented to 3 and the code below the for function runs.
The increment happens after the first iteration through the for loop; not before. i will be 2 for the first iteration.
When printf() right at the end executes, I believe the program goes back to main() at line 7. Which again calls the function checkPrimeNumber(). Of course, that sets things in motion again and again the program halts until an integer is entered in from the keyboard and Enter is pressed. I see that whatever "i" is, it gets reset to 2 again as the for function again executes.
The function is only executed once. Since the function doesn't return a value, when it completes, it goes to the return command in main.
 

Thread Starter

richard3194

Joined Oct 18, 2011
193
It's still unclear to me. This is the way I'm looking at it: There are two loops, one created by the programmer in the code he/she has written, the other is associated with the built-in function named "for" which is hidden.

Although we cannot see the code, there is code assocated with the for function. That code is set to execute at line 17. In normal operation of that code it runs untill a false condition is met. But, that false condition does not arise, because "I" never gets to 7 when n is 12. I'm seeing the code associated with the for function as independent of the programmers code and having difficulty seeing what stops it. Despite seeing that after the first iteration the program goes back to main(). I'm imagining the code associated with the for function running somehow in the background simply because "i" has not reached a value of 7 and that it (the code) is sort of independent. But, if that was the case, we might get multiple print outs on screen. Which does not happen. We only get one printing at the screen.

EDIT: Am I missing some code which under normal operation makes the for function loop? Which is missing in this example, because this is not a normal use of the for function? Do I have a misunderstanding of how the for function works in terms of loops?
 
Last edited:

butlmd

Joined Oct 17, 2018
2
Perhaps you're overthinking this a bit. In C, for is a keyword, not a function. The loop body in this example is between the two curly braces and consists of the if (n % i == 0) flag = 1; statement. The body is executed while the exit condition (i < n/2) is true. After the for loop completes, the rest of the code with the prints executes.

Now, to be pedantic, the for keyword does contribute code to the program; you can see it if you run objdump on your executable and look at the assembler output.

Hope that helps -
Mark
 

dl324

Joined Mar 30, 2015
18,326
It's still unclear to me. This is the way I'm looking at it: There are two loops, one created by the programmer in the code he/she has written, the other is associated with the built-in function named "for" which is hidden.
Unless you're running on a microcontroller that doesn't have an OS and inserts code to loop on main(), there is only one loop; the for().
Although we cannot see the code, there is code assocated with the for function. That code is set to execute at line 17. In normal operation of that code it runs untill a false condition is met. But, that false condition does not arise, because "I" never gets to 7 when n is 12. I'm seeing the code associated with the for function as independent of the programmers code and having difficulty seeing what stops it.
In the first iteration of the for loop, i=2. On the second i=3, and so on until i is incremented to 7 and the for loop stops.
Despite seeing that after the first iteration the program goes back to main().
The checkPrimeNumber function doesn't return to main() until the it exits the for loop and prints a message to stdout.
Do I have a misunderstanding of how the for function works in terms of loops?
Apparently.
 

Thread Starter

richard3194

Joined Oct 18, 2011
193
Ah. I must not forget that the user defined function is checkPrimeNumber(). I think I was beggining to see for() as a function. I would because I want to see anything with () after it as a function.
 

Thread Starter

richard3194

Joined Oct 18, 2011
193
I understand how the for loop works in principle. Nothing I've said indicates otherwise. As I see it "i" never gets beyond 3 when 12 is entered at the keyboard. If I'm wrong about that, I don't think it shows I don't undertand the for loop in principle. Some detail I'm not getting. I'll read up. It might be that "..the body of the loop is executed", rather than just block of code is executed as I'm thinking. It's not just any block of code. Whatever, I'll figure it out. Rich
 
Last edited:

Thread Starter

richard3194

Joined Oct 18, 2011
193
Perhaps you're overthinking this a bit. In C, for is a keyword, not a function. The loop body in this example is between the two curly braces and consists of the if (n % i == 0) flag = 1; statement. The body is executed while the exit condition (i < n/2) is true. After the for loop completes, the rest of the code with the prints executes.

Now, to be pedantic, the for keyword does contribute code to the program; you can see it if you run objdump on your executable and look at the assembler output.

Hope that helps -
Mark
Aaah. I'm including too much code as the body of the loop. That's my error. It starts at line 19 and ends at 25. :) Thanks. Rich I get it now. "i" will reach 7 and that stops the iteration and then the program moves on to line 26. (Referring to my initial since edited post).

So glad for this forum. :)
 
Last edited:

Thread Starter

richard3194

Joined Oct 18, 2011
193
Hi. I have some more questions, but not about the for loop. As to line numbering, I'm referring to my initial post (which I've edited to improve the style).

As to why I see two loops: The function call is made at line 7, so the code jumps to line 12. The code stops at line 17 waiting for keyboard input. At line 30, there is a return to main() at line 7, which executes the function call again. I'm seeing that as a loop. Not sure if technically it is.

But, if I have it correct about the lines that are executed, how would line 8 ever be executed? Remember, I'm practically a complete newbie, so my questions will be basic. :)
 
Last edited:

AlbertHall

Joined Jun 4, 2014
12,625
At line 30, there is a return to main() at line 7, which executes the function call again. I'm seeing that as a loop. Not sure if technically it is.
When a function returns, it returns to the line after the line which called it - in this case the return is to line 8. Line 8 returns the value '0' to whatever called the 'main' function and ends this program.
 

Thread Starter

richard3194

Joined Oct 18, 2011
193
OK, let me just cycle thru this, to see if I get it.

If this simple program is in a hosted environment, then an operating system, on some event, will invoke main().

Program prints on a screen the prompt "Enter a positive integer". scanf) causes the program to halt and program restarts when a number is entered at keyboard and Enter key is pressed. Then if 12 was entered, the screen prints "12 is not a prime number". After that line 8 in executed and control is passed back to the operating system main() having completed successfully.

If the above is correct, the event that invoked main(), must again happen in order to enter another number at the keyboard. Is that correct? I think it is and it shows that these examples I'm finding on the internet are not neccesarily to be taken as practical programs. Which is a learning event for me.
 
Last edited:

John P

Joined Oct 14, 2008
2,060
You could also write it without a flag:

Code:
// return type of the function is void because no value is returned from the function
void checkPrimeNumber()
{
    int n, i;

    printf("Enter a positive integer: ");
    scanf("%d",&n);

    for(i=2; (i <= n/2) && (n%i); ++i)
      ;
    if (i > n/2)
        printf("%d is a prime number.", n);
    else
        printf("%d is not a prime number.", n);
}
Actually it would run faster if you used this test
if (i*i < n)

Think of n = 23. With the original version, you won't drop out of the loop until i = 12. But if you use the i*i method, you'd drop out at 5. For large numbers, that's a big saving of time.

Oh, and why test even numbers at all? If you keep looping past the number 2, you know it can't be a divisor.
 
Last edited:

Thread Starter

richard3194

Joined Oct 18, 2011
193
Can I ask: Would the program above, impractical is it is, run on a PC? I'm assuming that if the associated executable file was on HDD, then simply opening the file would be the event that would invoke main(), and of course, it self terminates. I know the source code, as is, would not allow one to use the program on an MCU. Thanks. Rich
 

WBahn

Joined Mar 31, 2012
32,823
Can I ask: Would the program above, impractical is it is, run on a PC? I'm assuming that if the associated executable file was on HDD, then simply opening the file would be the event that would invoke main(), and of course, it self terminates. I know the source code, as is, would not allow one to use the program on an MCU. Thanks. Rich
Depends on what you mean by "opening" the file.

The usual terminology is to "run" the program or "launch" the program. There are a number of ways to do this. Typing the name of the program at a command prompt will launch it as will double-clicking the file name in a File Explorer window (I'm assuming you are using Windows -- it's similar but not exactly the same in Linux). This is because either of those actions tells the operating system to do the "normal" thing with a .exe file and the normal thing is to execute them. Usually the term "open" a file means to bring it into some kind of editing application so that you can view and possibly modify it.
 

Thread Starter

richard3194

Joined Oct 18, 2011
193
I was wanting to cut and paste the code into a compiler for Windows 7, but Windows 7 SDK is a big program. Is there any compiler that is compact which will take the source code of the program above, and produce an .exe file that I can run on Windows? Thanks.

EDIT:: I wonder if for these small programs I could be using something like this:

https://digitalmars.com/features.html

EDIT: Oh, I have to buy that. :)
 
Last edited:

WBahn

Joined Mar 31, 2012
32,823
I was wanting to cut and paste the code into a compiler for Windows 7, but Windows 7 SDK is a big program. Is there any compiler that is compact which will take the source code of the program above, and produce an .exe file that I can run on Windows? Thanks.

EDIT:: I wonder if for these small programs I could be using something like this:

https://digitalmars.com/features.html

EDIT: Oh, I have to buy that. :)
I like Dev-C++ compiler. It's pretty lightweight and it does single-file compiles without requiring a project be created, which is REALLY nice for quick playing around. That's not to say that it doesn't have its frustrating aspects, but overall I like it.
 

dl324

Joined Mar 30, 2015
18,326
I was wanting to cut and paste the code into a compiler for Windows 7, but Windows 7 SDK is a big program. Is there any compiler that is compact which will take the source code of the program above, and produce an .exe file that I can run on Windows?
Do you want the program to run under Windows, or are you just interested in learning how to program using a Windows computer?

If it's the latter, I'd suggest upgrading to Win10 and installing Ubuntu (or Debian) from the App Store. Then install build-essentials which will give you a C/C++ compiler with a Linux interface.

The last time I checked, Win10 upgrades were still free.

I just installed build-essentials and compiled a simple program. It ran under "Ubuntu", but, unfortunately, it won't run under "Windows".

I do all of my programming on a wimpy 1GHz single core ARM processor running Debian.
 

WBahn

Joined Mar 31, 2012
32,823
I few comments on your program:

I would not force checkPrimeNumber() to be burdened with asking the user for a number or printing out some result. Is that how you would like other functions such as log() to work?

Instead, define your function to perform one simple task, namely check if a number is prime and return a boolean value in response. Then name the function something meaningful in that context.

I'm a big non-fan of scanf(), but I'll ignore that here.

You will get massively faster performance if you only check odd positive integers up through the square root of the number you are checking.

You should also be sure that your function behaves reasonable for all possible values that could be passed to it, including negative numbers. Consider how your current program behaves if someone enters 0 or -10.

There are some other things that you could do to speed it up, too.

Code:
#include <stdio.h>

int isPrime(int n);

int main()
{
   int n;

   printf("Enter a positive integer: ");
   scanf("%d",&n);

   if (isPrime(n))
      printf("%d is a prime number.", n);
   else
      printf("%d is not a prime number.", n);

   return 0;
}

int isPrime(int n)
{
   int i;

   if ( n < 2 ) // primes must be greater than 1
      return 0;

   if ( 2 == n ) // 2 is prime
      return 1;

   if ( 0 == n%2 ) // all other evens are nonprime
      return 0;

   for (i = 3; i*i <= n; i += 2 ) // check odd integers through sqrt(n)
      if (0 = n % i)
         return 0;

   return 1;
}
 
Top