constant pointer vs pointer on a constant value [d

2019-01-01 14:49发布

问题:

This question already has an answer here:

  • What is the difference between char * const and const char *? 18 answers

What is the difference between the following declarations?

char * const a;
const char * a;

In order to understand the difference I wrote this small program:

#include <stdio.h>
#include <stdlib.h>


int main (int argc, char **argv)
{
    char a = \'x\';
    char b = \'y\';

    char * const pc1 = &a;
    const char * pc2 = &a;

    printf (\"Before\\n\");
    printf (\"pc1=%p\\n\", pc1);
    printf (\"*pc1=%c\\n\", *pc1);
    printf (\"pc2=%p\\n\", pc2);
    printf (\"*pc2=%c\\n\", *pc2);

    *pc1 = b;
/*     pc1 = &b; */

/*     *pc2 = b; */
    pc2 = &b;

    printf (\"\\n\\n\");

    printf (\"After\\n\");
    printf (\"pc1=%p\\n\", pc1);
    printf (\"*pc1=%c\\n\", *pc1);
    printf (\"pc2=%p\\n\", pc2);
    printf (\"*pc2=%c\\n\", *pc2);

    return EXIT_SUCCESS;
}

I compiled the program (with gcc 3.4) and ran it. The output highlights the difference rather well:

Before
pc1=ffbfd7e7
*pc1=x
pc2=ffbfd7e7
*pc2=x


After
pc1=ffbfd7e7
*pc1=y
pc2=ffbfd7e6
*pc2=x

However, I had to write the small program to get the answer. In case I\'m away from the machine (at an interview for instance), I wouldn\'t be able to answer the question.

Can someone please explain, by commenting the above example, how the const keyword operates?

回答1:

char * const a;

means that the pointer is constant and immutable but the pointed data is not.
You could use const_cast(in C++) or c-style cast to cast away the constness in this case as data itself is not constant.

const char * a;

means that the pointed data cannot be written to using the pointer a. Using a const_cast(C++) or c-style cast to cast away the constness in this case causes Undefined Behavior.



回答2:

To parse complicated types, you start at the variable, go left, and spiral outwards. If there aren\'t any arrays or functions to worry about (because these sit to the right of the variable name) this becomes a case of reading from right-to-left.

So with char *const a; you have a, which is a const pointer (*) to a char. In other words you can change the char which a is pointing at, but you can\'t make a point at anything different.

Conversely with const char* b; you have b, which is a pointer (*) to a char which is const. You can make b point at any char you like, but you cannot change the value of that char using *b = ...;.

You can also of course have both flavours of const-ness at one time: const char *const c;.



回答3:

char * const a;

*a is writable, but a is not; in other words, you can modify the value pointed to by a, but you cannot modify a itself. a is a constant pointer to char.

const char * a; 

a is writable, but *a is not; in other words, you can modify a (pointing it to a new location), but you cannot modify the value pointed to by a.

Note that this is identical to

char const * a;

In this case, a is a pointer to a const char.



回答4:

Now that you know the difference between char * const a and const char * a. Many times we get confused if its a constant pointer or pointer to a constant variable.

How to read it? Follow the below simple step to identify between upper two.

Lets see how to read below declaration

char * const a;

read from Right to Left

Now start with a,

1 . adjacent to a there is const.

char * (const a);

---> So a is a constant (????).

2 . Now go along you get *

char (* (const a));

---> So a is a constant pointer to (????).

3 . Go along and there is char

(char (* (const a)));

---> a is a constant pointer to character variable

a is constant pointer to character variable. 

Isn\'t it easy to read?

Similarily for second declaration

const char * a;

Now again start with a,

1 . Adjacent to a there is *

---> So a is a pointer to (????)

2 . Now there is char

---> so a is pointer character,

Well that doesn\'t make any sense!!! So shuffle pointer and character

---> so a is character pointer to (?????)

3 . Now you have constant

---> so a is character pointer to constant variable

But though you can make out what declaration means, lets make it sound more sensible.

a is pointer to constant character variable


回答5:

The easiest way to understand the difference is to think of the different possibilities. There are two objects to consider, the pointer and the object pointed to (in this case \'a\' is the name of the pointer, the object pointed to is unnamed, of type char). The possibilities are:

  1. nothing is const
  2. the pointer is const
  3. the object pointed to is const
  4. both the pointer and the pointed to object are const.

These different possibilities can be expressed in C as follows:

  1. char * a;
  2. char * const a;
  3. const char * a;
  4. const char * const a;

I hope this illustrates the possible differences



回答6:

The first is a constant pointer to a char and the second is a pointer to a constant char. You didn\'t touch all the cases in your code:

char * const pc1 = &a; /* You can\'t make pc1 point to anything else */
const char * pc2 = &a; /* You can\'t dereference pc2 to write. */

*pc1 = \'c\' /* Legal. */
*pc2 = \'c\' /* Illegal. */

pc1 = &b; /* Illegal, pc1 is a constant pointer. */
pc2 = &b; /* Legal, pc2 itself is not constant. */


回答7:

Above are great answers. Here is an easy way to remember this:

a is a pointer

*a is the value

Now if you say \"const a\" then the pointer is const. (i.e. char * const a;)

If you say \"const *a\" then the value is const. (i.e. const char * a;)



回答8:

I will explain it verbally first and then with an example:

A pointer object can be declared as a const pointer or a pointer to a const object (or both):

const pointer cannot be reassigned to point to a different object from the one it is initially assigned, but it can be used to modify the object that it points to (called the \"pointee\").
Reference variables are thus an alternate syntax for constpointers.

A pointer to a const object, on the other hand, can be reassigned to point to another object of the same type or of a convertible type, but it cannot be used to modify any object.

const pointer to a const object can also be declared and can neither be used to modify the pointee nor be reassigned to point to another object.

Example:

void Foo( int * ptr,
         int const * ptrToConst,
         int * const constPtr,
         int const * const constPtrToConst ) 
{ 
    *ptr = 0; // OK: modifies the \"pointee\" data 
    ptr = 0; // OK: modifies the pointer 

    *ptrToConst = 0; // Error! Cannot modify the \"pointee\" data
     ptrToConst = 0; // OK: modifies the pointer 

    *constPtr = 0; // OK: modifies the \"pointee\" data 
    constPtr = 0; // Error! Cannot modify the pointer 

    *constPtrToConst = 0; // Error! Cannot modify the \"pointee\" data 
    constPtrToConst = 0; // Error! Cannot modify the pointer 
}

Happy to help! Good Luck!



回答9:

You may use cdecl utility or its online versions, like https://cdecl.org/

For example:

void (* x)(int (*[])()); is a declare x as pointer to function (array of pointer to function returning int) returning void



回答10:

Trying to answer in simple way:

char * const a;  => a is (const) constant (*) pointer of type char {L <- R}. =>( Constant Pointer )
const char * a;  => a is (*) pointer to char constant             {L <- R}. =>( Pointer to Constant)

Constant Pointer:

pointer is constant !!. i.e, the address it is holding can\'t be changed. It will be stored in read only memory.

Let\'s try to change the address of pointer to understand more:

char * const a = &b; 
char c;
a = &c; // illegal , you can\'t change the address. `a` is const at L-value, so can\'t change. `a` is read-only variable.

It means once constant pointer points some thing it is forever.

pointer a points only b.

However you can change the value of b eg:

char b=\'a\';
char * const a =&b;

printf(\"\\n print a  : [%c]\\n\",*a);
*a = \'c\';
printf(\"\\n now print a  : [%c]\\n\",*a);

Pointer to Constant:

Value pointed by the pointer can\'t be changed.

const char *a;
char b = \'b\';
const char * a =&b;
char c;
a=&c; //legal

*a = \'c\'; // illegal , *a is pointer to constant can\'t change!.


回答11:

const char * a;

This states pointer to constant character. For eg.

char b=\'s\';
const char *a = &b;

Here a points to a constant char(\'s\',in this case).You can\'t use a to change that value.But this declaration doesn\'t mean that value it points to is really a constant,it just means the value is a constant insofar as a is concerned. You can change the value of b directly by changing the value of b,but you can\'t change the value indirectly via the a pointer.

*a=\'t\'; //INVALID b=\'t\' ; //VALID

char * const a=&b

This states a constant pointer to char. It constraints a to point only to b however it allows you to alter the value of b.

Hope it helps!!! :)



标签: c pointers const