The Gateway to Computer Science Excellence
+3 votes
234 views

What is the answer?

How char *const  and const char* differ 

by Boss (32.5k points) | 234 views

2 Answers

+4 votes
Best answer

Copying a portion of C grammar for declarations:

declaration
  : declaration_specifiers ';'
  | declaration_specifiers init_declarator_list ';'
  ;
declaration_specifiers
  : storage_class_specifier
  | storage_class_specifier declaration_specifiers
  | type_specifier
  | type_specifier declaration_specifiers
  | type_qualifier
  | type_qualifier declaration_specifiers
  | function_specifier
  | function_specifier declaration_specifiers
  ;
storage_class_specifier
  : TYPEDEF
  | EXTERN
  | STATIC
  | AUTO
  | REGISTER
  ;
type_specifier
  : VOID
  | CHAR
  | SHORT
  | INT
  | LONG
  | FLOAT
  | DOUBLE
  | SIGNED
  | UNSIGNED
  | BOOL
  | COMPLEX
  | IMAGINARY
  | struct_or_union_specifier
  | enum_specifier
  | TYPE_NAME
  ;
type_qualifier
  : CONST
  | RESTRICT
  | VOLATILE
  ;
 
declarator
  : pointer direct_declarator
  | direct_declarator
  ;
direct_declarator
  : IDENTIFIER
  | '(' declarator ')'
  | direct_declarator '[' type_qualifier_list assignment_expression ']'
  | direct_declarator '[' type_qualifier_list ']'
  | direct_declarator '[' assignment_expression ']'
  | direct_declarator '[' STATIC type_qualifier_list assignment_expression ']'
  | direct_declarator '[' type_qualifier_list STATIC assignment_expression ']'
  | direct_declarator '[' type_qualifier_list '*' ']'
  | direct_declarator '[' '*' ']'
  | direct_declarator '[' ']'
  | direct_declarator '(' parameter_type_list ')'
  | direct_declarator '(' identifier_list ')'
  | direct_declarator '(' ')'
  ;
 
init_declarator_list
  : init_declarator
  | init_declarator_list ',' init_declarator
 

;

init_declarator
  : declarator
  | declarator '=' initializer
  ;
pointer
  : '*'
  | '*' type_qualifier_list
  | '*' pointer
  | '*' type_qualifier_list pointer
  ;
type_qualifier_list
  : type_qualifier
  | type_qualifier_list type_qualifier
  ;

Full list:

So, "const" is a type qualifier and in a declaration a type qualifier can come alone or followed by declaration specifier. ( "const; " is a valid C statement as per C grammar).  

Now see the "declarator". After a pointer we can have any number of type quantifiers. i.e.,

char * p, char * const p, char * const const p;

etc.  

const char *p1 = "hello";
const * char p1 = "hello";
char const * p1 = "hello";
char * const p1 = "hello"

There are 4 ways we can write "const" and "char" involving a pointer. The thing to identify is whether "pointer" is constant or if it is a normal pointer to a "const char". 

If pointer is "const", it cannot point to anything else and must be initialized (assigned a value along with declaration). 

If pointer is to a character constant, then the location pointed to by the pointer cannot be modified. (If modified result is undefined meaning anything can happen). 

So, lets see the 4 options I gave:

  1. Constant character pointer, p1 - yes, p1 is a pointer to a constant char.
  2. After "*" we cannot have a type specifier - hence invalid. 
  3. Character constant pointer, p1 - p1 is a pointer to a character constant - same as 1.
  4. Constant pointer to character, p1 - p1 is a constant pointer to a character. 

So, now coming to question:

p1 is a pointer to a character constant - (*p1) is READ ONLY

p2 is a constant pointer - p2 is READ ONLY.

So, statements 4 and 5 are not allowed. 

by Veteran (425k points)
selected by
+4 votes

Answer is A).

const char* p1 ---> This means that the string is constant . so it is stored in a read area in memory . so we cannot change its contents or edit it . Hence , if we dare to change the contents of this string , it will throw compiler error , but pointer can point to any other string .

char* const p2 ---> This means that the pointer is constant so it cannot point to any other string but if we want to change the contents of the string , we can as it is not constant .

Now, stm 3 , P1 wants to point to other string which is allowed and hence no error.

In stm 4 , P2 wants to point to other string , which results in an error .

Stm 5 is an error bcoz, P1 cannot edit the contents of constant string .

Stm 6 has no error , as P2 can change the contents of the string .

by Veteran (50.7k points)
0
Hi kapil I have a confusion here in stm 5 which is *(p1+3) = 'A'

as you said in your explanation that Stm 5 is an error bcoz, P1 cannot edit the contents of constant string .But actually here we are not editing anything

but if you see here p1 is a pointer here in which we are adding some integer *(p1+3) which is perfectly legal .and then memory address of A which is stored in memory somewhere we are assigning that address to pointer at location *(p1+3)...So why would it throw an error.
0
@shekhar sir ,

Here , P1 is a pointer which holds the base address of stm 1 string . so P1 will contain the address as it value inside it .
Now , in this base address , we add 3 take(3000 + 3 = 3003)

then *(3003) has to be given the value A, so we only change a character in this stm 1 string , which is definitely not allowed ,as it is stored in read area , we cannot write anything...
0
are we changing anything here ? I guess no see

if character pointer have a array A of string constant like this     K       A       P         I       L

                                                                                                  100     200   300     400    500

and if pointer p1 is pointing to K then then pointer *p1 =&A      it is going to get the 100

if we do p1+3 then pointer p1 going to point  3 elements beyond the first element which is 400

means no *p1 =&(A+3) right ?   now if we do *(p1+3) = "A"    .nothing wrong in it

in case of string constant only problem is we can't change the value but if a pointer pointing to it and holding the address of a location 'A' then what is wrong in it.

I am not asking to edit  or assign anything I am just asking to hold the value of some location by a pointer ...what is wrong in it ?
0
sir,

can u plz tell me the answer...?

char* p = "kapil" ;

char p[ ] = "kapil" ;

p[3] = ' p ' ;// or we can say *( p + 3) ='p'  

for both we apply this , what is the difference ?
0
first is a char pointer which points to the string constant but p will points to the starting of the array .

second one is the array of char but in this we can change any char. but not in the upper case .

there is no difference b/w p[3] ='p' and *(p+3) ='p' because starting of an array can be used as a pointer ..
0

u r right , there is not difference in writing .

The first one creates a pointer and sets it to the address of a constant string (assume in a region that does not have write protection on pages). Writing to this pointer is illegal and will probably crash. hence , we write const before it , to show that yes it is constant .

The second one creates an array and copies characters into it. Writing to this array will write to some location on stack and is perfectly legal.

Quick search syntax
tags tag:apple
author user:martin
title title:apple
content content:apple
exclude -tag:apple
force match +apple
views views:100
score score:10
answers answers:2
is accepted isaccepted:true
is closed isclosed:true
50,645 questions
56,616 answers
195,897 comments
102,355 users