I'm currently working my way through understanding the code of copy.c used in "whodunit" and "resize".

This loop is supposed to iterate over the scanlines of a Bitmap (by incrementing i) and within that, iterate over each pixel of the scanlines (by incrementing j).

I don't understand where the incremented values of i and j are connected to what scanline/pixel is being handled, as they are not used again int the body of the loop.

How does the program move from one line/pixel to the next?

Any Help is greatly appreciated!

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    // iterate over pixels in scanline
    for (int j = 0; j < bi.biWidth; j++)
        // temporary storage
        RGBTRIPLE triple;

        // read RGB triple from infile
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

        // write RGB triple to outfile
        fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);

    // skip over padding, if any
    fseek(inptr, padding, SEEK_CUR);

    // then add it back (to demonstrate how)
    for (int k = 0; k < padding; k++)
        fputc(0x00, outptr);

2 Answers 2


Both the i and j counters are used to count passes through the loops. They aren't actually used inside the loops, but they don't need to be.

Let's start with the inner loop. biWidth is the number of pixels in a line. j counts from 0 to biWidth, counting by 1 with each pass through the loop. Inside the loop, one pixel is processed in each pass. So, j is indirectly counting/controlling the number of pixels processed.

After the line of pixels is processed by the loop, the padding is skipped by a separate fseek and the output padding is added by the next inner loop in much the same way.

Now, the outer loop. It works the same way. The outer loop processes one complete line on each pass. On each loop, the inner for loops do the heavy lifting of processing the pixels until the current line is processed and then, on the next pass, start over again at the beginning of the next line.

Once again, the outer loop index, i, counts the number of lines processed without actually being used inside of the loop.

THere's no requirement that a for loop's index has to be used inside the loop itself. It can simply be used to count the number of passes through the loop, as is done extensively here.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

  • Your answer somewhat helped me understand this, though I guess I didn't express myself that well.
    – Sigmund
    Commented May 20, 2018 at 8:55
  • Along with Cliff B’s answer I found this thread to be helpful: cs50.stackexchange.com/questions/2332/…
    – Sigmund
    Commented May 20, 2018 at 10:49

I believe that the it all comes down to the ampersand, which is a pointer and gives you the address of the variable 'triple'. Here, the variable 'triple' takes up 3 bytes and the computer should remember the place of the last byte of this 3 bytes in its memory. It's as if the computer is using 'fseek(memory, 0, SEEK_CUR)' every time the for loop of j runs to get to the location of the last byte of 'triple'. That way, the next iteration of the j for loop will have the computer read starting from the first byte of the next 3 bytes or 'triple'.

From Reddit: "Also, remember when using fread, it reads what you ask it to AND moves the cursor to the end of what it read. That's why you don't have to actually use the values of I and j the way I think you are wanting to."

That's how I made sense of it, feel free to correct me.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .