2

I wrote the following program,

#include<stdio.h>
int main(void)
{
int i='A';
printf("i=%c",i);
return 0;
}

and I got the result as,

i=A

So I tried another program,

#include<stdio.h>
int main(void)
{
int i='ABC';
printf("i=%c",i);
return 0;
}

According to me, since 32 bits are used to store an int value and each of 'A', 'B' and 'C' have 8 bit ASCII codes which totals to 24 bits therefore 24 bits were stored in a 32 bit unit. So I expected the output to be,

i=ABC

but the output instead was

i=C 

and I can't understand why?

  • 4
    `"%c"` will never print 3 characters. – Bo Persson Dec 12 '17 at 13:06
  • Did you turn on the compiler warnings? Did your compiler not cry __at all__? – Ajay Brahmakshatriya Dec 12 '17 at 13:06
  • The 'A' notation is for specifying a single character. 'ABC' is 3 characters, what happens when you specify more than 1 character in a a character literal notation is non-standard and will depend on your particular compiler. What happens could also be undefined behavior. However - you should tell us which compiler you use. – nos Dec 12 '17 at 13:07
  • 1
    read the warnings. They'll tell you about the [multi-character constant](https://stackoverflow.com/q/7755202/995714) https://stackoverflow.com/q/6944730/995714 – phuclv Dec 12 '17 at 13:25
  • @Useless C does not specify any _character literal_. `'ABC'` is an _integer character constant_, one containing more than one character. – chux - Reinstate Monica Dec 12 '17 at 14:23
  • @nos The C standard specifies code like `'ABC'` as an _integer character constant_. It _is_ standard. The value it represents is is implementation-defined. – chux - Reinstate Monica Dec 12 '17 at 14:26

5 Answers5

1

'ABC' in this case is a integer character constant as per section 6.4.4.4.10 of the standard.

An integer character constant has type int. The value of an integer character constant containing a single character that maps to a single-byte execution character is the numerical value of the representation of the mapped character interpreted as an integer. The value of an integer character constant containing more than one character (e.g.,'ab'), or containing a character or escape sequence that does not map to a single-byteexecution character, is implementation-defined. If an integer character constant contains a single character or escape sequence, its value is the one that results when an object with type char whose value is that of the single character or escape sequence is converted to type int.

In this case, 'A'==0x41, 'B'==0x42, 'C'==0x43, and your compiler then interprets i to be 0x414243. As said in the other answer, this value is implementation dependent.

When you try to access it using '%c', the overflown part will be cut and you are only left with 0x43, which is 'C'.

To get more insight to it, read the answers to this question as well.

Weijun Zhou
  • 746
  • 1
  • 7
  • 25
  • 1
    Technically it is _not_ non-standard... it does is implementation dependent but it clearly is part of the standard. see section [6.4.4.4.10](http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf) – sidyll Dec 12 '17 at 13:19
  • 1
    The standard doesn't specify those values for A, B, and C either – Bathsheba Dec 12 '17 at 13:27
  • 1
    Thank you. I am happy that I can always learn something from SO not just when I ask questions but also when I answer questions. – Weijun Zhou Dec 12 '17 at 13:33
1

The conversion specifier c used in this call

printf("i=%c",i);

in fact extracts one character from the integer argument. So using this specifier you in any case can not get three characters as the output.

From the C Standard (7.21.6.1 The fprintf function)

c If no l length modifier is present, the int argument is converted to an unsigned char, and the resulting character is written

Take into account that the internal representation of a multi-byte character constant is implementation defined. From the C Standard (6.4.4.4 Character constants)

  1. ...The value of an integer character constant containing more than one character (e.g., 'ab'), or containing a character or escape sequence that does not map to a single-byte execution character, is implementation-defined.
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

'ABC' is an integer character constant. Depending on code set (overwhelming it is ASCII), endian, int width (apparently 32 bits in OP's case), it may have the same value like below. It is implementation defined behavior.

'ABC'
0x41424300
0x434241
or others.

The "%c" directs printf() to take the int value, cast it to unsigned char and print the associated character. This is the main reason for apparent loss of information.

In OP's case, it appears that i took on the value of 0x434241.

int i='A';
printf("i=%c",i); --> 'A'
// same as 
printf("i=%c",0x434241); --> 'A'
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

In C, 'A' is an int constant that's guaranteed to fit into a char.

'ABC' is a multicharacter constant. It has an int type, but an implementation defined value. The behaviour on using %c to print that in printf is possibly undefined if the value cannot fit into a char.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • @chux: Yes it's not the first time you've called me out on my sloppy terminology; in this area particularly. – Bathsheba Dec 12 '17 at 14:37
  • `printf` will expect an `int` parameter to match the `%c` format specifier, and will convert the `int` value to an `unsigned char` value. None of that is undefined behaviour, but the output will be implementation defined because the `int` value is implementation defined. – Ian Abbott Dec 12 '17 at 14:38
0

if you want i to contain 3 characters you need to init a array that contains 3 characters

char i[3]; i[0]= 'A'; i[1]= 'B'; i[2]='C';

the ' ' can contain only one char your code converts the integer i into a character or better you store in your 32 bit intiger a converted 8 bit character. But i think You want to seperate the 32 bits into 8 bit containers make a char array like char i[3]. and then you will see that

int j=i;

this will result in an error because you are unable to convert a char array into a integer.

MoJoWi
  • 3
  • 4