Michael
Michael

Reputation: 585

what does the output of this code mean? printf("%d", "x");

Here is the full code

#include<stdio.h>

int main(void) {

    printf("%d", "x");

    getchar();
    return 0;
}

The output is 15620184. Logically is should return the numeral value of the string "x". But x itself is not a string.

Upvotes: 1

Views: 7226

Answers (4)

John Bode
John Bode

Reputation: 123488

Essentially, you're attempting to print the address of the string literal "x" as a decimal integer, which isn't guaranteed to work.

The expression "x" has type "2-element array of char"; since the expression is not the operand of the sizeof or unary & operators, it is converted ("decays") to an expression of type "pointer to char", and the value of the expression is the address of the first character of the string.

The d conversion specifier expects its corresponding argument to have type int; you're passing an argument of type int *, so the behavior is undefined. The output may be an accurate representation of the address value as a decimal integer, or it may be total garbage.

Types matter, and specific conversion specifers expect their corresponding arguments to be of a specific type (adapted from Harbison & Steele, § 15.11.7):

Output Format     Specifier        Argument Type
-------------     ---------        -------------
Decimal Integer     hhi,hhd                 char
 (Signed)             hi,hd                short
                        i,d                  int
                      li,ld                 long
                    lli,lld            long long
                      zi,zd               size_t
                      ti,td            prtdiff_t
                      ji,jd             intmax_t

Decimal Integer         hhu                 char
 (Unsigned)              hu                short
                          u                  int
                         lu                 long
                        llu            long long
                         zu               size_t
                         tu            prtdiff_t
                         ju             intmax_t

Octal Integer           hho         unsigned char
                         ho        unsigned short
                          o          unsigned int
                         lo         unsigned long
                        llo    unsigned long long
                         zo                size_t
                         to             ptrdiff_t
                         jo              intmax_t

Hexadecimal         hhx,hhX         unsigned char
 Integer              hx,hX        unsigned short
                        x,X          unsigned int
                      lx,lX         unsigned long
                    llx,llX    unsigned long long
                      zx,zX                size_t
                      tx,tX             ptrdiff_t
                      jx,jX              intmax_t

Decimal Float          f,lf                double 
                         Lf           long double

Decimal Float,    e,E,le,lE                double
 Exponential          Le,LE           long double     
 Notation           

Decimal Float,    g,G,lg,lG                double
 Same as f or         Lg,LG           long double
 e depending on 
 value

Hexadecimal       a,A,la,lA                double
 Float                La,LA           long double

Single Character          c                   int
Single Wide Character    lc                wint_t

String                    s                char *
Wide String              ls             wchar_t *

Pointer Value             p                void *

Note that the representation of a pointer value is implementation-defined. Most platforms you're likely to work on will output an integral value in hex notation. Some may output the string "null" for a NULL pointer. Some may use a completely different representation.

Note that, to print a pointer value, you should explicitly cast the argument to void * if it isn't already:

printf( "%p\n", (void *) "x" );

This is probably the only place in C where you need to explicitly cast a pointer value to void *.

Upvotes: 2

jcoder
jcoder

Reputation: 30035

I want to make it clear as other have said that this code is wrong because it has undefined behavior so could do absolutely anything on your platform. Don't do this... However to aid understanding :-

"x" is a string constant and this decays to a pointer to the string and passed as a parameter to printf. You've asked it to print an "int" so it interprets the bytes of the address as if they were an int and prints those.

In practice this will print the address that the string is stored at as a decimal number.

But nothing in the standard guarantees this, it could do anything, and is likely to differ on other platforms. In general though, due to the way C is implement though in most cases it will do what I've described.

Note than on some 64 bit platforms an int is 32 bits but an address is 64 bits so this is likely to at best only print an integer based on half the bytes of the address.

As others have said it's undefined and bad so don't do this, but it's still useful to understand what it's actually doing.

Edit: As suggested... If you want to interpret the data passed properly use %p instead of %d which tells printf to interpret the data passed as a memory address rather than an int. Although the format is system dependent it's likely to be print the same int, and is properly defined behavior then

Upvotes: 9

abhiarora
abhiarora

Reputation: 10430

what does this code do? printf(“%d”, “x”);

The code will have undefined behavior. The code you have pasted will give warning. Have a look at the warning that i have got by compiling your code with gcc.

warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat=]
  printf("%d", "x");

You can get to know after looking at the above warning that in place of "x" you should pass a variable or constant of type int but you have passed a pointer to null-terminated character array (which is "x"). It is because you have specified a format specifier which is "%d" in your printf function which requires a int data type variable or constant.

Logically is should return the numeral value of the string "x"

To print the numerical value of variable of type char or character constant ('x'), use printf as

printf("%d", 'x'): //Remeber character literal in c are stored as int

To print the character array "x", use printf as

printf("%s", "x"); //OR
printf("x");

To print the address stored in a pointer, you must use "%p" format specifier as

printf("%p", "x");

There are many format specifiers in c. Few are given below-

%c - For Character Variable
%d - For Integers
%f - For Double
%s - For Null-Terminated Character Array
%p - For Pointers (of void * type)

Upvotes: 4

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53006

This code is "UNDEFINED BEHAVIOR", you should never use it, to print a string of characters you MUST use "%s" as the specifier, to print the address stored in a pointer you MUST use "%p" and cast the pointer to void *, example

printf("%p\n", (void *) "x");

ALWAYS add a trailing "\n" character to printf() to flush the output buffer, that's only unnecessary with stderr, but it's still good to develop the habit.

Also, "x" IS a string, and if you want the ascii value of 'x' the character then, this

printf("%d\n", 'x');

note the single quotes.

Please read print(3), and learn about the many specifiers handled by printf() and family.

Upvotes: 7

Related Questions