-2

I am vastly confused. I'm having a headache. I'm new to C.

#include<stdio.h>

int main()
{
int i = 257;
int *iPtr = &i;    

printf("val 1: %d \t val 2: %d \n\n",*( (char*)iPtr ), *( (char*)iPtr+1) );

int iptr_alias = iPtr;
int and_val = iptr_alias & 255;

printf("Value of iPtr (aka address of i): %d   \n\n", iPtr);
printf("Value at location pointed to by iPtr using %%c: %c \n\n",*iPtr); //gives weird character


int f = 257;
int *fptr = &f;


printf("char starred fptr: %d \t charred 257: %d \n\n",*((char*)fptr), ((char)257) );
// i know the above is obvious. 
system("PAUSE");
}

My questions:

1. Apparently *( (char*) iPtr ) = 257 & 255 = 1 (bitwise and operation). And (char)*iPtr is the same also . But it doesn't print 1 if i use %c modifier. Why?

2. And why *( (char*) iPtr+1 ) = 1 ??

I'm so confused with all this (which i wrote myself to clear confusion, but it worked otherwise..)

((char)257) gives 1 using %d or %o or %x for that matter. %c gives some weird ASCII character

I mean, when i do printf(" %c ", 257) , then i don't get 1, instead, I get a weird ASCII character. Why?

In the actual problem, I was supposed to determine what would be printed as val 1 and val 2.

I maybe overlooking anything stupidly simple, but i'm really feeling confused and tired about this mess. Please help.

Tony K
  • 61
  • 3
  • 10
  • Are you asking why you get an ascii character with `%c`? Do you understand the difference between `%c` and `%d`? – Alex Hart Sep 25 '12 at 16:58
  • printf("%c", 32) shows the ascii character. take a look at the ascii table, so you see what characters have which number. %i, %d etc format the values as a string, and then print the number. – user287107 Sep 25 '12 at 17:19
  • no, i'm confused as to why `printf("%d", ((char)257) )` gives `1` whereas `printf("%d",257)` gives 257. Now obviously `(char)` is changing things, and now as i understand, ((char)257) (thanks to Joachim Pileborg) gives 1 because `Remember that a char is only 8 bits, and can therefore represent number from 0 to 255. When you print 257 it rolls over and becomes 1 (256 would be zero).` – Tony K Sep 25 '12 at 17:26

2 Answers2

1

Remember that a char is only 8 bits, and can therefore represent number from 0 to 255. When you print 257 it rolls over and becomes 1 (256 would be zero).

As for why why 257 (i.e. 1) becomes a weird character, I direct you to an ASCII table.

Edit: About signed versus unsigned

In this case, your char type is unsigned. If it were signed then the rollover would have happen at 127 (but due to how signed/unsigned works it would have roll over to -128 and 129 would roll over to -127).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    in this case `char` is unsigned. That's not always true. – rubenvb Sep 25 '12 at 17:03
  • @Joachim Pileborg i'm still confused about `*( (char*) iPtr+1 ) = 1` wouldn't it be 2? – Tony K Sep 25 '12 at 17:34
  • @TonyK That is _undefined behavior_, see my modified answer. – Some programmer dude Sep 25 '12 at 17:43
  • @TonyK, I don't really think that's undefined behavior, I've been told that conversions to/from `char*` are actually well defined. The reason you get `1` can be found in my answer. – Mark Ransom Sep 25 '12 at 18:17
  • Re your Edit 2, `*((char*)iPtr + 1)` is only undefined behaviour if `sizeof(int) == 1` (but then `CHAR_BIT >= 16`, so `(char)257` would yield 257). If `sizeof(int) > 1`, that gives you the second-lowest-addressed byte of the `int i;`, which in little-endian systems is 1, in big-endian systems would be 0 (like the lowest-addressed byte you'd get from `*((char*)iPtr)`). – Daniel Fischer Sep 25 '12 at 22:24
1

The integer 257 is also 0x101 in hex. On a little-endian machine with 32-bit integers the individual bytes will be 0x01 0x01 0x00 0x00.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622