1

In the below program,

#include<stdio.h>
int main(){
  int a = 1025;
  int *p;
  p = &a;

  char *p0;
  p0 = (char *)p;


  //print("\n%d %d", *p0, *(p0+1));
  printf("\n%d and %d", *p0, p0[1]);

}

Output:

1 and 4


char & int are arithmetic types in C, To understand the output after type casting, I need to understand the binary representation of 1025, which is, 00000000 00000000 00000100 00000001. Little endianness of Intel arch will take first byte 00000001.

Question:

For the above program written in java, array notation cannot be used to access each byte of int.

In the above C program, array notation can be alternatively used to access each byte of int.

As per this program, How different is array from a pointer in C?

15
  • 2
    An array is a contiguous sequence of elements. Commented Oct 18, 2016 at 12:22
  • @JoachimPileborg Same with one dimensional array in Java Commented Oct 18, 2016 at 12:25
  • 7
    There is no array in your program. p[x] is just shorthand for *(p + x). Commented Oct 18, 2016 at 12:27
  • 1
    @overexchange The comment you link describes casting of arithmetic values, not pointers. Commented Oct 18, 2016 at 12:37
  • 2
    "I need to understand the binary representation of 1025" The binary representation can as well be 00000001 00000100 00000000 00000000. And that's actually what you have, since you got the output 1 4. This is because of CPU endianess. Commented Oct 18, 2016 at 12:41

4 Answers 4

1

array - a contiguous series of elements that actually exists in memory. It has an address, usually considered as the address of the first element of the array.

pointer - a variable that contains an address. The address contained in a pointer may or may not point to actual memory.

Think of it this way - your home has an address. It exists somewhere, and you can put stuff in it - it's an array. You can put any address on an envelope and try to mail it. It may or may not get properly delivered for a lot of reasons - the street address written on an envelope is a pointer. And you can't store anything in that writing.

Sign up to request clarification or add additional context in comments.

Comments

0

For the above program written in java, array notation cannot be used to access each byte of int.

You're right

In the above C program, array notation can be alternatively used to access each byte of int.

Yes, you can declare a char pointer, point it to the first byte of the int and then access each byte of the int variable with array notation.

The same way you can declare an array

char arr[3]={1,2,3};

And use it as a pointer

char *prt;
prt = arr;

That is equivalent to

ptr = & ( arr[0] ); // The address of the first element of arr

As per this program, How different is array from a pointer in C?

To simplify (as per this program) an array is a pointer to the first element of the array.

p0 is a pointer to an array whose items are p0[0], p0[1],...

To clarify more:

You can declare a variable as a pointer or as array.

In your code you don't declare arrays.

But as you use p0[1] you're treating p0 as an array.

Finally:

I quote...

To understand the output after type casting

See https://stackoverflow.com/a/6752688/1579327

The result of casting a larger type into a smaller one is undefined (implementation dependent) iF the smaller type is signed and the value of the larger type doesn't fit into the smaller one.

4 Comments

What does it mean to say No? Can you share the java code? BTW, there is no array in the above query
I meant "array notation cannot be used to access each byte of int" (edited the answer)
What does Yes mean? Read what Michael Walz says.
Yes means that what you stated is true. I tried to clarify more. See my last edit.
0

Strictly answering the question in the title - arrays are not pointers:


  • int arr[10]:

    • Amount of memory used is sizeof(int)*10 bytes

    • The values of arr and &arr are necessarily identical

    • arr points to a valid memory address, but cannot be set to point to any other memory address (i.e., it serves as a constant "label")


  • int* ptr = malloc(sizeof(int)*10):

    • Amount of memory used is sizeof(int*) + sizeof(int)*10 bytes

    • The values of ptr and &ptr are not necessarily identical (in fact, they are mostly different)

    • ptr can be set to point to both valid and invalid memory addresses (i.e., you can change it during runtime as many times as you will)

1 Comment

By "values", I mean, if you cast them to void* or to size_t.
0

Even though they aren't the same thing, there is a close relationship between arrays and pointers in C. The array subscripting operation a[i] is defined in terms of pointer arithmetic:

a[i] == *(a + i)

That is, take the address a, offset i elements of the array's base type from that address, and dereference the result. For example, if a is an array of int, the expression a + 1 evaluates to the address of the next integer object following the one stored at a, which may be anywhere from 2, 4, or 8 bytes away.

Arrays are not pointers; however, except when it is the operand of the sizeof or unary & operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted ("decay") to an expression of type "pointer to T", and the value of the expression will be the address of the first element in the array.

So, given the code

int a[10];
a[2] = 2;

In the statement a[2] = 2, the expression a is not the operand of the sizeof or unary & operators, so it is converted ("decays") from type int [10] to int *, and it evaluates to the address of the first element of a. We then offset 2 elements of type int from that address and assign the value 2 to that location. Note that this conversion applies to the expression a, not the array object to which it refers.

So how does all that relate to your code?

In C, a non-bitfield object is composed of a contiguous sequence of one or more bytes. Objects of char type take up 1 byte by definition, so an object of any multibyte type (int, long, float, double, etc.) can be treated as an array of char (or unsigned char).

A picture may help - I took your code and used a little utility I wrote to dump the contents of each object in memory:

       Item        Address   00   01   02   03
       ----        -------   --   --   --   --
          a 0x7ffffa8a29cc   01   04   00   00    ....

          p 0x7ffffa8a29c0   cc   29   8a   fa    .)..
            0x7ffffa8a29c4   ff   7f   00   00    ....

         p0 0x7ffffa8a29b8   cc   29   8a   fa    .)..
            0x7ffffa8a29bc   ff   7f   00   00    ....

The binary representation of 1025 is 0x0401. As you can see, the object a is 4 bytes wide and contains the byte sequence {0x01, 0x04, 0x00, 0x00}. This is on an x86 system, which is little-endian, so the least significant byte comes first in the sequence.

Both p and p0 store the address of a. I'm on a 64-bit system, so pointer values are 8 bytes wide.

*p0 evaluates to the value of first byte in a, which in this case is 0x01. p0[1] is equivalent to *(p0 + 1), and evaluates to the value of the second character value following p0, which in this case is 0x04.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.