C Pointers Confusing .. Ahh Read the Technique

Given the following C declarations, what does each one mean?
1.) int (*p)[ 5 ];

2.) char *x[ 3 ][ 4 ];

3.) int *(*a[ 10 ])();

4.) int (*t[])();

C declarations can sometimes be quite complex – and interviewers love to test out the ability of candidates to break down and understand those declarations. The way to approach this problem is to use a general method that will help you read any C declaration – otherwise, you can easily find yourself very confused. Here’s a good rule to follow when trying to make sense of a C declaration:

Start at the variable name, also known as the identifier. Without skipping a right parenthesis, look right and say what you see – even if you see nothing continue. Without skipping a left parenthesis look left again and say what you see. If you are currently inside a pair of parentheses, jump outside this level. Look right and say what you see. Look left and say what you see. Keep doing this until you say the variable type or return type.

An important note: you should always remember that functions and arrays are read left-to-right and have precedence over pointers, which are read right-to-left.

Before reading the answers, it is best to use the rule given, and try it out for yourself. For the first example, we start at p. We look right and there is a parenthesis, which we don’t want to skip until we look left. So we look left and get that p is a pointer. Now, we can jump outside the parentheses, and we look right and find an array of size of 5, so now we can add to our statement that p is a pointer to an array of size 5. Now, we look left and find the ‘int’, so we can finish our declaration by saying that p is “a pointer to an array of 5 ints”.

For the second example, we start with x. We look right and find an array composed of 3 arrays of size 4. You may have been tempted to jump back left to the pointer after reading out “array of size 3”, but you must note that arrays take precedence over pointers, so continuing on with the second array is important. So now we see that x is an array composed of 3 arrays of size 4, and the next step is to move left. We see a pointer, so now we can say that “x is an array composed of 3 arrays of 4 pointers to char”.

For the last two examples, we’ll just be giving the answers, since you should be able to figure them out on your own now. In the third example, a is “an array of 10 pointers to functions returning an int pointer”. For the fourth example, t is “an array of pointers to functions returning an int”.

What’s the difference between const char *p, char * const p and const char *
const p?
const char *p –
This is a pointer to a constant char. One cannot change the value
pointed at by p, but can change the pointer p itse
lf.
*p = ‘A’ is illegal.
p = “Hello” is legal.
Note that even char const *p is the same!
const * char p – This is a constant pointer to (nonconst)
char. One cannot change
the pointer p, but can change the value pointed at
by p.
*p = ‘A’ is legal.
p = “Hello” is illegal.
const char * const p –
This is a constant pointer to constant char! One cannot
change the value pointed to by p nor the poin
ter.
153
*p = ‘A’ is illegal.
p = “Hello” is also illegal.
To interpret these declarations, let us first consider the general form of declaration:
[qualifier] [storage-class] type [*[*]..] [qualifier] ident ;
or
[storage-class] [qualifier] type [*[*]..] [qualifier] ident ;
where,
qualifier:
volatile
const
storage-class:
auto extern
static register
type:
void char short
int long float
double signed unsigned
enum-specifier
typedef-name
struct-or-union-specifier
Both the forms are equivalent. Keywords in the brackets are optional. The simplest tip
here is to notice the relative position of the `const’ keyword with respect to the asterisk
(*).
Note the following points:
• If the `const’ keyword is to the left of the asterisk, and is the only such keyword in
the declaration, then object pointed by the pointer is constant, however, the
pointer itself is variable. For example:
const char * pcc;
char const * pcc;
• If the `const’ keyword is to the right of the asterisk, and is the only such keyword
in the declaration, then the object pointed by the pointer is variable, but the
154
pointer is constant; i.e., the pointer, once initialized, will always point to the same
object through out it’s scope. For example:
char * const cpc;
• If the `const’ keyword is on both sides of the asterisk, the both the pointer and the
pointed object are constant. For example:
const char * const cpcc;
char const * const cpcc2;
One can also follow the “nearness” principle; i.e.,
• If the `const’ keyword is nearest to the `type’, then the object is constant. For
example:
char const * pcc;
• If the `const’ keyword is nearest to the identifier, then the pointer is constant. For
example:
char * const cpc;
• If the `const’ keyword is nearest, both to the identifier and the type, then both the
pointer and the object are constant. For example:
const char * const cpcc;
char const * const cpcc2;
However, the first method seems more reliable…

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: