7
int (*ptr)(char (*ch)[]);

What does the above declaration means? Does it mean

ptr is pointer to a function that accepts an argument which is array of pointers to characters returning integer?

How to evaluate?

Rohit
  • 6,941
  • 17
  • 58
  • 102

4 Answers4

4

ptr is pointer to a function that accepts an argument which is a pointer to an array of characters, returning integer.

Ziffusion
  • 8,779
  • 4
  • 29
  • 57
  • 1
    how do u evaluate the same? – Rohit Jun 10 '13 at 18:29
  • Not sure what you are asking. Can you phrase it differently? – Ziffusion Jun 10 '13 at 18:31
  • I mean, how did you come to this conclusion? – Rohit Jun 10 '13 at 18:32
  • 1
    The way you think about this is as follows. To declare a pointer argument, first omit the star and just declare the type. In your case this is "char ch[]". Which is an array of chars. Then you add the star before the name. But here you have to use parens, because otherwise it would confuse the type ("char" vs "char star"). So, it becomes "char (star ch)[]". – Ziffusion Jun 10 '13 at 18:43
  • 1
    "array of characters" isn't a valid target type for a pointer though. You need "array of `N` characters" for some integral `N`. – Ben Voigt Jun 11 '13 at 02:00
3

There's rule: http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html

Briefly, you should start from identifier, then parse everything from identifier to the right (it can be () - function or [] array), then parse everything from identifier to the left. Parentheses changes this order - you should parse everything in the most inner parentheses first and so on, it works like with arithmetic calculations.

In other words, there is an order of precedence (which can be changed by parentheses), from higher to lower:

1) () - function and [] - array, from left to right;

2) * - pointer, type, type modifier, from right to left.


Your example

int (*ptr)(char (*ch)[])

We start from identifier

int (*ptr)(char (*ch)[]);  // (1)ptr
      |_|                      
       1

Identifier ptr is in parentheses, so we parse everything in parenteses first

(*ptr)  // (1)ptr
  |_|       
   1

There's nothing to the right, so we parse to the left

(*ptr)  // (1)ptr is (2)a pointer
 ||_|       
 2 1

We finished in parentheses, now we parse to the right of parentheses

int (*ptr)(char (*ch)[]);  // (1)ptr is (2)a pointer to (3)function
     ||_| |____________|
     2 1        3

So far we ignore function arguments and parse to the left of parentheses

int (*ptr)(char (*ch)[]);  // (1)ptr is (2)a pointer to (3)function which returns (4)int
|_| ||_| |____________|
 4  2 1        3

In the same way we parse argument of function (I've inserted some spaces for better alignment)

char  (* ch )[ ]  // (1)ch is (2)a pointer to (3)array of (4)chars
|___|  | |_| |_|
  4    2  1   3

Finally, we have:

ptr is a pointer to function which returns int and accepts a pointer to array of chars as argument

kotlomoy
  • 1,420
  • 8
  • 14
2

As you have written, ptr is a pointer to a function that returns int, and takes as an argument a pointer to an array of char.

However, you are not allowed to have a pointer to an array without a bound on the array. So, your variable is incorrectly specified, and will not compile. It seems you want ptr to have a type that can accept a pointer to a function that can take any size array. This requires a template construction. For a function argument, it would have the form:

template <unsigned N>
int foo (int (*ptr)(char (*)[N])) {
    //...
}

Normally, the way to simplify such types is to use typedef to represent the complicated parts, so that the variable itself becomes a simple pointer to some type. This is particularly useful when trying to write a function that returns a function pointer.

void x (char *s) {}
typedef void xtype (char *);

void (* y_hard ())(char *) { return x; }
xtype * y_easy () { return x; }

However, the parameterized nature of the function argument makes that harder to achieve. Assuming C++ 11, you can use the following construct (thanks to this answer):

template <unsigned N>
using ArrayArg = const char [N];

template <unsigned N>
using Function = int (ArrayArg<N> *);

template <unsigned N>
int foo (Function<N> *ptr) {
    //...
}
Community
  • 1
  • 1
jxh
  • 69,070
  • 8
  • 110
  • 193
1

It works fine in GCC.

Yes ptr is a function pointer. It is a pointer to a function returning an integer and accepting a pointer to a character array as argument.

Consider the function fun with the following prototype,

int fun(char (*ptr)[]);

fun() is a function accepting a pointer to a character array as argument.

and the following piece of code compile without any error or warning,

int (*ptr)(char (*ch)[]);
ptr=fun;
Deepu
  • 7,592
  • 4
  • 25
  • 47
  • The question is tagged c++. G++ fails to compile this code. See: http://ideone.com/G7kJpr – jxh Jun 11 '13 at 01:32