Bruno Dumbra Bruno Dumbra - 3 years ago 114
C Question

Can't understand the logic on decrease/increace 'for' in C

enter image description here

I coded this and when I run on win10 (Code Blocks) the numnbers don't get organized by crescent order, but when I run it on my linux (ubuntu 14 - Code Blocks) its organized. Could someone tell me why? (the code is very simple and not much elaborated.

#include "stdio.h"
#include "stdlib.h"

int main(int argc, char *argv[])
{

int i=0, j, num[2], aux;

for (i =0; i<3; i++)
{
printf (" Enter a value for num %d ", i+1);
scanf ("%d", &num[i]);
}

for (i =0; i<3; i++)

{
for (j=0; j<3; j++){
if (num[j] > num[j+1])
{
aux = num[j];
num[j] = num[j+1];
num[j+1] = aux;

}
}
}
for (i=1; i<4; i++)
{
printf("%d", num[i]);
printf("\n");
}


system("PAUSE");
return 0;
}

Answer Source

Your logic doesn't work, neither in Linux nor in Windows. Getting a correct result is a matter of a pure luck, as you're accessing memory past the end of the declared array (the first pair of loops uses index 2 and the last loop iterates up to index 4 while your int num[2] array has only two elements, num[0] and num[1]). This triggers a so called Undefined Behavior, which may result in anything, from returning correct results, through crashing the program, up to destroying it.

Edit

To add some insight, consider you local variables: i, j, num[] and aux. Such variables are usually located on a stack, often in the order of declarations (or exactly reversed). Simple variables, like i or aux may be allocated in some CPU registers, but that depends on the level of optimizations, made by a compiler.

So the variables' layout may look like this:

--------------------------------------------------------------
      |         |         |        |        |         | 
  ... |    i    |    j    | num[0] | num[1] |   aux   |  ...
      |         |         |        |        |         | 
--------------------------------------------------------------

That implies, when you reach an item of the num[] array with index one past the array's length, you most probably actually access the aux variable.

So as soon as you input the third value, you actually store it in aux, which will get overwritten immediately after with the first execution of

aux = num[j];

Yet another error hides between the inner for loop and the if condition in it. Can you spot it...?

Look:

      for (j=0; j<3; j++){
        if (num[j] > num[j+1])
           ....

See? Even if the num[] array was 3 items long, this will run into UB, because at the last iteration you have j==2 so index [j+1] would be out of bounds.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download