Good job on coming up with that example. It does a good job of showing the difference between declaring a pointer (like char *text;
) and assigning to a pointer (like text = "Hello, World!";
).
When you write:
char *text = "Hello!";
it is essentially the same as saying:
char *text; /* Note the '*' before text */
text = "Hello!"; /* Note that there's no '*' on this line */
(Just so you know, the first line can also be written as char* text;
.)
So why is there no *
on the second line? Because text
is of type char*
, and "Hello!" is also of type char*
. There is no disagreement here.
Also, the following three lines are identical, as far as the compiler is concerned:
char *text = "Hello!";
char* text = "Hello!";
char * text = "Hello!";
The placement of the space before or after the *
makes no difference. The second line is arguably easier to read, as it drives the point home that text
is a char*
. (But be careful! This style can burn you if you declare more than one variable on a line!)
As for:
int *pt;
*pt = 606; /* Unsafe! */
you might say that *pt
is an int
, and so is 606
, but it's more accurate to say that pt
(without a *
) is a pointer to memory that should contain an int. Whereas *pt
(with a *
) refers to the int inside the memory that pt
(without the *
) is pointing to.
And since pt
was never initialized, using *pt
(either to assign to or to de-reference) is unsafe.
Now, the interesting part about the lines:
int *pt;
*pt = 606; /* Unsafe! */
is that they'll compile (although possibly with a warning). That's because the compiler sees *pt
as an int
, and 606
as an int
as well, so there's no disagreement. However, as written, the pointer pt
doesn't point to any valid memory, so assigning to *pt
will likely cause a crash, or corrupt data, or usher about the end of the world, etc.
It's important to realize that *pt
is not a variable (even though it is often used like one). *pt
just refers to the value in the memory whose address is contained in pt
. Therefore, whether *pt
is safe to use depends on whether pt
contains a valid memory address. If pt
isn't set to valid memory, then the use of *pt
is unsafe.
So now you might be wondering: What's the point of declaring pt
as an int*
instead of just an int
?
It depends on the case, but in many cases, there isn't any point.
When programming in C and C++, I use the advice: If you can get away with declaring a variable without making it a pointer, then you probably shouldn't declare it as a pointer.
Very often programmers use pointers when they don't need to. At the time, they aren't thinking of any other way. In my experience, when it's brought to their attention to not use a pointer, they will often say that it's impossible not to use a pointer. And when I prove them otherwise, they will usually backtrack and say that their code (which uses pointers) is more efficient than the code that doesn't use pointers.
(That's not true for all programmers, though. Some will recognize the appeal and simplicity of replacing a pointer with a non-pointer, and gladly change their code.)
I can't speak for all cases, of course, but C compilers these days are usually smart enough to compile both pointer code and non-pointer code to be practically identical in terms of efficiency. Not only that, but depending on the case, non-pointer code is often more efficient than code that uses pointers.