1

I am learning now c and i am studying pointers. I have read some examples and I come up with this:

   #include <stdio.h>

   int main ()
   { 
      float balance[10][5];
      float *p;

      p = (float *) balance;

      *(p + 16) = 200.0; //init the balance[3][1] with the value 200.0
       printf("%f\n", balance[3][1]); 
       return 0;    
   }

My question is this. Why I have to cast the balance with a (float *) ? Is this because the array is 2 dimensions? So the pointer is also 2 dimensions? So I have to transform it to a 1 dimension ?

5 Answers 5

3

Why i have to cast the balance with a (float *) ?

This is because p is of type float * while balance is of type float (*)[5] after decaying to the pointer.

is this because the array is 2 dimensions?

Yes.

so the pointer is also 2 dimensions?

balance decays to float (*)[5].

so i have to transform it to a 1 dimension ?

Yes.

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

2 Comments

To avoid using cast, you can write p = & balance[0][0];
True. But I just answered the queries. :)
1

This code is an ugly hack, and will only serve to confuse you, now and when you come back to look at this code in the future. The idea behind pointer arithmetic is to make accessing arrays easier, not harder. If you change

    float *p;

to

    float **p;

your pointer is now a double pointer, which means that when you use the indirection operator (*) once, you get another pointer. The array you've created looks like this:

[0,0][0,1][0,2][0,3][0,4]
[1,0][1,1][1,2][1,3][1,4]
[2,0][2,1][2,2][2,3][2,4]
[3,0][3,1][3,2][3,3][3,4]
[4,0][4,1][4,2][4,3][4,4]
[5,0][5,1][5,2][5,3][5,4]
[6,0][6,1][6,2][6,3][6,4]
[7,0][7,1][7,2][7,3][7,4]
[8,0][8,1][8,2][8,3][8,4]
[9,0][9,1][9,2][9,3][9,4]

Since you have two levels of indirection, the first pointer will point to your row, and the second one will point to your column. Since indirection is done backwards, that means that in pointer notation the innermost element is the element that would be furthest left in array notation.

arr[ROW][COL] === *(*(p + ROW) + COL) 

Now, if you want to access elements, you can do that using array notation arr[ROW][COL], or with pointer arithmetic. With a double pointer, there are two levels of indirection. So whereas you had to use

    p = (float *) balance;
    *(p + 16)

to get the location you wanted, it would actually be a lot easier (in my opinion) to simply write

    p = balance;
    *(*(p + 3) + 1)

because now you're using pointer arithmetic similarly to array indexing, and it's easier to tell just at a glance which element you want to point at.

As far as casting a double pointer to a single pointer, it's really easier to just handle the double pointer in the first place, and that's all that the name of an array is.

    int arr[ROW][COL] = {0};
    int **p_arr = arr; /* Valid operation. arr without array notation is a double pointer */

Comments

0

This example demonstrates how arrays are allocated in memory. A two-dimensioanl array is allocated by rows that is after the first row there is the second row of the array in the memory. As the memory for arrays is allocated as one extent then you can interpretated it as a one-dimensionale array.

The array in your example has in fact 50 elements (10 * 5). As the rows are accomodated sequentially in the memory then the position of the element balance[3][1] can be calculated as 3 * 5 + 1 that is equal to 16. So if you will consider that extent of the memory as one dimensional array then the corresoponding element can be written as p[16] or (that is the same) as *(p + 16).

One useful trick of such interpretation of a two-dimensional array can be applied to sorting of a two-dimensional array. It is much simpler to sort a two-dimensional array as one-dimensional array using standard sort functions.

Comments

0

Why I have to cast the balance with a (float *)

You don't have to, you can use it simply as an array, just as is done in the printf(). I would advise you to refrain from combining flat access and multidimensional access.

Comments

-1

here the variable "balance" stores the base address of the 2 dimensional array..

what is a pointer? A variable which store the address is called pointer

right!!

'p' is single floating pointer which stores the address of a floating variable but here 'balance' is a floating array variable.

what you have did is, typecasting the 2D array variable to a pointer as a 1D array...i.e. according to the pointer variable 'p' what you assigned in 'balance' which is a 2D array has now become a 1D array...

if you assign pointer lyk this

float **p;

then

p=balance; is a valid statement and the pointer treat this as a 2D array.

2 Comments

A float ** is a pointer to a pointer to a float value, therefore it points to a memory area where one or more pointers reside. A float[10][5] is a memory area of 50 floats and can be used as a pointer to that area. Therefore your answer doesn't work.
You can check with the compiler and the above assignment is valid.. balance is a 2D array i.e. balance stores base address of 2D array and balance[0] stores address of the first row and balance[0][0] points the value in the first row and first column. Here balance carries 2 address and hence double pointer is valid.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.