When you wrote
char letter;
printf("%p\n", &letter);
you declared a variable called letter
. It has a well-defined location (or address). The only thing we don't know is which char
value is in it -- that's either indeterminate or undefined, depending on who you ask. So if you had tried to do printf("%c\n", letter)
, that might have gotten you into trouble, because that would try to print the undefined/indeterminate value.
But when you wrote
char *letter1;
printf("%p\n", letter1); //program crashes
that's completely different. letter1
is a variable of type pointer-to-char
. As before, it has a well-defined location, and an indeterminate initial value. But what's confusing here is that the value it doesn't have is (or would be) also an address.
If you wrote
printf("%p\n", &letter1);
you'd print the address of letter1
, and as I said, that's well-defined. But you tried to print
printf("%p\n", letter1);
and there you try to print the address in letter1
, which is a much bigger problem.
(I wouldn't expect an actual crash, though -- in practice I'd merely expect a "random value". I wouldn't expect a crash unless you tried to do printf("%c\n", *letter1)
.)
One more thing: Taking the address of an uninitialized variable can't be undefined, because plenty of well-defined programs do just that!
Taking an address of an uninitialized variable and passing it to a function can be a good way of assigning a value to a variable. If you have a function that returns a value "by reference", you're probably going to pass it the address of a variable, and it will often be uninitialized, like this:
char *p;
int n = strtol("23skidoo", &p, 10);
printf("%d %s\n", n, p);
Footnote: I wrote that the initial value was "either indeterminate or undefined, depending on who you ask", and that alludes to a tremendous subtlety which I only learned about a couple of days ago, which is that the indeterminacy/undefinedness of the initial values of local variables like these can evidently depend on whether they do or might have their addresses taken. There's sort of a Heisenberg -- or maybe Schrödinger -- uncertainty principle here, where the behavior depends on how closely you attempt to observe it. If your program actually did crash when you tried to print the value of letter1
, it might not crash if you changed it to printf("%p %p\n", &letter1, letter1);
.