简体   繁体   中英

What does this declaration means “int(*ptr[3])();”?

Whole code :

#include<stdio.h>    
 aaa(){ 
    printf("hi");  
 }  
 bbb(){  
    printf("hello");  
 }  
 ccc(){ 
    printf("ccc");  
 }  
int main(){  
     int(*ptr[3])(); 
     ptr[0]=aaa;  
     ptr[1]=bbb;  
     ptr[3]=ccc;   
     ptr[3]();   
}   

Output will be "bye".
What i can see from seeing the code that int(*ptr[3])() is some kind of declaration of array that is related to int, it is also look like function call. In lower lines of code name of functions are assigned to array, and piece of array can be used for function calling. Can somebody explain, what declaration is and how function calling is proceeding ?

When you faced such a type, you may then use the cdecl tool to decode it :

$ cdecl explain "int (*p[3])()"
declare p as array 3 of pointer to function returning int
$

Beware that ptr is a reserved word for cdecl, you just have to rename the variable to something more basic...

------EDIT------

Becareful that an empty list of arguments doesn't means the same in C or C++. In C that means a function with an unknown number of arguments (a C function with no args must be declared as f(void) ). In C++ that means a function with no arguments.

它将ptr声明为一个由3个类型为int(*)()元素组成的数组,这是一个指向int()类型的指针,该指针是一个返回int的零参数函数。

int (*ptr[3])() is a an array of 3 pointers to functions returning int.

A bit more clearly, that means it is an array of function pointers. The array has space for 3 of them and the functions are expected to return ints.


Some other issues with the example code

There were a few issues with the code so I went and tidied it up.

Assigning out of bounds in an array is undefined behaviour .

test.c:30:3: warning: array index 3 is past the end of the array (which contains 3
elements) [-Warray-bounds]
ptr[3] = ccc;
^   ~
test.c:23:3: note: array 'ptr' declared here
int (*ptr[3])();

Cleaned up code:

#include <stdio.h>

/* Missing function prototypes
 * For C a function taking no arguments should have void for its argument
 * For C++ void can be skipped
 */
int aaa(void);
int bbb(void);
int ccc(void);

/* The function should be declared with type specifier, although it is assumed
 * by default to return int.
 */
int aaa(void) {
  /* Unless this print statement is going to be part of more output, you should
   * return a newline
   */
  printf("hi\n");
  /* As this function is meant to return an int, we will return 0*/
  return 0;
}

int bbb(void) {
  printf("hello\n");
  return 0;
}

int ccc(void) {
  printf("ccc\n");
  return 0;
}

int main(void) {
  int (*ptr[3])();
  ptr[0] = aaa;
  ptr[1] = bbb;
  /* Now assigning to valid ptr[2] and not out of bounds ptr[3] */
  ptr[2] = ccc;
  ptr[2]();
}

You read it boustrophedonically:

You start from the innermost part and start reading in the direction RIGHT->LEFT.

So here:

int(*ptr[3])()

You go to the identifier ptr that is the innermost part, then you start reading so:

...(*ptr[3])...

ARRAY OF 3 (POINTERS TO ...)

int(...)()

...FUNCTIONS THAT HAVE NO PROTOTYPE (C89 semantics) AND RETURN INT.

It simply means an array of 3 pointers pointing to functions namely aaa(), bbb() and ccc(). :)

In simpler sense, an array of 3 function pointers..

I guess ptr[3] = ccc; is wrong here .. it's like ABW - writing out of the bound of the array. It should be ... ptr[2] = ccc;

That declaration means that someone wasn't thinking clearly. It would be much simpler if it was unrolled:

typedef int (*fptr)();
fptr ptr[3];

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