-1

If I for example define an array

char string[20] = "something";

And function

void f(char* somestring[])

What is this, an address or a number or what and how can I work with this? In which purposes is it used?

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
user648933
  • 25
  • 3
  • `string` is an *array* of 20 `char`s. `somestring` is a *pointer* to a pointer to a `char`. – John Bollinger Mar 18 '19 at 20:28
  • See [What is the difference between char array vs char pointer in c?](https://stackoverflow.com/questions/10186765/what-is-the-difference-between-char-array-vs-char-pointer-in-c), and [Is an array name a pointer?](https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer). – John Bollinger Mar 18 '19 at 20:29
  • The last part of the question is much too broad to answer here. – John Bollinger Mar 18 '19 at 20:32

2 Answers2

0

First, an address is a number. Then, type char *foo[] (which really is just char **foo) has several equivalent interpretations.

  1. foo is a doubly indexed char array.
  2. foo is a pointer to a char array (that is, a string if it's null terminated like a string literal is).
  3. and probably the rarest use case, foo is a pointer, to a pointer to a char value.

It can be used in several ways as well.

  1. foo is a char 2-dimensional array ; then foo[x][y] retrieves you the character in the array at row x and column y.
  2. foo is a pointer to a string. Then (*foo)[x] gives you the x-th character of the string.
  3. Use **foo to set the char value, and *foo to change the character pointed to by the pointer.

EDIT: of course, all these are composeable and equivalent. For instance, foo[0][0] is just (*foo)[0] which is just **foo.

TDk
  • 1,019
  • 6
  • 18
0

string is a 20-element array of char - you can store a string of up to 19 characters (need to reserve one element for the string terminator), or you can store a sequence of 20 characters that does not represent a string (like a hash value or something).

Except when it is the operand of the sizeof or unary & operators, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and its value will be the address of the first element of the array.

So, if you passed string as an argument to a function, like so:

f( string );

what the function actually receives is a pointer value:

void f( char *somestring ) { ... }

In the context of a function parameter declaration (and only in that context), T a[N] and T a[] are both treated as T *a, so you could declare f to be any of

void f( char somestring[20] ) { ... }

or

void f( char somestring[] ) { ... }

as well.

The subscript operator [] is defined to work on pointer expressions as well as array expressions, so you can still use [] to index into somestring like any other array:

void f( char *somestring )
{
  int i = 0;
  while ( somestring[i++] )
  {
    // do something interesting with somestring[i]
  }
}

So, if void f( char *somestring ) is the same as void f( char somestring[] ), then what do we make of

void f( char *somestring[] )

?

In this case, it's clear that somestring is meant to be an array of pointers to char, something like

char *strings[] = {"foo", "bar", "bletch", ... };

Each strings[i] stores the address of the corresponding string literal, not the contents of the string itself. By the same rule above, the prototype may also be written as

void f( char **somestring ) { ... }

or

void f( char *somestring[N] ) { ... }

The one thing somestrings is not in this case is a 2D array of char. If strings had been declared

#define N ... // number of strings
#define M ... // maximum length of string

char strings[N][M+1] = {"foo", "bar", "bletch", ... };

then, if we pass strings to f, it would "decay" to

void f( char (*somestrings)[M+1] ) { ... }

The the type of strings is "N-element array of M+1-element array of char", so the expression "decays" to "pointer to M+1-element array of char".

John Bode
  • 119,563
  • 19
  • 122
  • 198