1

I have following code

int main()
{
    int arr[3] = {2, 3};
    char *p;
    p = arr;
    p = (char *)((int*)(p));
    printf("%d, ", *p);
    p++;
    p = (int*)(p+1);
    printf("%d", *p);
    return 0;
}

o/p-2,0

but I want to know how it is printing 0 in second printf ,I know all stuffs about little-endian as in memory of 4 byte integer how these elements are stored, as follows

00000010 00000000 0000000 00000000 00000011 00000000 00000000 00000000

so, during the first printf we got 2 as answer but during second printf the pointer is at second byte which is 0 but it is now a integer pointer but how it is printing 0,as it has to check for upto 4 bytes of memory then it has to print the whole data upto 4 byte. I thought will be 3 as upto 4 byte it will print.

what i want is how the integer data is printing by printf,can any one tell this.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
pradipta
  • 1,718
  • 2
  • 13
  • 24
  • 2
    p always remains a char pointer! – Luca Oct 01 '12 at 07:41
  • Thanks for your answer,but then what is the use of (int *) there.kindly tell . – pradipta Oct 01 '12 at 07:42
  • The (int*) cast is unnecessary (wrong?), since p and p+1 are already assignment compatible. In particular, it even emits a warning ("assignment from incompatible pointer type"). It would be necessary if you had something like `int* i; ... i = p + 1;` – Andreas Fester Oct 01 '12 at 07:47

3 Answers3

3

The type of the pointer p does not change with either of the two: p = (char *)((int*)(p)); p = (int*)(p+1);.

It still remains a pointer to a char.

The cast only works to alter values (or types) in expressions. It applies to copies of values extracted from variables but does not modify those variables. Once the expression is over, the cast is gone with the value copy it was associated with.

Example:

signed char c = -1;
int i;
i = (unsigned char)c;

Here the value of c, -1, is converted/cast to the type unsigned char. If chars are 8-bit, the result of (unsigned char)-1 is 255 and this value is of type unsigned char, which then gets converted to int and assigned to i.

c does not change anyhow in the above process.

Example 2:

unsigned u = 0x55AA;
unsigned* pu = &u;
unsigned char* pc = (unsigned char*)pu;

Here pu is converted/cast to type pointer to unsigned char. That conversion does not modify the variable pu, it only changes a copy of its value. And here it just changes the type of the copy, not the actual address, contained in the pointer variable. And then this copy of the address is assigned to pc. The cast is needed to avoid compiler warnings/errors, because the compiler has all the rights to "wonder" what is going on here and if there might be a programming mistake.

Now both pu and pc point to the same location, the beginning of the variable u. But they have different types, one points to an unsigned char and the other, to an unsigned int.

And so if you dereference pu and pc, you'll get different values and those will be of different types as well.

Likewise, if you do pointer arithmetic on the two pointers, for example, adding 1 to each, they will advance to point to different locations in memory. pu+1 will point to the location right after the end of u and pc+1 will point to the 2nd unsigned char from the beginning of u.

Are you starting to see it?

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • Thanks for the answer but can I know what is the use of type cast then. – pradipta Oct 01 '12 at 08:21
  • Thanks for your clear explanation,I gone through the ISO standard for the casting but I am not able to catch all the stuff there.can you suggest something like that standard, where I can get the things little bit simpler and clear. – pradipta Oct 01 '12 at 09:20
  • 1
    The standard is not an easy read and should not be among the first sources to learn from. Look up SO for good/recommended C/C++ books. Somewhere there's a big post listing those. Wait, [here it is](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list). – Alexey Frunze Oct 01 '12 at 09:35
3

I think your basic problem is actually a error in the code,you say that 'during second printf the pointer is at second byte' but this is not true. You first increment the pointer with p++ (now it points at the second bytes) then you increment AGAIN with the p=(int *)(P+1) leaving p pointing at the THIRD byte.

It seems to me that you don't really understand how the type conversions work, as far as I can tell removing all the type casting doesn't change the functionality of this code at all.

Elemental
  • 7,365
  • 2
  • 28
  • 33
  • I got the same result.What actually happening here even if it is pointing to the third byte result is same and always saying 0. – pradipta Oct 01 '12 at 08:17
0

I think for 2, it is stored as '00000010 00000000 0000000 00000000'. Since p is a char pointer, when p increases it, it means p moves forward 2 bytes. And for the code, 'p = (int*) (p+1), when p increases one, p is a char pointer. So that, after p + 1, p pointed to '0000000 00000000'. So the second printf will print 0.

  • Thanks for your answer but 'Since p is a char pointer, when p increases it, it means p moves forward 2 bytes' I do not think this is correct as char is 1 byte it will forward only one byte. – pradipta Oct 01 '12 at 08:20