A function pointer is typically implemented as the address of the code for the function's entry point, but as far as the language is concerned it's just an opaque value that can be used to call the function (and compared for [in]equality to other function pointers of the same type). It could be an index into a program-wide or system-wide table, and/or it could contain extra information.
The language does not provide a way to query the address of a statement; as far as the C standard is concerned, that concept doesn't even exist.
If you want to look at the generated machine code, you could reasonably talk about the address of the code generated for a given statement. For example, your statement
ptr = &display;
might correspond to a MOV
instruction, and that instruction probably has a (machine-level) address, though the standard language gives you no way to use that information. A goto
statement jumps to a specified statement, and it's probably implemented with an instruction that refers to the machine address of the first instruction for that statement, but the standard's description of goto
doesn't talk about it at that level of detail; it only describes the semantics.
Some compilers, including gcc, have an extension (documented here) that lets you take the address of a label. But that applies only to labelled statements.
In particular, the directive
#include <stdio.h>
is processed by an early phase of the compiler, often implemented as a separate preprocessor. It introduces a number of declarations that can be referred to by the following code. There is typically no generated code that corresponds to the #include
directive, so it's meaningless to talk about its "address".
And as PSkocik points out in a comment, code generation is not necessarily linear; there might not be any code associated with a given statement if the compiler is able to reorder it for better speed. (If you use the gcc extension to take the address of a label, then the compiler might inhibit optimization if necessary to ensure that that address is meaningful.)
As far as standard C is concerned, even if you could take the address of a given statement, the language doesn't have any constructs that would let you do anything with it; the standard goto
statement, for example, only takes a literal label name.