LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Nested for loops and arrays in C (https://www.linuxquestions.org/questions/programming-9/nested-for-loops-and-arrays-in-c-721445/)

iongrey 04-24-2009 12:50 PM

Nested for loops and arrays in C
 
Good Day All,

I have three loops. One loop has values saved at indexes 65-90. The second loop has values stored at indexes 97-122. I tried using nested for loops to add the values at the indexes and save them in a third array with a range of 26, but when I print the third array, the value are all zeroes. For example array1 [65] = 2 + array2 [97] = 1 = array3 [0] = 3

Here is my code:

Code:


for (q=65; q<91; ++q){
    for (r=97; r<123; ++r){
        for (s=0; s<26; ++s){
            array3[s] = array1[q] + array2[r];
            }

    }
}
for (m=0; m<26; ++m){
    printf("%d total %d\n",m,array3[m]);

}

The arrays are all int.

I'd appreciate any insight.

Thank You

paulsm4 04-24-2009 01:14 PM

Hi -

For example
Code:

array3[s] = array1[q] + array2[r];
Is it possible that array1[65] is "0", array2[97] is also "0", and the result in array3[0] will be ... you guessed it?

Why not put a breakpoint in the debugger and examine array1 and array2 when you do the addition?

Just a thought .. PSM

PS:
While you're in the debugger, it wouldn't hurt to verify that q is "65" and r is "97", like you expect them to be...

PPS:
And don't forget that "65" is the *66th* element in array1, or that "97" is actually the *98th* element in array2...

dmail 04-24-2009 01:20 PM

Code:

for (q=65; q<91; ++q){
    for (r=97; r<123; ++r){
        for (s=0; s<26; ++s){
            array3[s] = array1[q] + array2[r];
            }

    }
}

Also I would say that code does not do what you intended to do.
How many times is array3 written to? hint it is not 26 and each previous value is overwritten.

iongrey 04-24-2009 01:45 PM

Hello,

Thanks for the advice so far.

I thought it was being written to 26 times, but apparently not. In my stupid reasoning I thought the code would have the s start at index 0, q at 65 and r at 97 then just add the values until indexes s=25, r=122 and q=90.

Now..., I'm lost and confused all over again :).

GazL 04-24-2009 01:51 PM

Quote:

Originally Posted by paulsm4 (Post 3519797)
Hi -

For example
Code:

array3[s] = array1[q] + array2[r];
Is it possible that array1[65] is "0", array2[97] is also "0", and the result in array3[0] will be ... you guessed it?

Actually, it's only the last iteration of the inner most loop that will matter so q=90, r=122 are the only values that matter.

The code is effectively the same as if it were written as:
Code:

for (s=0 ; s<26 ; ++s)
{
  array3[s] = array1[ 90 ] + array2[ 122 ] ;
}


If I've understood properly the intent was probably to do:

Code:

for (s=0 ; s<26 ; ++s)
{
  array3[s] = array1[ s + 65 ] + array2[ s + 97 ] ;
}

... though I'm a little curious about why it's using non overlapping index ranges. It's almost as if the code is intended to manipulate a single array rather than 3 different arrays.

iongrey 04-24-2009 02:21 PM

GazL, Thank You!!!

Code:

for (s=0 ; s<26 ; ++s)
{
  array3[s] = array1[ s + 65 ] + array2[ s + 97 ] ;
}

That is exactly what I intended to do.

I'm just a C newbie playing with the language.

Thanks again. You helped me out immensely.

GazL 04-24-2009 02:44 PM

Happy to help. I'm still learning myself.

I wasn't sure if you really meant to have 3 different arrays though or if you really meant to do something like
Code:

for (s=0 ; s<26 ; ++s)
{
  array[s] = array[ s + 65 ] + array[ s + 97 ] ;
}

but without seeing the rest of the program I can't tell. Anyway, have fun with your coding.

jiml8 04-24-2009 03:12 PM

To recap what you did wrong, when you nest for loops, the innermost loop is executed in its entirety, then the next outer loop is iterated once, then the innermost loop is executed in its entirety again.

This logic flows out until all loops have been executed in their entirety, with the outermost loop being executed entirely once, the next loop in being executed entirely as many times as necessary for the outer loop to execute once, the next inner loop executed entirely as many times as the product of the number of executions of the two outer loops and so forth.

johnsfine 04-24-2009 03:27 PM

Quote:

Originally Posted by iongrey (Post 3519864)
Code:

for (s=0 ; s<26 ; ++s)
{
  array3[s] = array1[ s + 65 ] + array2[ s + 97 ] ;
}

That is exactly what I intended to do.

That is a good (maybe best) way to put into array3 what you wanted to put into array3.

But clearly what you "intended" to do was run one loop (not nested) with three index variables.

That is also possible in C. I think you ought to learn that syntax.

You wrote nested loops:
Code:

for (q=65; q<91; ++q){
    for (r=97; r<123; ++r){
        for (s=0; s<26; ++s){
            array3[s] = array1[q] + array2[r];
            }

    }
}

One loop with multiple indexes would be
Code:

for (q=65, r=97, s=0; s<26; ++q, ++r, ++s){
    array3[s] = array1[q] + array2[r];
}

What GazL wrote might be considered even better, but I thought you should see the right syntax for the code you apparently were trying to write.

GazL 04-24-2009 03:56 PM

Quote:

Originally Posted by johnsfine (Post 3519927)
What GazL wrote might be considered even better, but I thought you should see the right syntax for the code you apparently were trying to write.

I'm not sure what I suggested is any better. I'm just used to thinking in languages that don't have fancy stuff like multi-index loops, so I tend to forget to use features like that.

Which is more efficient, 3 increment operations, or one increment and 2 integer additions? Yours certainly looks more elegant and I suspect it might be more efficient too.

johnsfine 04-24-2009 05:25 PM

Quote:

Originally Posted by GazL (Post 3519954)
Which is more efficient, 3 increment operations, or one increment and 2 integer additions? Yours certainly looks more elegant and I suspect it might be more efficient too.

I tend to rely on the optimizer to sort out simple stuff like that, such that there would be no difference in efficiency after optimization.

Sometimes there are surprises: Sometimes the optimizer fails to see something incredibly obvious, so the performance would be different. Sometimes the execution time of very bad looking asm code turns out to be quite good, so even looking at the generated asm code might not tell you which is better.

If you really care about performance (which I assume is not the case in this example), you need to use a profiler and find out the real performance.

If the optimizer doesn't sort it so well that the results are identical, I think it would handle your version better. Those two ADDs are quite a bit cheaper at run time than you'd expect, very likely cheaper than the two extra increments. If the ADDs (for complex) reasons turn out not to be super cheap, the optimizer can easily pull them out of loop in x86 32bit. In x86-64, either having the ADDs cheap in the loop or having the optimizer pull the ADDs out of the loop could happen if you had used 65L and 97L, but not with int constants.

I focus much more than most programmers on writing C++ code in ways that will generate fast running asm code, but in an example like this even I wouldn't worry about that.

The decision between these two versions of that code should be made on which best conveys the underlying meaning (to avoid bugs in case some revision is required) not on which compiles to better asm code.


All times are GMT -5. The time now is 01:56 AM.