0

I am learning c pointer and I follow c4learn as tutorial. In pointer to array of string section, which has following code:

char *arr[4] = {"C","C++","Java","VBA"};
char *(*ptr)[4] = &arr;

I didn't get what is

*(*ptr)[4]

? Wasn't it possible to use it like

**ptr

instead?

Update1:

Currently I am in the next section, function pointer and I saw again similar code:

void *(*ptr)();
Seyed Morteza Mousavi
  • 6,855
  • 8
  • 43
  • 69
  • `char *(*ptr)[4]` is a pointer-to-array-of-4-pointers-to-char. Since you take the address of an array, you have to use a pointer to array, not a pointer to pointer (since an array is not a pointer, contrary to popular belief.) – The Paramagnetic Croissant Mar 20 '15 at 07:44

4 Answers4

4
char *(*ptr)[4]

is a pointer to a length 4 array of pointers to char (char*). Since arr is a length 4 array of char*, ptr can be made to point to arr by assigning it the address of arr, &arr.

void *(*ptr)();

Is a pointer to a parameterless function returning void*. For example

void* fun();     // function

void *(*ptr)();  // function pointer

p = fun;         // function pointer points to function

C syntax can be quite confusing, so it may be easier to illustrate this with some examples. Note that whitespaces between T and ; make no difference.

T name[N];     // size N array of T
T * name[N];   // size N array of pointer to T
T (*name)[N];  // pointer to size N array of T
T ** name[N];  // size N array of pointer to pointer to T
T *(*name)[N]; // pointer to size N array of pointer to T
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • @SeyedMortezaMousavi I added something about the function pointer. But you're supposed to ask one question at a time. – juanchopanza Mar 20 '15 at 07:54
  • I asked them in the same question because of similarity between them. Any way thanks for your help but can you make the concept of parenthesis more clear? – Seyed Morteza Mousavi Mar 20 '15 at 07:59
  • @SeyedMortezaMousavi I added some explanations for the arrays. I hope it helps. Syntax is not C's strong point. And C++ inherited all of C's syntactical peculiarities. – juanchopanza Mar 20 '15 at 08:09
0
char *ar[4];

Declares ar as an array of four pointers to chars.

To declare a pointer, you take the declaration of something it can point to, and replace the variable name with (*some_other_name).

So char *(*ptr)[4]; declares ptr as a pointer to an array of four pointers to chars. Normally you can drop the brackets, but in this case, char **ptr[4]; would declare ptr as an array of four pointers to pointers to chars which is not what we want.

Similarly for a function pointer. void *fn() declares a function. void *(*ptr)() declares a pointer that could point to fn. void **ptr() would declare a function with a different return type.

user253751
  • 57,427
  • 7
  • 48
  • 90
0

Wasn't it possible to use it like **ptr instead?

Yes, assuming you mean like ptr2 below:

const char* arr[4] = {"C","C++","Java","VBA"};
const char* (*ptr)[4] = &arr;
const char** ptr2 = arr;

There is a difference though... with ptr the type still encodes the array length, so you can pass ptr but not ptr2 to functions like the one below:

template <size_t N>
void f(const char* (&arr)[N]) { ...can use N in implementation... }

Currently I am in the next section, function pointer and I saw again similar code: void *(*ptr)();

That creates a pointer to a function - taking no arguments - returning a void* (i.e. the address of an unspecified type of data, or nullptr).

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
0

char *(*ptr)[4] is an array pointer to an array of pointers.

With less obfuscated syntax: if you have a plain array int arr[4]; then you can have an array pointer to such an array by declaring int (*arr_ptr)[4].

So there are arrays, regular pointers and array pointers. Things get confusing because when you use the array name by itself, arr, it decays into a regular pointer to the first element. Similarly, if you have a regular pointer and let it point at the array, ptr = arr; it actually just points at the first element of the array.

Array pointers on the other hand, points at the "whole array". If you take sizeof(*arr_ptr) from the example above, you would get 4*sizeof(int), 4*4=16 bytes on a 32-bit machine.

It should be noted that an array pointer a mildly useful thing to have. If you are a beginner, you don't really need to waste your time trying to understand what this is. Array pointers are mainly there for language consistency reasons. The only real practical use for array pointers is pointer arithmetic on arrays-of-arrays, and dynamic allocation of multi-dimensional arrays.

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396