search
Log In
3 votes
333 views

What is the answer?

How char *const  and const char* differ 

in Unknown Category 333 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. 


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 .

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.

Related questions

2 votes
3 answers
2
0 votes
0 answers
3
64 views
Can i access array like this: const int array [5]= {10,20,30,40,50}; int *x; x=array+5; *x=6; // can i assign this value as x is pointing to some unknown location. and other array is constant. x=array+2; *x=2; // can i assign if array is constant. in both assignment any compiler error would be there ????
asked Dec 28, 2017 in Programming nitin_kumar 64 views
0 votes
0 answers
4
124 views
The output of below code is_______________. int main() { int i = 120; int *a = &i; foo(&a); printf("%d ", *a); printf("%d ", *a); } void foo(int **const a) { int j = 210; *a = &j; printf("%d ", **a); }
asked Nov 18, 2017 in Programming Hira Thakur 124 views
...