简体   繁体   中英

Pointers in C, integer pointer to character pointer

When I run this code:

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

The output is 2 and 0. The second result is slightly confusing. Could someone explain why this is happening?

Let's break this down:

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

Creates an array of 3 integers. Assuming your system is 32bit little endian this is how it looks in memory:

02 00 00 00 03 00 00 00 04 00 00 00

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

p now points to arr but is a pointer to char* . In other words, p points to the 02 .

printf("%d", *p);

You are printing as an int the location referenced by p . So when you dereference p (by writing *p ) you are accessing the char (since p is of type char* ) referenced by p . Which is 02 .

p = p+1;

p now points to the 00 just after 02 , because p is char* . So when you add 1, it will move by 1 * sizeof(char) = 1 * 1 = 1 byte in memory.

printf("%d", *p);

You are printing as an int the location referenced by p . So when you dereference p (by writing *p ) you are accessing the char (since p is of type char* ) referenced by p . Which is 00 .

If you wanted to print 3 instead of 0 you have to change your pointer type to int* instead of char* , making the pointer move by 1 * sizeof(int) = 1 * 4 = 4 bytes in memory.

The result you get will depend on the size of int on your implementation and its endianness.

Assuming 32bit ints, 8bit chars and a litte-endian environment (say x86), arr will be like this in memory:

<  arr[0]  > <  arr[1]  > <  arr[2] >
02 00 00 00  03 00 00 00  04 00 00 00
^  ^         ^
p  p+1 ...   p+4

If you take a char pointer to the start of that memory, and print out the first element, 2 should be output. If you increment that pointer, 0 will be output next. You'll need to increment it a few times more to 'see' 3.

Note that on a big-endian environment with the same type sizes, your program would have output two zeros, because the layout would have been:

<  arr[0]  > <  arr[1]  > <  arr[2] >
00 00 00 02  00 00 00 03  00 00 00 04
^  ^         ^
p  p+1 ...   p+4

This is because of something called endianness .

When you create an array like int arr[3] = {2, 3, 4}; it gets created in the memory as follows

Big endian:
    0   1   2     3      4   5   6      7     8   9  10     11 
  +---+---+---+--------+---+---+---+--------+---+---+---+--------+
  |   |   |   | ..0010 |   |   |   | ..0011 |   |   |   | ..0100 |
  +---+---+---+--------+---+---+---+--------+---+---+---+--------+

  <--       2       --><--       3        --><--        4      -->

Little endian:
       0     1   2    3    4   5   6      7     8       9  10   11 
  +--------+---+---+---+---------+---+---+---+--------+---+---+---+
  | ..0010 |   |   |   |  ..0011 |   |   |   | ..0100 |   |   |   |
  +--------+---+---+---+---------+---+---+---+--------+---+---+---+

  <--       2       --><--       3        --><--        4      -->

To understand more, you need to modify you program as follows:

int main(void)
{

    int arr[3] = {2, 3, 4};
    char *p = (char*) arr;  
    int i;
    int size = (int)sizeof(arr);

    for (i=0; i<size ; i++) {
        printf("%d", *p);
        p++;
    }

    return 0;
}

And, to check the endianness of you hardware, you can use the following function.

void endian(void)
{
        int i = 1;

        if (*(char *) &i == 1)
                printf("Little endian \n");
        else
                printf("Big endian \n");

        return;
}

Here is a paste that will let you understand the issue better: http://codepad.org/ClrrwjKY

As you can see, the value of the consecutive integers appear separated by three zeroes. This is because an integer is 4 bytes long, whereas a char is only 1 byte long. So when the int array is cast to char, you iterate over it byte by byte (or char by char), not by four bytes (int by int).

Here as 'p' is a character pointer.. p+1 increments the current value of p only by 1. As the array is integer, in order to access each values of the array one by one, you'll have to increment the character array by 2. If the address of integer array is 1000 therefore,

  arr[0] is at 1000
  arr[1] is at 1002
  arr[2] is at 1004

and the value of arr is the address of arr[0]; so initially

 p=arr=1000

when p is incremented, p is 1001 whereas arr[1] is 1002

.. So in order to access all the values you'll have to increment the value of p twice each time..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM