Another way to look at this problem altogether would be to change the data structure, so instead of using a classical 2d array the problem becomes trivial if you use a spiral array. Filling the edge in this case is just a matter of filling the first 4*(n-1) cells. Obviously this solution's acceptability depends entirely on what you're gonna do with your data afterwards.
for (i = 0; i < GRID_SIZE - 1; ++i) { // Note the "-1"...
// Top Edge
grid[0][i] = 0;
// Bottom Edge
grid[GRID_SIZE - 1][GRID_SIZE - i - 1] = 0; // Reverse the order: from left to right
// Left Edge
grid[GRID_SIZE - i - 1][0] = 0; // Reverse the order: from bottom to top
// Right Edge
grid[i][GRID_SIZE - 1] = 0;
}
This way, for every row/column, the loop acts on all but the last cell, which is actually the first cell of some other column/row.And furthermore why split in two? Why not split the range into three sections, or four, or N and completely unroll the loop?
Probably not a good-tasting construct at all.
Honestly the whole second half seemed damned weird. Give the requirement to zero the edges of a two dimensional array, it's so astonishingly obvious to just hard code the 0 and width-1/height-1 that do do anything else suggests a special effort to make a sub-optimal solution simply for arguments sake.
You could address both issues by having two for loops, one following the other. The first loop changes the top and bottom rows. The second loop changes the sides but not for the top and bottom cells. A comment could highlight that you're not updating the corners.
for (int r = 0; r < GRID_SIZE; r++) {
for (int c = 0; c < GRID_SIZE; c++) {
if (i == 1 && j >= 1 && j < GRID_SIZE - 1)
i = GRID_SIZE - 1;
grid[i][j] = 0;
}
}
Of course, this one has a conditional, and many would frown on mucking with the loop counter outside of the for statement.A source for this style may be dcraw, e.g. see from border_interpolate():
for (row=0; row < height; row++)
for (col=0; col < width; col++) {
if (col==border && row >= border && row < height-border)
col = width-border;
// etc.
The dcraw code is so tightly written that I assume Dave Coffin has good reason for this choice, but I've never tested variants for performance.Spoiler alert: flipping that single bit from i=0 to i=1 might deserve a little comment of the "why" category.
alarm bells
There are only 252 points along the edge. This code will act on each corner twice. If you were performing an operation like `+= 1` on each edge element, this code would be wrong. When you copy and paste it later and change all the `= 0` to something else, you might end up with an unfortunate surprise.
Once I saw this mistake in the 2nd code example, I guessed it would also appear in the 3rd one. Sure enough, it does. This is just as unsavory to me as the original code.
I'm not sure if the author is here or not, but if you are, can you see the fix?