Since you mentioned "optimal arithmetic", if you prefer doing additions over multiplications, you can take advantage of the fact that the square number of n is equal to the sum of the first n odd numbers; therefore the difference between the consecutive squares (i*i) and (i+1)*(1+1) is equal to the (i+1)st odd number (2*i+1). You can reverse that dependency to construct the square numbers like this:
void make_squares(int* square_array, int n) {
int square = 0; int current_odd_number = 1; while (current_odd_number < n<<1) { *square_array = square; square += current_odd_number; current_odd_number += 2; ++square_array; }
}
Note that modern CPUs will likely be just as fast doing the multiplications as suggested in solution 1. Just wanted to point out an alternative.