Q:

How is argv handled internally?

Here is some code from K&R that describes command-line arguments
int getline(char *s, int lim)
{
    int i = 0;

    while(i < lim - 1 && (*s = getchar()) != EOF && *s++ != '\n')
       i++;

    if(*s == '\n')
      *s++ = '\n', i++;

    *s = '\0';
    return i;
}

int main(int argc, char *argv[])
{   

     char line[MAXLINE];
     long lineno = 0;
     int c, except = 0, number = 0, found = 0;

     while(--argc > 0 && (*++argv)[0] == '-')
        while(c = *++argv[0])
          switch(c) {
             case 'x':
                  except = 1;
                  break;
             case 'n':
                  number = 1;
                  break;
             default:
                  printf("find: illegal option %c\n", c);
                  argc = 0;
                  found = -1;
                  break;
          }

     if(argc != 1)
         printf("Usage: find -x -n pattern\n");
     else
         while(getline(line, MAXLINE) > 0) {
             lineno++;
             if((strstr(line, *argv) != NULL) != except) {
                   if(number)
                      printf("%ld:", lineno);
                   printf("%s", line);
                   found++;
             }
         }

     printf("Found: %d", found);
     return found;
}

There is another question on here involving this, but there are a few things still not clear to me.
First of all, are the array of pointers in *argv[] handled internally as pointers to string constants, pointers to multiple arrays, each containing a string, or pointers to different spots in a single array, an array that holds all of the strings? I really only need a single sentence answer for this.

A:

A single sentence: it depends entirely on the implementation.
Expanding: provided the implementation follows the rules as laid out in the standard, it's free to arrange the actual character arrays however it sees fit.
The pointers in argv have to be consecutive (and argv[argc] must be NULL) but the character arrays that they point to can be all over the place, with the proviso that each argument has consecutive characters with a null terminator.
So it, could be:
argc == 2
+---------+---------+---------+
| argv[0] | argv[1] | argv[2] | --+
+---------+---------+---------+   |
  |            |                  V
  |            +-----------+     NULL
  |                        |
  V                        V
+---+---+---+---+---+----+---+---+----+
| s | l | e | e | p | \0 | 6 | 0 | \0 |
+---+---+---+---+---+----+---+---+----+

or, equally valid:
argc == 2
+---------+---------+---------+
| argv[0] | argv[1] | argv[2] | ------------+
+---------+---------+---------+             |
  |            |                            V
  |            +------------------------+  NULL
  |                                     |
  V                                     V
+---+---+---+---+---+----+ (any old   +---+---+----+
| s | l | e | e | p | \0 |  rubbish   | 6 | 0 | \0 |
+---+---+---+---+---+----+     here)  +---+---+----+

A:

The strings are not string constants, but you can consider them as pointers to multiple arrays each containing a string or as pointers to different spots in a single array that holds all the strings; the typical implementation on Unix is such that you can't tell the difference between the two, but other implementations could lay out the data differently because the standard only requires an 'as if' implementation that behaves as described by the standard (the relevant section of which is §5.1.2.2.1 Program startup) — and all that's a single sentence to meet the requirements of the question.

