C Pointer Casting

Sinduja Prakash picture Sinduja Prakash · Sep 9, 2017 · Viewed 9.5k times · Source
#include <stdio.h>
int main(void)
 {
  char *cp;
  short *sp;
  int *ip;
  short x[6];
  int i, y;
  y = 0x0102;
  for (i = 0; i < 6; i++) 
  {
    x[i] = y;
    y = y + 0x1010;
  }
  cp = (char*) x;
  printf("1) *cp = %x\n", *cp);
  sp = x;
  printf("2) *sp = %x\n", *sp);
  printf("3) cp[3] = %x\n", cp[3]);
  ip = (int*) x;
  ip = ip + 1;
  printf("A) *ip = %x\n", *ip);
  printf("B) cp[6] = %x\n", cp[6]);
  sp = sp + 5;
  printf("C) *sp = %x\n", *sp);
  *x = *cp + 2;
  printf("D) cp[1] = %x\n", cp[1]);
  return 0;
}

I do not understand how the short array is typecasted to a char, and what happens when the typecast happens. Could someone kindly help me out with this !!

Answer

J...S picture J...S · Sep 9, 2017

You declared a short array of 6 elements named x.

You assigned values into each of these elements. The initial values would be:

+------+--------+
| x[0] | 0x0102 |           
+------+--------+
| x[1] | 0x1112 |             
+------+--------+             
| x[2] | 0x2122 |             
+------+--------+             
| x[3] | 0x3132 |             
+------+--------+             
| x[4] | 0x4142 |             
+------+--------+             
| x[5] | 0x5152 |             
+------+--------+

I'm making a few assumptions here but modify them if that's not your case.

sizeof(char)  = 1 bytes
sizeof(short) = 2 bytes
sizeof(int)   = 4 bytes
Endianness    = little endian

So in memory, it would look like

+----+----+----+----+----+----+----+----+----+----+----+----+
| 11 | 10 | 9  | 8  | 7  | 6  | 5  | 4  | 3  | 2  | 1  | 0  |
+----+----+----+----+----+----+----+----+----+----+----+----+
| 51 | 52 | 41 | 42 | 31 | 32 | 21 | 22 | 11 | 12 | 01 | 02 |
+----+----+----+----+----+----+----+----+----+----+----+----+
| x[5]    | x[4]    | x[3]    | x[2]    | x[1]    | x[0]    |
+---------+---------+---------+---------+---------+---------+

where the

  • 1st row: the bytes numbers(used just for identification purposes here)
  • 2nd row: the content at the memory in hexadecimal (each 2 characters in hexadecimal represent a byte)
  • 3rd row: the index of the array x

You cast the base address of x and assign it to the char pointer cp. The printf() sees a character in *x whose size is 1 byte.

x pointed to byte 0 and so does cp but in the case of the latter, only 1 byte is considered as sizeof(char) is 1.

The content at byte 0 happens to be 0x02.

So,

cp = (char*) x;
printf("1) *cp = %x\n", *cp);

prints 2.

sp is a short pointer, the same type as x. So *sp would print the same thing as *x. It will consider the first 2 bytes from the given address. sp points to byte 0. So bytes 0 and 1 will be considered. Therefore, the value is 0x0102 which is printed by

sp = x;
printf("2) *sp = %x\n", *sp);

cp still points to byte 0. cp[3] is effectively *(cp+3). Since cp is a char pointer, cp+3 will point to 0 + 3*sizeof(char) which is 0 + 3*1 which in turn is byte 3.

At byte 3, we have 0x11 and only a single byte is considered as sizeof(char) is 1.

So,

printf("3) cp[3] = %x\n", cp[3]);

will print 11

In

ip = (int*) x;
ip = ip + 1;
printf("A) *ip = %x\n", *ip);

The integer pointer ip is assigned the base address of x. Then ip is incremented by 1. ip initially pointed to byte 0. Since ip+1 will point to byte 0 + 1*sizeof(int) which is 0 + 1*4 which in turn is byte 4.

So ip now points to byte 4. Since it is an integer pointer, 4 bytes are considered - namely bytes 4, 5, 6 & 7 the content of which is 31322122.


cp[6] means *(cp+6). cp+6 points to byte 6 the content of which is 32.

Hence,

printf("B) cp[6] = %x\n", cp[6]);

prints 32.

sp = sp + 5;
printf("C) *sp = %x\n", *sp);

sp after adding 5 to it, now points to byte 0 + 5*sizeof(short) which is 0 + 5*2 which in turn is byte 10 the content of which after considering 2 bytes (bytes 10 & 11) is 5152.

*x = *cp + 2;

*cp's value is 0x02.
*cp + 2 is 0x02 + 0x02 = 0x04 = 0x0004.
This value is assigned to the integer pointed to by *x (bytes 0 & 1).

So byte 0 is now 0x04 and byte 1 is now 0x00.

cp[1] is *(cp+1). cp+1 points to byte 1 the content is now 0x00 which is printed when

printf("D) cp[1] = %x\n", cp[1]);

is done.