Académique Documents
Professionnel Documents
Culture Documents
R. Inkulu
http://www.iitg.ac.in/rinkulu/
1 / 41
int func(void) {
int states[5], i; //defining
for (i=0; i<5; i++)
states[i]=i; //initializing
for (i=0; i<5; i++)
printf("%d", states[i]); //accessing the value
return 0;
}
array is used in storing multiple objects of same type
objects in the array are indexed starting from 0
array scope is limited to the function in which it is defined
2 / 41
sizeof() operator
int func(void) {
int a[5];
printf("%d, %d, %d",
sizeof(int), sizeof(a[3]), sizeof(a));
//outputs 4, 4, 20
}
sizeof(object or type name) is a compile-time unary operator to get
3 / 41
Two-dimensional arrays
int func(void) {
int a[2][3], i, j;
//defining
4 / 41
Three-dimensional arrays
int func(void) {
int a[2][3][4], i, j, k;
//defining
5 / 41
Address vs Value
int a, b[2];
a = 10;
printf("%d, %p", a, &a);
//prints 10, 0xbfeac818
b[0] = 22; b[1] = 24;
printf("%d, %p, %d, %p", b[0], &b[0], b[1], &b[1]);
//prints 22, 0xbfeac820, 24, 0xbfeac824
memory for arrays is allocated contiguously
6 / 41
int c[2][3], i, j;
for (i=0; i<2; i++)
for (j=0; j<3; j++) {
printf("%p, ", &c[i][j]);
}
//prints 0xbfd8f650, 0xbfd8f654, 0xbfd8f658,
//0xbfd8f65c, 0xbfd8f660, 0xbfd8f664,
contiguous memory is allocated for the first row, immediately
7 / 41
int a[2][5][3], i, j, k;
for (i=0; i<2; i++)
for (j=0; j<5; j++)
for (k=0; k<3; k++)
printf("%p, ", &a[i][j][k]);
//observed: difference between any two successive
//addresses printed is four
8 / 41
int a[2][5] = {
{0, 11, 22, 33, 44},
{1, 12, 23, 34, 45}
};
for (int i=0; i<2; i++)
for (int j=0; j<5; j++)
printf("%d, ", a[i][j]);
//prints 0, 11, 22, 33, 44, 1, 12, 23, 34, 45,
9 / 41
Introducing pointers
int x = 1, y = 2, z[2];
int *p = NULL;
//p is a pointer to int, initialized with NULL
p = &x;
y = *p;
*p = 0;
p = &z[1];
*p = 5;
*p = *p + 5;
//p points to x
//y is 1
//x is now 0
//p points to z[1]
//z[1] is 5
//z[1] is 10
10 / 41
Incrementing a pointer
p
z[0]
z[1]
z[2]
z[3]
int z[4];
int *p = &z[0];
*(p+1) = 7;
p += 2;
*p = 5;
*p = *p + 3;
*p += 2;
++(*p);
int *q = p;
*q = 89;
z[0]
z[1]
z[2]
z[3]
//*(p+(1*sizeof(int))) = 7
//i.e., z[1] has 7
//p = p + (2*sizeof(int))
//z[2] has 5
//z[2] has 8
//z[2] has 10
//z[2] has 11
//q also points to z[2]
//z[2] has 89
i sizeof (typeA)
11 / 41
z+2
&z[2]
z[1]
&z[1]
z+1
z[2]
p[0]
p[1]
*(p+0) *(p+1)
z[3]
p+0
&z[3]
z+3
p[2]
*(p+2)
p[3]
*(p+3)
&p[0]
p+1
&p[2]
&p[1]
p+2
&p[3]
p+3
double z[4], *p = z;
...
z[3] = 10;
...
ex. compiler replaces z[i] with (z + (i sizeof (double)))
12 / 41
variable
(Arrays and Pointers)
13 / 41
float z[4];
float *p = &z[0], *q;
q = z;
printf("%p, %p, %p", z, p, q);
//identical values are printed
*(z+2) = 20;
q[3] = 52;
*(q+3) = 58;
//z[2] has 20
//z[3] has 52
//z[3] has 58
14 / 41
int z[3][4], i, j;
printf("%p, %p, %p, ", z[0], z[1], z[2]);
//prints addresses of three rows i.e, &z[i][0]
printf("%p, %p", &z[2]+1, &z[1]+2);
//prints identical values
printf("%p, %p", z[2]+1, &z[2][1]);
//prints identical values
two-dimensional array is an array of rows:
z[i] is the name of the array that comprises the ith row;
and, &z[i] is the address of the first row
(Arrays and Pointers)
15 / 41
//prints 10 !
16 / 41
17 / 41
//prints 10, 15
18 / 41
//prints 15, 10
19 / 41
in array x of main
(Arrays and Pointers)
20 / 41
in array x of main
(Arrays and Pointers)
21 / 41
if (*(v+i) != 0)
int main(void) {
int x[3] = {20, 30, 0};
int k = countNonZeros(&x[1], 2);
printf("%d", k);
//prints 1
}
22 / 41
23 / 41
Homework!
24 / 41
Dynamic Memory
p
compile-time
system maintains a table of dynamically allocated memory blocks
25 / 41
z[0]
z[1]
z[2]
z[3]
26 / 41
Pointer arithmatic
at (1):
z[0]
double *p = (double*)
malloc(count*sizeof(double));
double *q = NULL;
... //denotes irrelevant
//stmts
//im here (1)
p += 2;
...
q = p;
p
//im here (2)
...
free(p);
z[1]
z[2]
z[3]
NULL
q
at (2):
z[0]
z[1]
z[2]
z[3]
27 / 41
28 / 41
compile-time
gives flexibility to allocate and deallocate memory based on the
29 / 41
advantages:
compiler will deallocate the memory automatically for all the
30 / 41
...
double *p = (double*)
malloc(count*sizeof(double));
at (2):
...
p
//im here (1)
free(p);
...
dangling
//im here (2)
at (3):
p = NULL;
p
//im here (3)
NULL
...
avoid dangling pointers by resetting pointer variable value after
the free
(Arrays and Pointers)
31 / 41
32 / 41
33 / 41
34 / 41
buf
buf[0]
buf[1]
STACK
HEAP
double *buf[2];
buf[0] = (double*) malloc(countA*sizeof(double));
buf[1] = (double*) malloc(countB*sizeof(double));
printf("%d, %d ", sizeof(buf[0]), sizeof(buf));
//prints sizeof(ptr), 2*sizeof(ptr)
...
free(buf[1]);
free(buf[0]);
buf is an array[2] of pointers, each entry of which points to a block
35 / 41
buf
buf[0]
buf[1]
STACK
STACK
*(buf[0]+2) or *(buf[1])
double z[4];
double *buf[2];
buf[0] = &z[0];
buf[1] = &z[2];
printf("%d, %d ", sizeof(buf[0]), sizeof(buf));
//prints 4, 8
...
//no need of free calls
36 / 41
*(buf+2)
*(buf+0)
*(buf+1)
STACK
(*(buf+1))[1]
HEAP
double (*buf)[2] =
(double (*)[2])malloc(count*sizeof(double [2]));
printf("%d, %d, %d, %d",
sizeof(double), sizeof(buf[0]),
sizeof(buf[2]), sizeof(buf));
//prints 8, 16, 16, 4 when count is 3
...
free(buf);
buf points to count number of array[2]s of doubles
37 / 41
38 / 41
Homework!
39 / 41
40 / 41
to be continued ...
41 / 41