Here are two very simple programs. I would expect to get the same output, but I don’t. I can’t figure out why. The first outputs 251. The second outputs -5. I can understand why the 251. However, I don’t see why the second program gives me a -5.
PROGRAM 1:
#include <stdio.h>
int main()
{
unsigned char a;
unsigned char b;
unsigned int c;
a = 0;
b= -5;
c = (a + b);
printf("c hex: %x\n", c);
printf("c dec: %d\n",c);
}
Output:
c hex: fb
c dec: 251
PROGRAM 2:
#include <stdio.h>
int main()
{
unsigned char a;
unsigned char b;
unsigned int c;
a = 0;
b= 5;
c = (a - b);
printf("c hex: %x\n", c);
printf("c dec: %d\n",c);
}
Output:
c hex: fffffffb
c dec: -5
There are two separate issues here. The first is the fact that you are getting different hex values for what looks like the same operations. The underlying fact that you are missing is that
chars are promoted toints (as areshorts) to do arithmetic. Here is the difference:Here,
ais extended to0x00000000andbis extended to0x000000fb(not sign extended, because it is an unsigned char). Then, the addition is performed, and we get0x000000fb.Here,
ais extended to0x00000000andbis extended to0x00000005. Then, the subtraction is performed, and we get0xfffffffb.The solution? Stick with
chars orints; mixing them can cause things you won’t expect.The second problem is that an
unsigned intis being printed as-5, clearly a signed value. However, in the string, you toldprintfto print its second argument, interpreted as a signed int (that’s what"%d"means). The trick here is thatprintfdoesn’t know what the types of the variables you passed in. It merely interprets them in the way the string tells it to. Here’s an example where we tellprintfto print a pointer as an int:When I run this program, I get a different value each time, which is the memory location of
a, converted to base 10. You may note that this kind of thing causes a warning. You should read all of the warnings your compiler gives you, and only ignore them if you’re completely sure you are doing what you intend to.