简体   繁体   中英

What does the (*) in (int (*)[30]) mean?

What does (int (*)[30]) mean in C? For instance, in:

int (*b)[30] = (int (*) [30]) malloc(30 * sizeof(int [20]));

It means, roughly, "is a pointer".

int (*b)[30]

This means " b is a pointer to an array of 30 integers".

(int (*) [30])

This means "cast to a pointer to an array of 30 integers".

int (*b)[30] = (int (*) [30]) malloc(30 * sizeof(int [20]));

Breaking it down:

      b        -- b
    (*b)       -- is a pointer
    (*b)[30]   -- to a 30-element array
int (*b)[30]   -- of int.

In both declarations and expressions, postfix operators like [] have higher precedence than unary operators like * , so T *a[] is interpreted as T *(a[]) ; IOW, a is an array of pointer to T . To designate a as a pointer to an array , we have to force the grouping T (*a)[] .

Simlilarly, the cast expression (int (*) [30]) means "treat the pointer value returned by malloc as a pointer to a 30-element array of int ". Note that, technically speaking, the cast expression is superfluous and should be removed.

The malloc call itself seems very wrong. You're allocating 30 instances of a 20-element array of int , but assigning the result to a pointer to a 30-element array of int ; that's going to cause problems. Assuming you're trying to allocate a N x 30 matrix of int , the following would be safer:

int (*b)[30] = malloc(N * sizeof *b); 

The type of the expression *b is int [30] , so sizeof *b is the same as sizeof (int [30]) .

How to parse C declarations and types: unwind them from outside in.

  • int (*b)[30] .
  • (*b)[30] is an int .
  • (*b) is an int array of length 30 .
  • b is a pointer to an int array of length 30 .

The nameless version int (*) [30] is entirely identical, just the name has been omitted.

If you have a copy of The C Programming Language, there's a program in there called cdecl that can transform such declarations into English. There's been various modifications of it over time, for example cutils in Debian supports the nameless form, and cdecl.org is online.

You can use cdecl to figure these kinds of things out:

cdecl> explain (int (*) [30]) 
cast unknown_name into pointer to array 30 of int

(*) before a variable name means that is a POINTER.

We have just seen that a variable which stores a reference to another variable is called a pointer. Pointers are said to "point to" the variable whose reference they store.

Using a pointer we can directly access the value stored in the variable which it points to. To do this, we simply have to precede the pointer's identifier with an asterisk (*), which acts as dereference operator and that can be literally translated to "value pointed by".

There's really nothing special about (*) . Since you're just referencing a type in your typecast (and not a variable, which has a name, of that type), you simply omit the name. Here the parens are still needed to distinguish an array of pointers from a pointer to an array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM