-1
#include<stdio.h>
void main()
{
   int n = 2;
   printf("%c",&n);
}

Output: L

On using %d it of course gives the address of variable n but why is it outputting L on using %c?

msc
  • 33,420
  • 29
  • 119
  • 214
  • 5
    Because a pointer is not a character, so this code is **undefined behavior**. It could do anything else as well. It's a random effect on your particular environment that the part of a pointer `printf()` will evaluate when trying to get a character translates to H... –  Jul 18 '17 at 11:39
  • 2
    I can smell UB. The only thing happening is UB. – Gaurav Sehgal Jul 18 '17 at 11:39
  • 2
    Hehe, so **now** it's *suddenly* "L"? Do you feel there's something not quite right now? –  Jul 18 '17 at 11:42
  • "but why is it outputting L on using %c?" --> What did you expect? – chux - Reinstate Monica Jul 18 '17 at 15:20

3 Answers3

8

It is undefined behaviour because you have used wrong format specifier.

C11 Standard: 7.21.6.1 : paragraph 9:

If a conversion specification is invalid, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

It means anything can happen if printf is called with a wrong format specifier.

msc
  • 33,420
  • 29
  • 119
  • 214
4

As the other answer of rsp said the behaviour is undefined and anything could happen.

In your case the following happens:

It reads one byte of &n because a character is of one byte size which is mostly 8 bits long, see CHAR_BIT explanation on SO. Then it prints it as character.
This byte could be the first byte of &n if the types int* and int are the same at your machine. That would mean that your variable n lies at address 0x48... (big-endian) or 0x...48 (little-endian) as 0x48 is H in the Ascci code. I assume that your program is using Ascii for encoding which doesn't necessarily have to.
(You changed the character from H to L but I leave this answer as it is.)
Also this byte can lie somewhere in the middle of the &n if an int* exceeds the size of an int at your system.

You should compile with more warnings enabled for example -Wall in gcc and you will get:

warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]

In the case you cast that value to a char the behaviour will be well defined but rely on the implementation as a cast of a pointer type to an integer is implementation defined.

Nevertheless what you're doing makes no sense also with a cast it will not do.

Andre Kampling
  • 5,476
  • 2
  • 20
  • 47
  • 1
    still a few imprecisions (which happens easily reasoning about UB): 1.) ascii isn't mandated 2.) a `char` is **always** a byte, but a byte might have more than 8 bits 3.) with a cast, it's not undefined, but still not particularly useful because the result of the conversion of a pointer to an integer type is *implementation defined* -- still upvoted, explanations are helpful! –  Jul 18 '17 at 11:56
  • @FelixPalmen: Thank you for your explanations! – Andre Kampling Jul 18 '17 at 12:02
  • Answer assumes `int` and `int*` are the same size and an `int` and `int*` are passed to `printf()` via the same mechanism. Neither are specified in C. – chux - Reinstate Monica Jul 18 '17 at 15:03
  • @chux: I described what behaviour happened on his machine saying it is undefined. Or did I get something wrong what do you mean? – Andre Kampling Jul 18 '17 at 15:09
  • This answer does say the behavior is undefined, but then goes on to describe "In your case the following happens.", which IMO, overstates the certitude. The address could exceed the width of `int` and so the byte extracted is not the first nor the last, but potentially a "middle" one. An `int` and address may pass in different ways, thus the `L` or `H` are simply garbage - no relation to the address. Understanding various outcomes of UB is good, yet ascertaining definite behavior about UB to a leaner is not helpful. – chux - Reinstate Monica Jul 18 '17 at 15:18
  • 1
    @chux: Didn't thought about that! Thank you I will add that tomorrow. – Andre Kampling Jul 18 '17 at 15:21
-1

It's because you told printf() function to show the first 1-byte of int n's address as a char.

John Park
  • 1,644
  • 1
  • 12
  • 17