**Pointers to values**

// **value** (of type int) stored in a memory location

**int value; **

// **avalue**: pointer to a value of type int

// **avalue**: address of a memory location containing a value of type int

**int* avalue; **

// Extracting the address of value

**avalue = &value;**

// Extracting value from address/pointer

**int val = *avalue;**

**1-dimensional arrays**

// One dimensional array **A** of size 6

**int A[6];**

**A**: Value of **&A[0]** OR pointer to the value at 0-th index

**A[i]**: Value stored in the i-th index, where 0 <= i < 6

**(A+i)**: Value of **&A[i]** OR pointer to the data at i-th index

***(A+i)**: Same as **A[i]**

**Multi-dimensional arrays**

Once the pointer arithmetic is clear in the context of one-dimensional arrays, we can now easily extend the logic to the pointer arithmetic in multi-dimensional arrays.

// **A** is a 3-dimensional array with the dimensions 4, 3 and 2, and having values of type int

**int A[4][3][2];**

**A**: Value of **&A[0]**

**A[i]**: Value of **&A[i][0]**, where 0 <= i < 4

**A[i][j]**: Value of **&A[i][j][0]**, where 0 <= i < 4, 0 <= j < 3

**A+i**: Same as **&A[i]**

***(A+i)**: Same as **A[i]** OR value of **&A[i][0]**

***(A+i)+j**: Value of **&A[i][j]**

***(*(A+i)+j)**: Same as **A[i][j]** OR value of **&A[i][j][0]**

***(*(A+i)+j)+k**: Value of **&A[i][j][k]**, where 0 <= i < 4, 0 <= j < 3, 0 <= k < 2

***(*(*(A+i)+j)+k)**: Same as **A[i][j][k]**

**Generalization**

**int A[i_1][i_2]…[i_n];**

Value of **A[i_1][i_2]…[i_k]** = **&A[i_1][i_2]…[i_k][0]**

**Difference between A[k] and *pA**

**int A[50];**

- Array A allocated for 50 elements, each of which is of type int
- Assignment A = 25 is not allowed

**int *pA; **

- a pointer to an int
- pA can be changed at any time