in a C programming exercise I'm doing something like this (just simplifying):
printf( "%s", 0);
The output is
(null)
What happens here? I assume that printf interprets the zero as a char *, so to NULL?
How could I replicate this result by something like
char string[] = NULL; //compiler-error
printf( "%s", string);
?
Firstly, your
printf("%s", 0);
leads to undefined behavior (UB). %s in printf requires a char * pointer as argument. You are passing 0, which is an int. That alone already breaks your code, just like
printf("%s", 42);
would. For that specific UB the fact that 0 is a zero does not make any difference.
Secondly, if you really want to attempt to pass a null-ponter to %s format specifier, you have to do something like
printf("%s", (char *) 0);
Of course, this leads to undefined behavior as well, since %s requires a pointer to a valid string as argument, and (char *) 0 is not a valid string pointer. But some implementations prefer to handle such situations gracefully and just print (null).
In your particular case you just got lucky: printf("%s", 0) "worked" the same way as printf("%s", (char *) 0) would and your implementation saved the day by outputting (null).
As others have noted, passing a null pointer to printf %s is not guaranteed to do anything. Everything else being equal, we would expect a segmentation violation or other ungraceful crash, as printf attempts to dereference the null pointer. As a convenience, however, many (most?) implementations of printf have, somewhere deep within them, the equivalent of
case 's':
char *p = va_arg(argp, char *);
if(p == NULL) p = "(null)";
fputs(p, stdout);
You can also do this using something like:
char *string = NULL;
printf("%s", string);
Many implementations of printf() will print (null) or something similar when passed a NULL pointer to %s. But they don't have to do that (it's not required by the standard).