Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

K&R: array of character pointers

On pg. 109 of K&R, we see:

void writelines(char *lineptr[], int nlines)
{
  while (nlines -- > 0) printf("%s\n", *lineptr++);
}

I'm confused about what *lineptr++ does exactly. From my understanding, printf requires a char pointer, so we provide that with *lineptr. Then we increment lineptr up to the next char pointer in the array? Isn't this illegal?

On page 99, K&R writes that "an array name is not a variable; constructions like a=pa [where a is an array, pa is a pointer to an array] and a++ are illegal."

like image 391
Elben Shira Avatar asked May 08 '09 02:05

Elben Shira


2 Answers

Keep reading! At the very bottom of p. 99

As formal parameters in a function definition,

 char s[];

and

 char *s;

are equivalent; we prefer the latter because it says more explicitly that the parameter is a pointer.

I.e. you can never pass an array (which is not a variable) to a function. If you declare a function that looks like it takes an array, it really takes a pointer (which is a variable). This makes sense. It would be odd for a function argument not to be a variable -- it can have a different value every time you call the function so it sure ain't a constant!

like image 181
Tom Future Avatar answered Oct 14 '22 23:10

Tom Future


lineptr is not really an array; it's a pointer to a pointer. Note that the postincrement operator ++ has higher precedence than the dereference operator *, so what happens in lineptr++ is this:

  1. lineptr gets incremented to point to the next element in the array
  2. The result of lineptr++ is the old value of lineptr, namely a pointer to the current element in the array
  3. *lineptr++ dereferenced that, so it is the value of the current element in the array

Thus, the while loop iterates over all of the elements in the array pointed to by lineptr (each element is a char*) and prints them out.

like image 25
Adam Rosenfield Avatar answered Oct 14 '22 21:10

Adam Rosenfield