简体   繁体   中英

Why char* can hold a single char in C?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM