Let's go through each of your questions one by one.
Printing
In your first code snippet, you show that printf
is capable of printing strings. Of course it printed a string. You gave it a %s
which is meant to be a string. But first, what is a string? To explain that, we need to understand arrays and chars.
What's a String?
First, what's a char
? A char
is a singular character (or an 8-bit number, but for our purposes it's a character). A character can be a letter (a
, b
, c
)m or any other symbol (?
, !
, .
, numbers, there are also some control characters). Typically, if you only needed one character, you'd declare it like this:
char letter_a = 'a';
So what is an array? An array is a group of values all next to each other. Consider the following code:
int int_array[] = int[50];
int_array[0] = 1;
int_array[1] = 2;
...
In this example, what is int_array
? The answer seems obvious. It's an array. But there's more to it than thar. What if we do this?
printf("%d\n", *int_array);
It prints out 1
. Why? Because int_array is actually just a pointer to the first element of the array.
So why am I talking about arrays? Because a string is just an array of characters. When you run char* string = "Hello!"
, you just create an array that looks like this: ['H', 'e', 'l', 'l', 'o', '!', '\0']
. C knows that the string has ended once it reaches the null symbol ('\0'
).
In your first snippet, var is a pointer to the letter 'H', and the print statement keeps printing characters until it reaches null.
What about the second snippet?
%d
doesn't dereference the variable like %s
does. It just prints a number as a signed integer. The integer in this case is the memory address of your integer.
Why cant you assign pointers?
You can. You'll get a warning, and it will probably cause a segmentation fault, but you can try it. I compiled your code example using clang and this is what I got:
test.c:1:1: warning: return type of 'main' is not 'int' [-Wmain-return-type]
void main() {
^
test.c:1:1: note: change return type to 'int'
void main() {
^~~~
int
test.c:2:7: warning: incompatible integer to pointer conversion initializing 'int *' with an expression of type 'int' [-Wint-conversion]
int* var = 5;
^ ~
2 warnings generated.
I will not dare try to run it though. Basically what you just did is try to access the fifth location in memory, which is most likely some OS stuff. You don't have access to that
Why did it work for the string?
Because it doesn't point to a specific location. It points to the location of the string that C made for you. Your code is roughly equivalent to this:
char h = 'H';
char e = 'e';
...
char* var = &h;