简体   繁体   中英

Char pointer to integer array

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

I run the code in codeblocks and it is giving 0 as output. If II change p as int pointer then its giving 2 as output.

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

Why so?

When p is declared as a pointer to char , it is expected to point at data with size of 1 byte. So (p + 1) increments p by 1 byte.

Since an int is at least 4 bytes long, (p + 1) is likely pointing to the second of the higher order bytes of 1 , which is still 0 .

If you wanted it to have identical output, you would do something like that

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

But it's best to avoid such code and compile with the -Wall flag, which would definitely produce a warning in your case.

When you increment a pointer, it moves by the size of the thing it is pointing to.

Let's say you have 16 bit integers. In binary, the number one is: 0000 0000 0000 0001

A char pointer can only point to 8 bits at a time: 0000 0000

To have a look from a slightly different angle, about the binary + operator, chapter 6.5.6, paragraph 8 of C99 standard says, [emphasis mine]

When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression . In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of the array object, provided they exist.

So, in your First case , p is of type char * and (p + 1) gives a result as a pointer which is incremented by sizeof(char) [that's 1 byte, most of the cases] and hence points to the 2nd element of the char array held by p . Since actually, the array held by p is of type int [Let's say 4 bytes of length, in a 32 bit system], so as per the value stored, [ 1 getting stored as 0000 0000 0000 0001 ], the *(p+1) prints out 0 .

OTOH, in your second case , p is of type int * and (p + 1) gives a result as a pointer which is incremented by sizeof(int) and hence points to the 2nd element of the int array held by p . Since actually, the array held by p is of type int , so as per the value stored, [ int x[] = {1, 2, 3}; ], the *(p+1) prints out 2 .

Assume sizeof(int) is 16 bits. 2 in binary is 00000000 00000010. sizeof(char) is 8 bits. Little and big endian are two ways of storing multibyte data-types.

Consider the following code:
int i = 2; char c = (char )&i; if ((*c)==2)
printf("Little endian"); else //if *c is 0 printf("Big endian");

From this code you can conclude that Big Endian will store 2 as 00000000 00000010. But Little Endian will store it as 00000010 00000000. , So zero as output would mean first 8 bits are zero, so system is Big Endian. Had it been using Little Endian, answer would be 2 as a char p is supposed to point 8 bits only. Actually, declaring the data type of pointer means to specify how any bits do you want it to refer and how many bits it will jump when incremented. If in this example, as p is a char pointer, *(p+1) will refer 00000010 in Big endian and 00000000 in Little Endian. Your compiler may be using 32 bit for interger, so i think in both cases *(p+1) will give 0. (as 2 => 00000000 00000000 00000000 00000010 2nd byte from either side is 0)

Refer to this: `#include

       int main()
      {
        int x[] = {1, 2, 3};
         char *p = &x;
        printf("%d\n", *p);
         printf("%d\n", *(p+1));
          printf("%d\n", *(p+2));
          printf("%d\n", *(p+3));
         printf("%d\n", *(p+4));
          printf("%d\n", *(p+5));
         printf("%d\n", *(p+6));
         printf("%d\n", *(p+7));
          printf("%d\n", *(p+8));
          return 0;
            }`

Output: 1 0 0 0 2 0 0 3

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