1

I'm recollecting my C programming skills after 1 year. So I decided to start from scratch. I got stuck with poineters

why i can do :

char *string="Hello";
printf ("%s",string);

But i can't do :

int *pt=23;
printf("%d",*pt);

Doesn't the pointer need to be an address ? but why the first example works?

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
Marià
  • 255
  • 2
  • 12
  • The line `int *pt=23;` will cause the pointer to point to the address 23 (which is most likely an invalid address). It will **not** cause the pointer to point to an `int` whose value is `23`. If you want to do that, then you must write `int i = 23; int *p = &i;` – Andreas Wenzel Feb 15 '21 at 14:08
  • and why char *string="Hello"; insted it works ? – Marià Feb 15 '21 at 14:11
  • `"Hello"` is a string literal, that is a pointer `to char`. But `23` is not a pointer to `int`. – Jabberwocky Feb 15 '21 at 14:11
  • @AndreasWenzel No that's not correct, `int *pt=23;` isn't valid C. The compiler will produce a diagnostic for a language constraint violation. – Lundin Feb 15 '21 at 14:11
  • @Lundin: Both the `gcc` and `clang` compiler accept that line, even if I compile with `-pedantic -std=c11`. All I get is a warning in both cases. – Andreas Wenzel Feb 15 '21 at 14:19
  • @AndreasWenzel Yeah you got a warning so the compiler did _not_ accept the code. [What must a C compiler do when it finds an error?](https://software.codidact.com/posts/277340) – Lundin Feb 15 '21 at 14:21
  • @Lundin: You are right. I should have used `-pedantic-errors` instead of only `-pedandic` to get the compiler to behave as I expect. Thanks for pointing it out. – Andreas Wenzel Feb 15 '21 at 17:50

5 Answers5

2

Because using string literals to initialize a character pointer or array is a special allowed syntax, with specific rules. In your case you set a pointer to point at a string literal's address, the string literal itself having type char[] and existing in read-only memory.

For the integer case, yes it needs to be an address, or more specifically another integer pointer. You can't initialize a pointer with an integer. See:
"Pointer from integer/integer from pointer without a cast" issues

Lundin
  • 195,001
  • 40
  • 254
  • 396
2

The string literal "Hello" is stored in memory as a character array like

char unnamed_literal[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

So in this declaration

char *string="Hello";

the pointer string is assigned with the address of the first character of the already existent array. It can be imaging like

char unnamed_literal[] = { 'H', 'e', 'l', 'l', 'o', '\0' };
char *string = unnamed_literal;;

As for this declaration

int *pt=23;

then the value 23 is not a valid address that points to a valid object defined in your program. The compiler should issue a message that you are trying to assign an integer to a pointer. Thus this call

printf("%d",*pt);

invokes undefined behavior.

To make an analogy with the initialization of a pointer by string literal you could write for example

int a[] = { 1, 2, 3 };
int *pt = a;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 1
    `int *pt=23;` already invokes undefined behavior since it's a constraint violation and invalid C. – Lundin Feb 15 '21 at 14:18
  • @Lundin A pointer may have an invalid value. – Vlad from Moscow Feb 15 '21 at 14:20
  • `23` is not a pointer, it is as integer arithmetic type, which in turn is not one of the valid right operands during simple assignment when the left operand is a pointer type. – Lundin Feb 15 '21 at 14:24
  • 6.5.4/3 is relevant to the discussion: _Conversions that involve pointers, other than where permitted by the constraints of 6.5.16.1, shall be specified by means of an explicit cast._ – Ian Abbott Feb 15 '21 at 14:28
  • @Lundin Assigning pointer with integer without (or with) the cast is not an UB. UB can be potentially inveked when this assignment results in the invalid pointer value and this pointer is used. Most low level hardware related software is written this way. – 0___________ Feb 15 '21 at 14:32
  • After some consideration, I don't think it is UB because the "shall" requirements being violated are within the "constraint" sections. The compiler is required to produce a diagnostic. The resulting pointer value might be a trap representation. – Ian Abbott Feb 15 '21 at 15:04
  • 1
    @0___________ I'm not going to explain this FAQ to every single person in the comment fields, just read the answer I posted and most importantly the link in it. [This](https://stackoverflow.com/questions/52186834/pointer-from-integer-integer-from-pointer-without-a-cast-issues). – Lundin Feb 16 '21 at 09:13
1

This is syntaxic sugar from standard C:

What is actually stored in your char pointer is the address at which the string is loaded in memory when starting the program.

For an integer however, it will try to set the address of the pointer to 23 which is (and should be) invalid.

Adalcar
  • 1,458
  • 11
  • 26
0

For example an integer, like:

int VAL = 10;

int *ptr = &VAL; /* ptr now points to val */

*ptr = DESIRED_VALUE; /* *(asterisk) here means dereference, meaning that the value of VAL will change */

or

int *&VAL = DESIRED_VALUE;
alex01011
  • 1,670
  • 2
  • 5
  • 17
0
    int variable_1 = 23;
    int *pointer_to_int = &variable_1;

The first line is an integer variable, initialized to an integer value.

The second line is a pointer to integer variable, initialized to an address of an integer variable (the address of the variable variable_1, defined in the previous declaration.

    char *p = "Charles Dickens";

This is a char pointer variable, initialized to the address of a string literal, which is a constant array of characters, composed of the characters between the quotes, plus an aditional \0 character, that represents the end of the string literal.

    char c = 'a'; /* char variable initialized to value 'a' */
    char *pointer_to_c = &c;

Probably you will find this last declaration very similar to the one above. The different thing is that in C you can use string literals, but a single character is similar to an integer, and this is the way pointer variables initialize: with variables addresses.

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31
  • so "hello world" is seen as an address? – Marià Feb 17 '21 at 15:20
  • a string literal is indeed an array of chars, it is normally referenced by a pointer. If you declare an array, it's name alone actually means _the address of the first element_ of the array. So a string literal, as an unnamed array, is accessed as an array, and the literal by itself, when used in an expression means the same: _the address of the first element_ – Luis Colorado Feb 18 '21 at 11:59