Also, why we can't use int *exp = [1,2,3]
for creating an array of integers using pointers if we can use char *exp
?
CodePudding user response:
In this declaration
char *exp="a b";
the compiler at first creates the string literal that has the array type char[4]
with static storage duration and the address of the first character of the string literal is assigned to the pointer exp
.
You may imagine that the following way
char unnamed_string_literal[4] = { 'a', ' ', 'b', '\0' };
char *exp = unnamed_string_literal;
That is in the last declaration of the variable exp
the array unnamed_string_literal
is implicitly converted to a pointer to its first element and this pointer is assigned to the pointer exp
.
You may not change the string literal. Any attempt to change a string literal result in undefined behavior.
That is you may not write for example
exp[0] = 'A';
In this declaration
char exp[]="a b";
there is created the character array exp
elements of which are initialized by elements of the string literal. You may imagine the declaration the following way
char exp[4] = { 'a', ' ', 'b', '\0' };
As the array is not declared with qualifier const
then you may change elements of the array.
On the other hand, you may not write
int *exp = { 1,2,3 };
because the construction { 1, 2, 3 } does not represent an object of an array type. You may use such a construction to initialize an array like
int exp[] = { 1, 2, 3 };
But you may not initialize a scalar object (pointers are scalar objects0 with a braced list that contains more than one expression.
However you may initialize the pointer by a compound literal that has an array type like
int *exp = ( int [] ){ 1,2,3 };
In this case the compiler creates an unnamed array of the type int[3]
and the address of its first element is assigned to the pointer exp
.
You should pay attention to these key concepts.
- Scalar objects may not be initialized by a braced list containing more than one expression.
- Array designators used in expressions with rare exceptions are converted to pointers to their first elements.
- String literals have array types.
CodePudding user response:
What is the difference between char *exp="a b"…
char *exp
declares exp
to be a pointer. When this appears inside a function, a pointer is created for the duration of execution of the block it is in. When it appears outside a function, a pointer is created for the duration of execution of the program.
It is initialized with the string literal "a b"
. When a string literal is used this way, it is automatically converted to a pointer to its first element, so exp
is initialized to point to the “a”. The string literal exists for the duration of execution of the program.
Because the pointer points to the characters of the string literal, any use of the pointer uses the string literal. The C standard does not define the behavior if you attempt to modify a string literal.
… and char exp[]="a b"?
char exp[]
declares exp
to be an array. Its duration is the same as for a pointer, above.
It is initialized by copying the string literal "a b"
into it, and the size of the string literal also determines the size of the array. An array is automatically converted to a pointer to its first element except when it is the operand of sizeof
, is the operand of unary &
, or is a string literal used to initialize an array. Since the latter is the case here, the string literal is not converted to a pointer.
Because exp
contains a copy of the string literal, you may modify exp
without affecting the string literal.
int *exp=[1,2,3]
First, [1,2,3]
is not a notation meaning an array. [
and ]
are used for subscripts, not for array contents. In initializers, we can use braces, {
and }
, for lists of initial values, but these designate only lists, not arrays.
C originally did not have an “array literal” notation like a string literal. However, later a compound literal was added to the language. You can create an object directly in source code by writing (type) { initial values }
. So you can create an array of int
with (int []) { 1, 2, 3 }
.
int *exp = (int []) { 1, 2, 3 };
will create a pointer named exp
and initialize it to point to the first element of the array. Unlike a string literal, which exists for the duration of the program, a compound literal inside a function exists only for the duration of the block of code it is in.