|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Contents
IntroductionEver came across a declaration like The basicsLet me start with a very simple example. Consider the declaration: int n;
This should be interpreted as "declare Coming to the declaration of a pointer variable, it would be declared as something like: int *p;
This is to be interpreted as "declare int* p,q;
At first sight, it looks like We can have a pointer to a pointer, which can be declared as: char **argv;
In principle, there is no limit to this, which means you can have a pointer to a pointer to a pointer to a pointer to a Consider the declarations: int RollNum[30][4]; int (*p)[4]=RollNum; int *q[5]; Here, We can have a mixed bag of int **p1; // p1 is a pointer to a pointer to an int. int *&p2; // p2 is a reference to a pointer to an int. int &*p3; // ERROR: Pointer to a reference is illegal. int &&p4; // ERROR: Reference to a reference is illegal. The const modifierThe const int n=5; int const m=10; The two variables
const int *p; int const *q; Which of them is a pointer to a int * const r= &n; // n has been declared as an int Here, To combine these two declarations to declare a const int * const p=&n // n has been declared as const int The following declarations should clear up any doubts over how char ** p1; // pointer to pointer to char const char **p2; // pointer to pointer to const char char * const * p3; // pointer to const pointer to char const char * const * p4; // pointer to const pointer to const char char ** const p5; // const pointer to pointer to char const char ** const p6; // const pointer to pointer to const char char * const * const p7; // const pointer to const pointer to char const char * const * const p8; // const pointer to const pointer to const char The subtleties of typedef
typedef char * PCHAR; PCHAR p,q; both Here are a few declarations made using typedef char * a; // a is a pointer to a char typedef a b(); // b is a function that returns // a pointer to a char typedef b *c; // c is a pointer to a function // that returns a pointer to a char typedef c d(); // d is a function returning // a pointer to a function // that returns a pointer to a char typedef d *e; // e is a pointer to a function // returning a pointer to a // function that returns a // pointer to a char e var[10]; // var is an array of 10 pointers to // functions returning pointers to // functions returning pointers to chars.
typedef struct tagPOINT { int x; int y; }POINT; POINT p; /* Valid C code */ Function pointersFunction pointers are probably the greatest source of confusion when it comes to interpreting declarations. Function pointers were used in the old DOS days for writing TSRs; in the Win32 world and X-Windows, they are used in callback functions. There are lots of other places where function pointers are used: virtual function tables, some templates in STL, and Win NT/2K/XP system services. Let's see a simple example of a function pointer: int (*p)(char); This declares A pointer to a function that takes two char ** (*p)(float, float); How about an array of 5 pointers to functions that receive two void * (*a[5])(char * const, char * const); The right-left rule [Important]This is a simple rule that allows you to interpret any declaration. It runs as follows: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed. Take the example given in the introduction: int * (* (*fp1) (int) ) [10]; This can be interpreted as follows:
Here's another example: int *( *( *arr[5])())();
Further examplesThe following examples should make it clear: float ( * ( *b()) [] )(); // b is a function that returns a // pointer to an array of pointers // to functions returning floats. void * ( *c) ( char, int (*)()); // c is a pointer to a function that takes // two parameters: // a char and a pointer to a // function that takes no // parameters and returns // an int // and returns a pointer to void. void ** (*d) (int &, char **(*)(char *, char **)); // d is a pointer to a function that takes // two parameters: // a reference to an int and a pointer // to a function that takes two parameters: // a pointer to a char and a pointer // to a pointer to a char // and returns a pointer to a pointer // to a char // and returns a pointer to a pointer to void float ( * ( * e[10]) (int &) ) [5]; // e is an array of 10 pointers to // functions that take a single // reference to an int as an argument // and return pointers to // an array of 5 floats. Suggested reading
CreditsI got the idea for this article after reading a thread posted by Jörgen Sigvardsson about a pointer declaration that he got in a mail, which has been reproduced in the introduction. Some of the examples were taken from the book "Test your C skills" by Yashvant Kanetkar. Some examples of function pointers were given by my cousin Madhukar M Rao. The idea of adding examples with mixed | ||||||||||||||||||||