2

I have an array with 10 int elements, and I want to point a pointer to this array, not with full size but half. By this, I can reach the first 5 elements by using ptr and the second 5 elements by increasing pointer one ptr++.

I just want to know how can I CAST, I don't need to know workarounds or union or struct or anything else... I just wonder the syntax of such a thing.

Here is the example that I struggle with ;

// Pointer to an integer 
int *p;
// Pointer to an array of 5 integers 
int (*ptr)[5]; // this could be void*
int arr[10]; 

// Points to 0th element of the arr. 
p = arr; 

// Points to the whole array arr. 
ptr = (int[5]*)&arr; // when arr sized as 5 , ptr = &arr; gives result a pointer "ptr" with size of 5  

printf("p = %p, ptr = %p\n", p, ptr); 

p++; 
ptr++; 

printf("p = %p, ptr = %p\n", p, ptr); 

return 0; 

Note: The answer is: ptr = (int(*)[5])&arr; (compiler's warning message helped me out to find this answer, it was not able to convert one to another type ... )

But I really don't know what is the () and why it is not the same thing as int*[5]. I really don't understand the purpose of parenthesis there.

  • By the way, the answer is: ptr = (int(*)[5])&arr; but I really don't know what is the (*) and why it is not the same thing int*[5]. I really don't understand the purpose of parenthesis there. – ground beef Aug 28 '20 at 01:32
  • 1
    When you have complex types like this, the easiest thing is to define a typedef. – Barmar Aug 28 '20 at 01:33
  • 1
    @groundbeef See [C pointer to array/array of pointers disambiguation](https://stackoverflow.com/questions/859634/c-pointer-to-array-array-of-pointers-disambiguation). – dxiv Aug 28 '20 at 02:00

2 Answers2

1

If I understand what you’re asking for, this is what you want:

ptr = (int (*)[5]) &arr;

The expression &arr has type int (*)[10] (pointer to 10-element array of int). Since ptr has type int (*)[5] (pointer to 5-element array of int), we just need to cast the result of &arr to that type.

Remember the following precedence rules:

T *a[N];        // a is an array of pointer to T
T (*a)[N];      // a is a pointer to an array of T
T *f();         // f is a function returning pointer to T
T (*f)();       // f is a pointer to a function returning T

Unary * has a lower precedence than [] and (), so an expression like *a[i] is parsed as *(a[i]) - you’re dereferencing the result of a[i]. If a is a pointer to an array, then you need explicitly group * with a so you index into what a points to - (*a)[i].

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

Define a typedef to make the casting easier.

typedef int (*int5ptr)[5];

// Pointer to an integer 
int *p;
// Pointer to an array of 5 integers 
int5ptr ptr;
int arr[10]; 

// Points to 0th element of the arr. 
p = arr; 

// Points to the whole array arr. 
ptr = (int5ptr)&arr;

printf("p = %p, ptr = %p\n", p, ptr); 

p++; 
ptr++; 

printf("p = %p, ptr = %p\n", p, ptr); 
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thank you for your answer, I really want to know direct casting syntax and under the hood. I found it but i still can not get the idea of paranthesis .I would use typedef but I really want to know why int ( * )[5] is not the same thing as int*[5] , what is the purpose of (), because when I tried as (int*[5])&addr , compiler gives an error about converting int** to subject type. – ground beef Aug 28 '20 at 01:44
  • 1
    @groundbeef Because `int (*ptr)[5]` and `int *ptr[5]` are different. This analogy could help. So the type is literally your declaration but stripping variable name. – Louis Go Aug 28 '20 at 01:59
  • @groundbeef The parentheses are necessary to override default precedence rules, just as in arithmetic expressions. You need to ensure that it's interpreted as a pointer to an array, not an array of pointers. – Barmar Aug 28 '20 at 08:06