Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers &...

34
Pointers to pointers & multi- dimensional arrays

Transcript of Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers &...

Page 1: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Pointers to pointers & multi-

dimensional arrays

Page 2: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Pointers to pointers

2

3 i: 4 j: 5 k:

ip2: ip1:

ipp:

int i=3;

int j=4;

int k=5;

int *ip1 = &i;

int *ip2 = &j;

int **ipp = &ip1;

Page 3: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Pointers to pointers

3

int i=3;

int j=4;

int k=5;

int *ip1 = &i;

int *ip2 = &j;

int **ipp = &ip1;

ipp = &ip2;

3 i: 4 j: 5 k:

ip1: ip2:

ipp:

Page 4: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Pointers to pointers

4

3 i: 4 j: 5 k:

ip1: ip2:

ipp:

int i=3;

int j=4;

int k=5;

int *ip1 = &i;

int *ip2 = &j;

int **ipp = &ip1;

ipp = &ip2;

*ipp = &k;

Page 5: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Reminder – the swap function

Does nothing Works

void swap(int a, int b) { int temp = a; a = b; b = temp; } int main() { int x, y; x = 3; y = 7; swap(x, y); // now x==3, y==7

}

void swap(int *pa, int *pb) { int temp = *pa; *pa = *pb; *pb = temp; } int main() { int x, y; x = 3; y = 7; swap(&x, &y); // x == 7, y == 3 }

Page 6: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Pointers to pointers: example

6

//put pointer to an allocated string in pp

int allocString( int len, char ** pp)

{

char *str = (char*)malloc(len + 1);

if (str==NULL)

{

return 1;

}

*pp = str;

return 0;

}

Page 7: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Pointers to pointers: example

7

// copy a string using "allocString"

void main()

{

char *s = "example";

char *copy;

allocString( strlen(s), &copy );

strcpy( copy, s);

free (copy);

}

Page 8: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays

8

Page 9: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays

9

Can be created in few ways:

1. Automatically:

int m[2][3]; // 2 rows, 3 columns

continuous memory (divided to 2 blocks)

access: m[row][col] = 0;

Page 10: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Automatic multi-dimensional arrays

10

#define R 2 #define C 3 int m[R][C]; int* m_ptr= &(m[0][0]); for (int i=0; i<R*C; ++i) { printf(“%d\n”, *m_ptr++); }

Page 11: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Automatic multi-dimensional arrays

A[0][0] A[0][1] … A[0][c-1]

… … … …

A[i][0] A[i][1] … A[i][c-1]

… … … …

A[R-1][0] A[R-1][1] … A[R-1][C-1]

11

• • • A

[i] [0]

A [i] [C-1]

• • •

A[i]

A [R-1] [0]

A [R-1] [C-1]

• • •

A[R-1]

• • •

A

A [0] [0]

A [0] [C-1]

• • •

A[0]

int A[R][C];

A+i*C*4 A+(R-1)*C*4

Row-major ordering

Like a matrix

Starting address of A[i]

Page 12: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Semi-dynamic multi-dimensional arrays

12

2. Semi-dynamic:

Define an array of pointers:

int *pa[5]; // allocates memory for 5 pointers

for (i=0; i<5; i++)

{

pa[i] = (int*) malloc( 7*sizeof(int) );

// pa[i] now points to a memory for 7 ints

}

Page 13: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Dynamic multi-dimensional arrays

13

3. Dynamically:

int ** array;

array = (int**) malloc( 5*sizeof(int*) );

for (i=0; i<5; i++)

{

array[i] = malloc( 7*sizeof(int) );

}

Page 14: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Semi/Dynamic multi-dimensional arrays

14

Memory not continuous

• Each pointer can be with different size

• Access: arr[ i ][ j ]

• Don’t forget to free all the memory:

for (i=0; i<nrows; i++ )

{

free( array[i] );

}

free( array ); // only for dynamic

Page 15: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Dynamic arrays – more efficient way

0,0 0,1 0,2 1,0 1,1 1,2

15

int* A= (int*) malloc(R*C*sizeof(int)); 1-D array R=3 C=2

• Access: A[ i*C + j ] // A [i][j]

• One access to memory vs. two in previous

semi/dynamic representations.

• Easier (& more efficient) implementation of

iterators

• But:

• Less readable code (can hide with macro or much better, inline functions)

Page 16: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Pointers to pointers to …

16

We also have pointers to pointers to pointers,

etc.:

double ** mat1 = getMatrix(); double ** mat2 = getMatrix(); //allocate an array of matrices double *** matrices = (double***) malloc(n*sizeof(double**)); matrices[0] = mat1; matrices[1] = mat2;

Page 17: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays as arguments

to functions

17

int arr[5][7]; // 5 rows, 7 columns

When sending ‘arr’ as an argument to a function, only

the 1st index can be omitted:

• void func( int x[5][7] ) //ok

• void func( int x[][7] ) //ok

• void func( int x[][] ) //error (always)

• void func( int * x[] ) //something else

• void func( int ** x ) //something else

Page 18: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Why ?

18

Page 19: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Pointers to arrays (of size X):

19

int foo (char arr[][20]);

arr is a pointer to an array of 20 chars.

Therefore:

sizeof (arr) = sizeof (void*);

sizeof (*arr) = 20*sizeof (char);

Page 20: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Pointers to arrays (of size X):

20

Explicit declaration:

char (*arr_2d)[20];

// arr_2d is a pointer

// not initialized

Using typedef:

typdef char arr_2d_20[20];

arr_2d_20 *p_arr_2d;

But:

typdef char arr_2d[][]; // comp. error

Page 21: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

char (*arr)[5]; char *arr[5];

After initialization

21

arr

Pointers to arrays (of size X):

Page 22: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

char (*arr)[5]; char *arr[5];

sizeof (arr) = sizeof(void*) sizeof (*arr) = 5*sizeof(char)

sizeof (arr) = 5*sizeof (char*) = 5*sizeof (void*) sizeof (*arr) = sizeof (char*)= sizeof (void*)

22

Pointers to arrays (of size X):

Page 23: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays as arguments

to functions

23

Page 24: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays as arguments

to functions

24

void foo( int matrix[ROWS_NUM][COLS_NUM] ) {

Page 25: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays as arguments

to functions

25

void foo( int matrix[ROWS_NUM][COLS_NUM] ) {

What is really sent?

Page 26: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays as arguments

to functions

26

void foo( int (*matrix)[COLS_NUM] ) {

pointer to an array of

COLS_NUM ints!

Page 27: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays as arguments

to functions

27

void foo( int (*matrix)[COLS_NUM] ) {

...

... matrix[r][c]

Page 28: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays as arguments

to functions

28

void foo( int (*matrix)[COLS_NUM] ) {

...

... matrix[r][c]

... (*(matrix+r))[c]

Page 29: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays as arguments

to functions

29

void foo( int (*matrix)[COLS_NUM] ) {

...

... matrix[r][c]

... (*(matrix+r))[c]

matrix is a pointer to int[COLS_NUM].

addition is done in this units.

This is why COLS_NUM is needed!

Page 30: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays as arguments

to functions

30

void foo( int (*matrix)[COLS_NUM] ) {

...

... matrix[r][c]

... (*(matrix+r))[c]

... *((*(matrix+r)) + c)

Page 31: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

Multi-dimensional arrays as arguments

to functions

31

void foo( int (*matrix)[COLS_NUM] ) {

...

... matrix[r][c]

... (*(matrix+r))[c]

... *((*(matrix+r)) + c) == *(matrix+r*COLS_NUM+c)

The compiler is probably optimizing the

internal computation to this.

Page 32: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

32

Example of dynamic multidimensional

array: argv, argc

We want to pass parameters to the program running

via the shell

Page 33: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

To pass command line arguments to our program we

should use the following main declaration:

main(int argc, char* argv[]) { ...

Compare to main(String[] args)

in java.

Unlike java the first argument is the

name of the program itself.

char** argv

char argv[][]

argv, argc

Page 34: Pointers to pointers & multi- dimensional arrays - ariel.ac.il · Pointers to pointers & multi-dimensional arrays . Pointers to pointers 2 i: 3 j: 4 k: 5 ip1: ip2: ipp: int i=3; int

argv & argc: example

$ prog1 –u danny –p 1234

argc == 5

argv[0] == “prog1”

argv[1] == “-u”

...

argv[4] == “1234”

Always: argv[argc] == NULL

(redundant since we are also given argc)