Home > Enterprise >  Why char* directly set the value but not in the case of int* in c programming
Why char* directly set the value but not in the case of int* in c programming

Time:06-25

There is no existence of string as a primitive data type in c language. char* make string exist. If a list of character set to an pointer like this (char *msg = "HI!") but why not in the case of pointer of type int like this (int *p = 10)?

Here is my code:

#include <stdio.h>

int main(void)
{
    char *msg = "HI!";
    int *p = 2;
    
    printf("%p\n", msg);
    printf("%p\n", &msg[0]);
    printf("%p\n", p);
}

I got an error message when I tried to compile it. Error message down below:

pointers.c:6:10: error: incompatible integer to pointer conversion initializing 'int *' with an expression of type 'int' [-Werror,-Wint-conversion]
    int *p = 2;
         ^   ~
1 error generated.
make: *** [<builtin>: pointers] Error 1

CodePudding user response:

When you say

char *msg = "HI!";

several special things are happening. First, the string literal "HI!" is treated like an anonymous array

char anonymous_array[] = "HI!";

(This treatment of string literals is one and perhaps the only way in which the C language does support the notion of a "string type".)

Second, when you attempt to use the value of this array, what you get (as you just about always do in C) is a pointer to the array's first element:

char *msg = &anonymous_array[0];

And that works well. On the other hand, when you say

int *p = 2;

nothing like that happens. If anything, this tells the compiler not that you want a pointer p pointing at the integer 2, but rather, that you want a pointer p that points at memory address 2. But your program probably doesn't have access to memory address 2, and even if it did, for a normal program, there's no way to know what's at that address, and nothing meaningful you could do with it. (If you're doing embedded programming, on the other hand, you might know that there's something interesting at that address for your particular architecture.)

If you want p to point to an integer object with the value 2, you'll need to create that integer object somehow. You could do

int i = 2;
int *p = &i;

or

int array[] = { 2 };
int *p = array;

Or — and this ends up being much closer to the way string initialization works — you can use a special syntax called a compound literal:

int *p = (int []){ 2 };

CodePudding user response:

String literals have types of character arrays. For example the string literal "HI!" has type char[4]. You can check that with this simple program

#include <stdio.h>

int main( void )
{
    printf( "%zu\n", sizeof( "HI!" ) );
}

From the C Standard (6.4.5 String literals)

6 In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals.78) The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence.

Used in expressions array designators with rare exceptions are implicitly converted to pointers to their first elements like in this declaration

char *msg = "HI!";

that is equivalent to

char *msg = &"HI!"[0];

From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)

3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

So if you had an integer array like

int a[] = { 2 };

you could write

int *p = a;
  • Related