By sachin sarwesh


2018-08-10 12:10:51 8 Comments

What is the output of following program written in C?

Is it 2 0 or 0 2, and why?

int main()
{
    int arr[]={2,3,4};  // predefined pointer
    char *p;
    p=(char *)arr;

    printf("%d\n",*p);
    printf("%p\n",p);
    p=p+1;

    printf("%d\n",*p);
    printf("%p\n",p);

    return 0;

}

2 comments

@dbush 2018-08-10 12:27:57

The result depends on the endianness of your system as well as the size of an int (it also depends on the number of bits in a byte, but for now we'll assume it's 8).

Endianness dictates the ordering of bytes in types such as integers. x86 based processors are little-endian, meaning that the least significant byte is first, while others are big-endian meaning the most significant byte is first.

For example, for a variable of type int with the value 2, and assuming an int is 32 bit, the memory on a big-endian system looks like this:

-----------------
| 0 | 0 | 0 | 2 |
-----------------

While on a little-endian system it looks like this:

-----------------
| 2 | 0 | 0 | 0 |
-----------------

Moving on to what happens when you take a char * and point it to an int (or a member of an int array). Normally, using a pointer to one type to point to another type and read the value though the other pointer is a strict aliasing violation which invokes undefined behavior, however the C standard has an exception for character types to allow you to access the bytes in an object's representation. So in this case it's allowed.

When you do this:

p=(char *)arr;

It causes p to point to the first byte of the first member of the array arr.

On big endian systems:

-----
| . | p
-----
  |
  v
-------------------------------------------------
| 0 | 0 | 0 | 2 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | 4 | arr
-------------------------------------------------
|    arr[0]     |    arr[1]     |    arr[2]     |
-------------------------------------------------

On little endian:

-----
| . | p
-----
  |
  v
-------------------------------------------------
| 2 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | 4 | 0 | 0 | 0 | arr
-------------------------------------------------
|    arr[0]     |    arr[1]     |    arr[2]     |
-------------------------------------------------

So when you read the value of *p you'll get 0 on big endian systems and 2 on little endian systems.

When you then perform p=p+1, you increase the address p points to by 1 character, i.e. 1 byte, so now it looks like this:

Big endian:

-----
| . | p
-----
  |----
      v
-------------------------------------------------
| 0 | 0 | 0 | 2 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | 4 | arr
-------------------------------------------------
|    arr[0]     |    arr[1]     |    arr[2]     |
-------------------------------------------------

Little endian:

-----
| . | p
-----
  |----
      v
-------------------------------------------------
| 2 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | 4 | 0 | 0 | 0 | arr
-------------------------------------------------
|    arr[0]     |    arr[1]     |    arr[2]     |
-------------------------------------------------

Now *p contains the value 0 on both big endian and little endian systems. This assumes however that an int is 32-bit. If an int is 16 bit, it instead looks like this:

Big endian:

-----
| . | p
-----
  |----
      v
-------------------------
| 0 | 2 | 0 | 3 | 0 | 4 | arr
-------------------------
|arr[0] |arr[1] |arr[2] |
-------------------------

Little endian:

-----
| . | p
-----
  |----
      v
-------------------------
| 2 | 0 | 3 | 0 | 4 | 0 | arr
-------------------------
|arr[0] |arr[1] |arr[2] |
-------------------------

In this case *p is 2 on big endian systems and 0 on little endian systems after incrementing.

@Toby Speight 2018-08-10 15:00:51

Technically, the answer also depends on CHAR_BIT - easily forgotten if you only work with small-char systems... For example, with char and int both 16 bits wide, 2 3 is another possible result.

@Achal 2018-08-10 12:29:38

This

int arr[]={2,3,4};

looks like below if your system supports little endian, in case of big endian output may vary.

 arr[2]      arr[1]   |------------arr[0]-----------------------------|  
 ----------------------------------------------------------------------
|     4      |   3    | 0000 0000 | 0000 0000 | 0000 0000 | 0000 0010  | 
 ----------------------------------------------------------------------
           0x108    0x104       0x103      0x102       0x101       0x100 -- assume arr base address starts from 0x100
                                                                     arr
MSB                                                                  LSB

Now when you do

char *p;
p=(char *)arr;

Here p is a char pointer & arr type casted as char* which means pointer p points to one byte memory location at a time i.e first time 0x100 to 0x101.

When the statement

printf("%d\n",*p);

executes it prints what data is there in 0x100-0x101 location which is 2, hence it prints 2.

And next when you do

p=p+1;

the pointer p increments by one byte i.e now p points to 0x101 memory location and when the statement printf("%d\n",*p); executes it prints what data is there in 0x101-0x102 location which is 0, hence it prints 0.

Also while using %p you should typecast pointer variable as void* as printf("%p") and casting to (void *)

printf("%p\n",(void*)p);

Related Questions

Sponsored Content

17 Answered Questions

[SOLVED] With arrays, why is it the case that a[5] == 5[a]?

14 Answered Questions

[SOLVED] What is the difference between const int*, const int * const, and int const *?

9 Answered Questions

[SOLVED] Improve INSERT-per-second performance of SQLite?

8 Answered Questions

[SOLVED] Regarding 'main(int argc, char *argv[])'

  • 2010-10-09 21:54:27
  • Fahad Uddin
  • 397908 View
  • 74 Score
  • 8 Answer
  • Tags:   c argv argc

7 Answered Questions

[SOLVED] What is the difference between char array vs char pointer in C?

  • 2012-04-17 07:12:43
  • diesel
  • 280777 View
  • 171 Score
  • 7 Answer
  • Tags:   c arrays pointers

1 Answered Questions

[SOLVED] Why do all the C files written by my lecturer start with a #?

  • 2017-08-11 07:17:56
  • The Main Man
  • 20520 View
  • 409 Score
  • 1 Answer
  • Tags:   c c-preprocessor

5 Answered Questions

[SOLVED] Type conversion - unsigned to signed int/char

1 Answered Questions

[SOLVED] Value of char pointer changes after assigning to another char pointer

  • 2015-01-10 07:00:03
  • IAmStarDust
  • 98 View
  • 0 Score
  • 1 Answer
  • Tags:   c pointers

2 Answered Questions

[SOLVED] int array to char pointer

  • 2014-05-11 16:16:32
  • user3624383
  • 477 View
  • 1 Score
  • 2 Answer
  • Tags:   c arrays pointers

4 Answered Questions

[SOLVED] Casting int to char pointer: unexpected value?

  • 2012-07-04 18:13:58
  • insane
  • 3078 View
  • 1 Score
  • 4 Answer
  • Tags:   c pointers

Sponsored Content