Just another program for my bot: 4 Ping sensors with Buzzer alarm (updated)

When you create an 'object' you are basically creating an array?

An object and an array are two different concepts. 'Objects' are an objected oriented programming concept (ie C++), which Arduino does support. That's beyond the scope of what code has been provided in this thread though. An array is a continuous sequence of variables of the same type that can be iteratively or independently accessed via the array index operator: [].

Is 'i' a (local?)variable for a stored calculation? Can this be used again in the program for other calculations from a totally different source (i.e. another sensor)?

This gets back into variable scope. Yes, i is a local variable, but it's important to understand HOW local it is. In the following case:

for (int i = 0; i < N_PINGS; ++i) {
    range [i] = ping(pingPins [i]);
    delay(5);
  }

i is only local to the for block. Once the for block finishes, that instance of the variable i no longer exists. Which is why in subsequent for loops, he's redeclaring the variable i (the purpose of the 'int' text in the for loop). The following has some not so obviously different behavior:

  int i;
  for (i = 0; i < N_PINGS; ++i) {
    range [i] = ping(pingPins [i]);
    delay(5);
  }

In this case, because i was declared prior to the for loop, and not inside it, it remains in scope outside the for loop, and will remain in scope until the block of code it was declared in is no longer in scope. What constitutes a 'block' of code? Anything within a a set of {} is a block of code. The body of the for loop is a block of code. The body of a function is a block of code. Variable scope extends into child blocks, but not back out to parent blocks, ie:

void loop()
{
  //This starts the loop function block of code
  int x = 25;

  while(x > 0)
  {
    //This starts the while block of code, which can gets visibility to it's parent's scope, so can see x
    int y;
    if(x > 10)
    {
      //This is yet another block.
      y = 5;
    }
    else
    {
      //And another block.
      y = 1;
    }
    x -= y;
  }
  //Now that you've left the while block, y is no longer in scope.  x remains in scope because you are still in the loop block  
  
}
//Now that you've left the loop block, x is no longer in scope either

#define N_PINGS 4 defines a macro. A very simple one. Everywhere in the code that the symbol N_PINGS exists will get replaced with the value 4 prior to actual compilation of the code. This gets into the code maintenance of things, making it potentially easy to change the number of sensors on your device and minimize the amount of changes in the code necessary to support it.

A common coding philosophy is that you should never have any hard coded values in your source code (commonly referred to as magic numbers). Those magic numbers should always be in either a variable, or a define. When dealing with thousands, tens of thousands, or hundreds of thousands of lines of code, it will rarely be obvious what those magic numbers actually mean. I've seen some programmers take it to the extreme and remove even hardcoded zeroes from their code, like:

int baseValue = 0;  //could also be #define'd (or const'd)
int numSensors = 5;  //etc.
for(int i = baseValue; i < numSensors; i++)