Consider the following code:
#include <stdio.h>
int ret_five() {
return 5;
}
int main() {
int x[5] = {1,2,3,4,5};
int (*p)();
p = &ret_five;
printf("%d\n", p()); // 1
p = ret_five;
printf("%d\n", p()); // 2
printf("%d\n", sizeof ret_five); // 3
printf("%d\n", sizeof &ret_five); // 4
printf("%d\n", (*p)()); // 5
printf("%d\n", (****p)()); // 6
printf("%p\n", p); // 7 // edited: replaced %d with %p
printf("%p\n", *p); // 8 // same here and in (8), (10)
printf("%p\n", **p); // 9
printf("%p\n", *******p); // 10
printf("%p\n", x); // 11
printf("%p\n", &x); // 12
return 0;
}
My questions are:
Lines (1) and (2) print the same result. Do
ret_fiveand&ret_fivehave the same data type? It seems like no, because lines (3) and (4) print different results.From a syntactical point of view, it seems to me that line (5) should be the right way to call the function that
ppoints to, but of course lines (1) and (2) print 5 just fine. Is there a technical reason for this, or was it a design decision made because the calls in (1) and (2) look cleaner? Or something else?Line (5) makes perfect sense to me (because
pis a function pointer, its dereferenced value is the function, we call the function, it returns 5, we print 5). I was very surprised to find that (6) prints 5 as well! Why is this?Similarly, lines (7)--(10) all print the same value, namely
&ret_five. Why does (10) work?Lines (11) and (12) print the same value, namely the address where the first element of
xlives in memory. Line (12) makes sense, but I don't quite understand exactly what is technically happening in line (11). Doesxautomatically get cast or interpreted as anint*in this context?To get the location in memory where
xis stored, I typically do&x[0], but it seems like&xworks just fine as well, and becausexis an array and not a pointer, it seems like in fact&xmay be the more canonical way of getting this memory address. Is there a reason to prefer one to the other?In general, are there best-practices in the above situations? For example, if
p = ret_five;andp = &ret_fivereally do the exact same thing, is there a reason to prefer one to the other?And, if the two assignments in question 7 really do the exact same thing, why, in a language that is otherwise so rigid, was this laxity built-in?