This might sound too crazy but I just had a thought. In C why
char *pc = 'H'; // single character
char *ps = "hello"; // a string
both are valid? I mean why a char*
can hold/refer a character as well as a null terminated string?
Why there are no guard clause or compiler error generated for *pc
as that char*
is not holding a null terminated string?
I checked it in Ideone and don't get any warning.
It can hold a char
because there is an implicit conversion from char
to char *
(via int
), and because sizeof(char *) >= sizeof(char)
. You shouldn't do this, though (technically it is undefined behavior because the literal numeric value of a character is not likely to be a valid pointer address to a char
type).
And in many/most compilers, this does generate a warning:
$ gcc -otest test.c
test.c:5: warning: initialization makes pointer from integer without a cast
In
char *pc = 'H';
'H'
as an int
will be casted to a char *
and will be used to initialize pc
, compiler should give a warning about this.
In
char *ps = "hello";
"hello"
will evaluate to its base address, which will be used to initialize ps
.
char *pc = 'H';
The above statement defines pc
of type char *
which means it can hold the address of an object of type char
. You are initializing it with the character H
- a different type. Remember that a character literal is of type int
and evaluates to its character code which in ASCII is 72
. So, the above statement is equivalent to
char *pc = 72;
This is an illegal operation and compiler should warn you about it (in gcc, use the flag -Wall
). You should not directly assign an address to a pointer because you don't know if you have access to the memory address. You should use the address of
operator &
to get the address of an object and then assign it to a pointer.
char *ps = "hello";
In the above statement, the string literal evaluates to a pointer to its first element. This address is assigned to ps
which is of the same type, ie, char *
. However, string literals are read-only in C
but are not const
qualified (unlike in C++
) and thus attempting to modify the string literal using the pointer ps
would not result in compiler error but undefined behaviour and most likely program crash due to segfault. Therefore, you should define ps
as a pointer to a const object
-
const char *ps = "hello";
When I compile the above lines of code using g++, I get the following warning:
test-12.c:1:12: warning: initialization makes pointer from integer without a cast [enabled by default]
The compiler is performing a few automatic casts to initialize pc
.
char
-> int
-> char*
.
One just have to pay attention to the compiler warnings to detect unusual operations like you are attempting.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.