SlideShare ist ein Scribd-Unternehmen logo
1 von 47
1
Chapter 8
Arrays
Pointers
Strings
**
*
*
WEEK 8
Lecturer: Hamid Milton Mansaray
Phone#: +23276563575
Email: hmmansaray@ccmtsl.com
One-dimensional arrays
An array stores a set of data of the same type.
Note indexing of elements always starts at zero,
so the first entry is a[0] not a[1].
It is sometimes useful to define the size of an array as a symbolic constant:
#define NPOINTS 100
int a[NPOINTS];
The array is then typically processed with a for loop:
for (i = 0; i < NPOINTS; ++i)
sum += a[i];
Changes in size are then taken care of all in one place.
Declaration: int a[size]; /* space for a[0].... a[size-1]
allocated. */
Usage: b=a[expr]; /* expr = integral expression
between 0 and size-1 */
One-dimensional arrays
• The index i is referred to as a subscript. Arrays can be initialized:
float a[5] = { 0.0, 1.0, 2.0, 3.0, 4.0 };
If some but not all elements are initialized, others are set to zero.
External and static arrays are initialized to zero by default anyway;
automatic arrays are not, although some compilers do so.
• Arrays can be declared without size! size is set to the number of
initializers:
float f[] = {0.0, 1.0, 2.0, 3.0, 4.0};
is equivalent to the above.
• For character arrays an alternative is available:
char s[] = “abc”;
is equivalent to
char s[] = {‘a’, ‘b’, ‘c’, ‘0’};
The 0 at the end here is the “end-of-character-string” symbol.
One-dimensional arrays
pointers
A common error is to access elements beyond the end of the array;
e.g. a[N] in an N-element array.
Ensure that subscripts stay within bounds
(Remember array subscript starts at zero!).
float a[5] = {0.0}, b=555.5;
printf(“%fn“,a[5]);
Example:
Wrong, but compiler may not complain!
What do you get for a[5]?
How is a stored in memory?
top of stack
bottom of stack
Address space of a program
text Code Write protected
(segmentation violation!)
0x0000
0xFFFF
Local variables
Function arguments
Return addresses of functions
Typically ~10kB
heap Dynamically allocated variables
top of heap
main
func1
func2
Stack frames:
stack
up close
stack
Global and static variables
bss
Constants (initialized data)
data
Addresses in memory – the & operator
int main(void)
{
int a=2, b=5;
....
}
b
2
5
a
...
... 4 bytes
of memory
Stack region of memory for a simple program
programmer‘s
view
fa44
fa40
fa5c
fa48
computer‘s
view ?
How to get address of a in memory?
&a would return the hex number fa48 in the example
Which variable to assign an address to?
pointers
Pointers
• variables are stored in particular locations, or addresses, in memory
• if v is a variable then &v is the address in memory of its stored value
• pointers are used to access these memory locations directly
Declaration: int *p;
declares that p is a pointer to the address of an int type variable.
If a is an integer, for example, we can then set p = &a;
If p holds the address of a variable, the indirection or dereferencing
operator * gives the value that is held at that address.
think of * as the inverse of &
don’t confuse it with the * used in the int *p declaration
think of int* as the type of p
*p is equivalent to a
Pointer example
int a=2, b=5, *p;
fa48
fa44
fa40
b
2
5
a
? p
2
5
fa48
p = &a; b = *p;
now p points
to variable a
2
2
fa48
b is set to a
p = &b;
2
2
fa44
now p points
to variable b
*p = 8; *(p+1)=3; *p=(int)p; p=(int*)&p;
3
8
fa44
pointer
arithmetic
3
fa44
fa44
typecast
to int
3
fa44
fa40
typecast
to pointer
2
8
fa44
fa48
fa44
fa40
pointer
assignment
Pointers
Exercise:
int i = 3, j = 5, *p = &i, *q = &j, *r;
double x;
Give values for:
*p
**&q
j* *p
j + *&i
j/ *p
* and & are unary operator (check your table for precedence)
Notice the use of a space between / and * to avoid j/*q,
which would have looked like the start of a comment...
do not point at constants (&3), expressions or register variables
Pointer to void
void * is a generic pointer, and can be assigned to any variable type.
However, for good practice you should always “type cast” it into the
appropriate pointer type.
This makes sure that the pointer types agree
p = (int *) v;
If v happens to point to some integer, this is the proper assignement:
Pointer must always have a type that they point to. Exception:
int *p;
void *v;
Example:
Call-by-reference
stack after
two nested
function calls
main
func1
func2
0xFFFF
a
0x0000
int func1(void)
{
int a;
func2(&a);
}
int func2(int *p)
{
....
}
func2 could change a in func1, if it had a pointer to it!
pass the pointer &a as a function argument!
(which itself would of course not be changed)
In C, only copies of variables are passed down to functions as values
How to use a function to change variables in the calling function?
p
Call-by-reference
#include <stdio.h>
void swap(int *, int *);
/*----------------------------------*/
int main(void)
{
int i = 3, j = 5;
swap (&i, &j);
printf(“%d %dn”, i, j); /* 5 3 is printed */
return 0;
}
/*----------------------------------*/
void swap(int *p, int *q)
{
int tmp;
tmp = *p;
*p = *q;
*q = tmp;
}
• Declare a function parameter to be a pointer
• Pass an address as an argument when the function is called
• Use the dereferenced pointer in the function body
function parameters are pointers to int
Pass the addresses of the variables
when calling the function
Inside the function, use the
dereference operator * to access the
values stored at the addresses you
sent down
Exercise: Change this program and make it rotate three variables: i → j, j
→ k and k → i.
Arrays and Pointers
If a is an array, i is an int, and p is a pointer,
a[i] is equivalent to *(a + i);
p[i] is equivalent to *(p + i);
if a is an array of int and p an integer pointer,
p = &a[0]; can be used to point to the first element,
p = &a[1]; to point to the second etc
The address operator can also be applied to array elements
But there‘s a better way!
In C, an array name is an address (or pointer) to the start of the array!
p = a; is equivalent to p = &a[0];
p = a+1; is equivalent to p = &a[1];
a is fixed, so that a = p; is illegal!
pointer arithemtic
Pointer arithmetic
If p and q are both pointing to elements of an array, p - q yields the
int value representing the number of array elements between p and q.
One of the powerful features of C!
If p is a pointer to a particular type, then p+1 yields the correct machine
address of the next variable of that type.
• If p is a pointer to int, then p+1 will point to address ff38
• If p is a pointer to char, then p+1 will point to address ff35
• if p is a pointer to double, then p+1 would point to address ff42
p points to address ff34
Example:
double a[2], *p, *q
p = a; /* points to base of array */
q = p + 1; /* equiv. q = &a[1] */
printf(“%dn”, q - p); /* 1 is printed */
printf(“%dn”, (int)q - (int)p); /* 8 is printed */
Example:
Example: summing an array
for (p = a; p < &a[N]; ++p)
sum += *p;
for (i = 0; i < N; ++i)
sum += *(a + i);
for (p = a, i = 0; i < N; ++i)
sum += p[i];
The following are examples for summing an array a,
with p being a pointer of the proper type of the array
Note however that because a is a constant pointer, expressions such as
a = p; ++a; a += 2 &a;
are illegal. We cannot change the value of a in the way that we can for p.
Exercise: Bubble sort
This is an extremely inefficient sorting algorithm!
Compile and run a program containing this function; then go through the
code, adding comments to ensure that you understand how it works.
(Then forget you ever knew it, and work with a better algorithm instead).
void swap(int *, int *); /* same swap function as before
*/
void bubble(int a[], int n) /* n is size of a */
{
int i,j;
for (i = 0; i < n-1; ++i)
for (j = n - 1; j > i; --j)
if (a[j-1] > a[j])
swap(&a[j-1],&a[j]);
}
Note that the swap function call could also have been written
swap(a + j - 1, a + j);
heap
Dynamic Memory Allocation
sizeof(int) finds the right
element size
calloc returns a pointer to void (i.e. pointer of no particular type) that
points to the start of the assigned space (or to NULL if there is not enough
space on the heap). You should cast the pointer to the proper type!
It is not always known in advance how big an array will
be in running a program. Two ways around this:
text
stack
bss
data
a = (int *) calloc(n,sizeof(int));
1. Set aside huge amounts of memory when writing
the program, and hope that it‘s more than needed
2. Take the memory that is needed “on the fly” from
the „heap“
The latter is obviously more intelligent and flexible.
If you need memory to store n array elements, each
of which is (say) an integer, you do this:
calloc stands for “contiguous allocation”
of memory: grab the memory in one lump
Dynamic Memory Allocation
If a is NULL, free has no effect; if it is the base address of the space
allocated by calloc( ) or malloc( ), the space is deallocated; ortherwise
there is a system-dependent error. If you don’t give the memory back,
but keep on taking more, you will eat it all until the program crashes.
a = (int *) calloc(n, sizeof(int));
int can be replaced with any other type
There is also an alternative:
where total_size = n * element_size.
a = (int *) malloc(total_size);
space allocated by calloc or malloc must be given back explicitly
by
free(a) /* where a is the pointer name */
before exiting the function.
initializes the
space with 0
no initialization
Example 1
a = malloc(n*sizeof(int));
/* allocates space for array a */
fill_array(a,n); /* fill with random nos 1-10 */
wrt_array(a,n); /* writes out the array */
printf("sum = %dnn", sum_array(a,n));
free(a);
Try it and see!
Notes about this code:
• srand(time(NULL)) “seeds” the random-number generator;
• rand() %19 takes the remainder when a random number is divided by
19, to give a random number between 0 and 18, so rand() %19 – 9
gives a random number between –9 and 9)
Example 2
-3 4 7 13 1 2 16
-3 1 2 4 7 13 16
/* Merge a[] of size m and b[] of size n into c[]; from K&P */
#include "mergesort.h“
void merge(int a[], int b[], int c[], int m, int n){
int i = 0, j = 0, k = 0;
while (i < m && j < n) c[k++]=((a[i] < b[j])? a[i++]:b[j++]);
while (i < m) c[k++] = a[i++]; /* pick up any remainder */
while (j < n) c[k++] = b[j++];
}
This is the basis for a standard sorting routine, called mergesort.
We’ll be looking at it in the problem sheet and in the weeks to come.
Pointer basics 1
Pointers contain memory locations
declaration: int *p;
declares that p is a pointer to the
address of an int type variable
dereferencing operator *
int a=2, b=5, *p;
fa48
fa44
fa40
b
a
p
2
5
fa48
How to access the object that p points to?????
*p returns the object
that p is pointing to
in the example,
*p is an integer number
Example:
Pointer basics 2
How to assign an address to p?????
p now points to a
p = &a;
If the object to be
addressed is already
declared, use the
& operator
If the object to be addressed is not declared,
use memory allocation
p = (int *) malloc(sizeof(int));
free(p) to return memory
p now points to the chunk of memory allocated
Object can be
accessed by
a or *p
Object can only be accessed by *p
because it hasn‘t got a name assigned
Memory returned when
a goes out of scope, for
example when function
returns
Arrays and pointers
Declaration: int b[N]; /* space for b[0].... b[N-1]
allocated. */
Usage:
p = (int *) calloc(N, sizeof(int));
p = (int *) malloc(N * sizeof(int));
Pointer arithmetic: p+1
Pointer to array: int *p; p = b;
element_i=b[i]; element_i=p[i];
element_i=*(p + i);
element_i=*(b + i);
array name b is a constant pointer to first array element
points to next array element
Declaration of array with memory allocation:
p is a variable pointer to first array element
int *p;
b = p; is illegal because
b is constant
p is now equivalent to b!
Strings
char astring[] = {'t','h','i','s',' ','i','s',' ',
't','e','d','i','o','u','s',
'n','0'};
In C strings are implemented as 1 dimensional arrays.
The type of the array elements is char
char bstring[] = “this is much better“;
In this case, no explicit 0 is needed (it is added automatically)
The last element must be the null character 0
This terminates the string, so the end of the string can be found
“abc” is a character array of size 4
•“a” is a two-element string, whereas
•‘a’ is a character.
Strings as pointers
Note the difference between arrays and pointer
• char *p = “abcde”;
here, the compiler puts the string constant abcde0 somewhere in memory,
then allocates a pointer that points to its first element.
• char s[] = “abcde”;
here, s is stored in 6 contiguous bytes along with the other variables of the
function. You can’t make “s” point anywhere else than to the start of the string.
The difference between the two ways of declaring strings
is explained in the next two slides!
As with other arrays, strings are treated as pointers:
char *p = “abc”;
printf(“%s %sn”, p, p+1); /* abc bc is printed */
Before scanning to an address, make sure sufficient memory is allocated
char *p = (char*) malloc(21); /* allocate memory to hold string */
scanf(“ %20s”, p); /* reads 20 characters from input */
no & character when pointers are used
String literals
Expressions like “abcd“ are called string literals.
When you include a string literal in
your program, two things happen:
The array elements a b c d 0
are placed somewhere in the data
segment of address space (close
to the code, at low addresses).
top of stack
text
0x0000
0xFFFF
heap
top of heap
stack
bss
d
0
c
b
a
data
this address
is returned
The address of a is returned.
If you want to reuse the string,
you must store the address in a
pointer variable.
(otherwise you will never find it again)
1.
2.
char *p; p = “abcd“;
p
Array of char
top of stack
text
0x0000
0xFFFF
heap
top of heap
bss
data
fixed address
pointed to by s
d
0
c
b
a
stack
char s[] = “abcd“;
This is how an array of char is initialized
Space is created on the stack for
5 characters.
1.
Constant pointer s created
on the stack. The address
it points to can never change!
2.
s
a b c d 0 are put at the proper
addresses s, s+1, s+2, ....
on the stack
3.
s = “abcd“; is illegal, because it attempts to change s
into the address of the string literal
/* Count the number of words in a string (from K & P) */
#include <ctype.h>
int word_cnt(const char *s)
{
int cnt = 0;
while (*s != ‘0’) { /* repeat until end of string */
while (isspace(*s)) /* skip white space */
++s;
if (*s != ‘0’) { /* must have found a word. */
++cnt; /* count it, then ignore all the */
/* rest of the characters in it */
while (!isspace(*s) && *s != ‘0’)
++s; /* skip the word */
}
}
return cnt;
}
Example: Word count
Points to start of array of chars, i.e. a string
Keep going as long as not pointing to end-
of-string char
If char is space, just move s on to next char
Not a space or end-of-string, so have found
a word... increment the word counter
Move on without counting until
we find the next space
String-handling functions
• char *strcat(char *s1, const char *s2)
takes two strings and concatenates (joins) them, putting result in s1.
Programmer must ensure s1 points to adequate space. A pointer to the
string s1 is returned.
• int strcmp(const char *s1, const char *s2)
Returns an integer that is <, equal or > 0 depending on whether s1 is
lexicographically (i.e. alphabetically) less than, equal to or greater than s2.
• char *strcpy(char *s1, const char *s2)
characters in s2 are copied into s1 until 0 is moved. Pointer s1 is returned.
• size_t strlen(const char *s)
returns count of number of characters before 0. (size_t is an integral
unsigned type; usually unsigned int.)
Various string-handling functions are available in the standard library,
if you
#include <string.h>
Implementation of string functions
char *strcat(char *s1, register const char *s2)
{
register char *p = s1;
while (*p)
++p;
while (*p++ = *s2++);
return s1;
}
char *strcpy(char *s1, register const char *s2)
{
register char *p = s1;
while (*p++ = *s2++);
return s1;
}
size_t strlen(const char *s)
{
size_t n;
for (n = 0; *s != '0'; ++s)
++n;
return n;
}
strcat
strcpy
strlen
return pointer
to char
register for
fast execution
iterate until end-of-string
character ‘0‘ is reached
Assignment of strings
char *p;
/* Dynamically allocate space */
p = (char*) malloc(37);
P = “text with no more than 36 characters“;
/* Declare array */
char s[37];
strcpy( s, “text with no more than 36 characters“);
If you don‘t want to assign text to an array of char or to
a dereferenced pointer during initialization, here‘s how to
do it later in the program:
For a string represented by a variable pointer:
For a string represented by an array name:
char str1[ ] = “1 2 3 go”, str2[100], tmp[100];
int a, b, c;
sscanf(str1, “%d%d%d%s”, &a, &b, &c, tmp);
sprintf(str2, “%s %s %d %d %dn”, tmp, tmp,
a, b, c);
printf(“%s”, str2);
Writing to strings: sprintf, sscanf
Read from str1 instead of from keyboard
• sprintf() writes to its first argument, which should be a pointer to char (string).
• sscanf() reads from its first argument instead of from the keyboard.
The functions sprintf()and sscanf()are string versions of the
functions printf()and sscanf(), respectively: they write to and from
strings instead of to and from the screen/keyboard.
Here, sscanf( ) takes input from str1; it reads 3 decimals and a string, putting
them into a, b, c and tmp respectively. Then sprintf( ) writes to str2; or, rather, it
writes characters in memory, beginning at the address str2.
Note that str2 already has adequate memory allocated (100 bytes) to write the whole
of the string – if this weren’t the case there would be an access violation (and crash).
Its output is two strings and three integers. Using printf() to print str2 to the
screen, we see that the output is go go 1 2 3
Note that if we use sscanf() to read from the string again, it starts from the
beginning, not from where it left off.
Read 3 numbers and a
string; put them in the
addresses of a, b, c and
tmp
Multidimensional
arrays
One-dimensional arrays
...
a[1]
a[9]
a[0]
ff64
ff60
ff84
Computer memory is linearly addressed
int a[10];
ideal for representing 1-dimensonal arrays
a
What about 2-dimensional arrays?
a00 a01 a02 a03
a10 a11 a12 a13
a20 a21 a22 a23
a9
...
a1
a0
specify address for first element
a=a[0] and get others by offset
int *p=a;
What is the type of a?
a is pointer to int
for(i=0;i<3;i++) {
for(j=0;j<4;j++) {
a[i][j]=i*10+j;
printf(" %02d",
a[i][j]);
}
printf("n");
}
Two-dimensional arrays in address space
a23
a22
a21
a20
a13
a12
a11
a10
a03
a02
a01
a00
a00 a01 a02 a03
a10 a11 a12 a13
a20 a21 a22 a23
int a[3][4];
declaration:
a[i][j]
usage: int *b = (int*) a;
a[i][j] = *(b+4*i+j);
Base address:
int *b = &a[0][0];
int a[3][4];
b
b+1
b+2
b+3
b+4
a
a+1
a+2
int (*p)[4]=a;
What is the type of a?
a is a pointer to a1D-
array of 4 elements
Two-dimensional arrays
int a[3][4];
Array elements are stored contiguously, one after the other.
Alternative interpretation: three arrays of four arrays of int.
a[i][j]
*(a[i] + j)
(*(a + i))[j]
*((*(a + i)) + j)
*(&a[0][0] + 4*i + j)
Different ways to access element i,j:
3 rows and 4 columns
The array name a by itself is equivalent to &a[0]; it is a pointer to an
array with 4 elements. The base address of the array is &a[0][0].
The mapping between pointer values and array indices is called the
storage mapping function.
The compiler needs to know sizes in advance, because it needs to
know that a new row starts every n elements.
Multi-dimensional arrays
Initialization: Example for a 3D array:
int a[2][2][3] = {{{1,1,0},{2,0,0}}, {{3,0,0},{4,4,0}} };
From here the compiler can work out that the first size is 2. It is possible to
initialize all array elements to zero:
int a[2][2][3] = {0};
a[i][j]
a[i]
a
int a[M][N];
c[i][j][k]
c[i][j]
c[i]
c
int c[L][M][N];
x[i]
x
int x[N];
array element
pointer to element
pointer to array of
N elements
pointer to array of
N*M elements
declaration
Example: Adding array elements
int sum (int a[7] [9] [2]) /* 7x9x2 matrix */
{
int i, j, k, sum = 0;
for (i = 0; i < 7; ++i)
for (j = 0; j < 9; ++j)
for (k = 0; k < 2; ++k)
sum += a[i][j][k];
return sum;
}
Exercise 3:
write a short program in which you initialise a 3x3 matrix (with
numbers 1-9, for example), and then call functions that
(a) multiply
(b) add
all of the elements together, and print out the answer.
Passing arrays to functions
int sumarray(int a[][4]){
int i, j, sum = 0;
for (i=0; i<3; i++)
for (j=0; j<4; j++)
sum += a[i][j];
return sum;
}
int a[3][4], result;
...
result = sumarray(a);
Only the address of the first element is passed to the function
For the correct calculation of addresses, the array size must be
specified for every dimension except the first one
int sumarray(int *a,int n, int m){
int i, j, sum = 0;
for (i=0; i<n; i++)
for (j=0; j<m; j++)
sum += *(a + m*i + j)
return sum;
}
int a[3][4], result;
...
result =
sumarray(a[0],3,4);
This can be avoided only by passing a pointer to the first element
and calculating the adresses yourself:
typedef
Use the typedef command to define new data types in terms of old ones:
typedef int * pointer_to_int;
known type new type
Example:
typedef double scalar;
typedef scalar vector [3];
typedef scalar matrix [3] [3];
typedef vector matrix [3];
or equivalently:
scalar dot_product(vector x, vector y)
{
int i;
scalar sum = 0.0;
for (i = 0; i < N; ++i)
sum += x[i] * y[i];
return sum;
}
Application:
Arrays of pointers
w[6]
w[4]
w[2]
pp
w[5]
w[3]
w[1]
w[0]
w and
pp are
pointer
to pointer
w[i] and
*PP is
pointer
to int
*w[i]
and
**pp
is int
Arrays can be of any type,
including pointers int *w[N];
int **pp=w;
Example:
declaration
Arrays of pointers are more
flexible and faster to move
around than arrays of data.
More efficient use of memory
Applications:
• Alphabetical sorting of words
• Memory management by
operating system
No need to allocate memory in
advance
Ragged arrays
A group of words may be stored as
• a two-dimensional array of type char, or
• a one-dimensional array of pointers to char.
#include <stdio.h>
int main(void)
{
char a[2][9] = {"abc:", "an apple"};
char *p[2] = {"abc:", "an apple"};
printf("%c%c%c %s %sn", a[0][0], a[0][1], a[0][2], a[0], a[1]);
printf("%c%c%c %s %sn", p[0][0], p[0][1], p[0][2], p[0], p[1]);
return 0;
}
Example:
Ragged arrays
char a[2][9] = {"abc:",
"an apple"};
a is a 2D array, and its declaration
causes space for 2x9 = 18 chars to be
allocated. Only the first five elements
‘a’, ‘b’, ‘c’, ‘:’ and ‘0’ are used in a[0];
the rest are initialized to zero.
char *p[2] = {"abc:",
"an apple"};
p is a 1D array of pointers to char.
When it is declared, space for two
pointers is allocated. p[0] is initialized
to point at “abc:”, a string requiring
space for 5 chars. p[1] is initialized to
point at “an apple“ which requires
space for 9 chars. Thus, p does its
work in less space than a; it is also
faster, as no mapping function is
generated.
a b c : 0
a n a p p l e 0 a n a p p l e 0
a b c : 0
An array of pointers whose elements point to arrays
of different sizes is called a ragged array.
Note that a[0][8] is a
valid expression,
but p[0][8] is not.
Dynamic allocation of arrays
Explicitly declared multidimensional arrays have some drawbacks:
• Size of the array must be specified in advance
in the declaration
int a[3][3];
• Functions work only for arrays of a fixed size:
function(int a[][3])
Use array of pointers + memory allocation instead
To get an arbitrary size array of pointers, we dynamically allocate it,
creating a pointer to an array of pointers, each pointing at a 1D array.
This is not suitable for working with matrices of arbitrary size
Dynamic allocation of arrays
int i, j, n; /*i, j matrix indices; n size*/
double **a;
a = (double **) calloc(n, sizeof(double *));
for (i = 0; i < n; ++i)
a[i] = (double *) calloc(n, sizeof(double));
Allocate space for n elements
of size “pointer to double“
Allocate space for the matrix rows
(n elements of double), one at a time
a[1]
...
a[0]
a[n-1]
n
-
1
3
1 2
0
n
-
1
3
1 2
0
n
-
1
3
1 2
0
a
... matrix isn‘t necessarily
stored in a contiguous
block in memory!
Dynamic allocation of arrays
Matrix elements are accessed as usual:
a[i][j] is matrix element (double)
a[i] is pointer to double
Warning: no mapping between pointer values and array indices!
(&a[0][0]+i*n+j)
Memory must be properly returned (in the right order):
int i;
for (i = 0; i < n; ++i)
free(a[i]);
free(a);
function( double **a, n);
function(a,n);
Function calls without a priory knowledge of size:
For 3D arrays of arbitrary size, use pointer-to-pointer-to-pointer-to-double:
double ***a;
Mathematical functions
• There are no built-in mathematical functions in C
• Functions such as
sqrt() exp() log() sin() cos() tan()
are built into the mathematics library.
• All of these take one arguments of type double, and return a
value of type double;
• pow() takes two arguments, base and exponent, of type double
and returns as double.
• In order to use functions from the standard maths library, you
should #include <math.h> at the top of the program, and you
have to have -lm as an argument in your compilation command:
exponent
base

Weitere ähnliche Inhalte

Ähnlich wie ch08.ppt

Pointers in c - Mohammad Salman
Pointers in c - Mohammad SalmanPointers in c - Mohammad Salman
Pointers in c - Mohammad SalmanMohammadSalman129
 
01 stack 20160908_jintaek_seo
01 stack 20160908_jintaek_seo01 stack 20160908_jintaek_seo
01 stack 20160908_jintaek_seoJinTaek Seo
 
Pointers and Dynamic Memory Allocation
Pointers and Dynamic Memory AllocationPointers and Dynamic Memory Allocation
Pointers and Dynamic Memory AllocationRabin BK
 
Unit-I Pointer Data structure.pptx
Unit-I Pointer Data structure.pptxUnit-I Pointer Data structure.pptx
Unit-I Pointer Data structure.pptxajajkhan16
 
btech-1picu-5pointerstructureunionandintrotofilehandling-150122010700-conver.ppt
btech-1picu-5pointerstructureunionandintrotofilehandling-150122010700-conver.pptbtech-1picu-5pointerstructureunionandintrotofilehandling-150122010700-conver.ppt
btech-1picu-5pointerstructureunionandintrotofilehandling-150122010700-conver.pptchintuyadav19
 
The best every notes on c language is here check it out
The best every notes on c language is here check it outThe best every notes on c language is here check it out
The best every notes on c language is here check it outrajatryadav22
 
Ctutorial-Pointers 1.ppt
Ctutorial-Pointers 1.pptCtutorial-Pointers 1.ppt
Ctutorial-Pointers 1.pptDEEPAK948083
 
Improve Your Edge on Machine Learning - Day 1.pptx
Improve Your Edge on Machine Learning - Day 1.pptxImprove Your Edge on Machine Learning - Day 1.pptx
Improve Your Edge on Machine Learning - Day 1.pptxCatherineVania1
 
Pointers and Memory Allocation ESC101.pptx
Pointers and Memory Allocation ESC101.pptxPointers and Memory Allocation ESC101.pptx
Pointers and Memory Allocation ESC101.pptxkrishna50blogging
 
Pointers (Pp Tminimizer)
Pointers (Pp Tminimizer)Pointers (Pp Tminimizer)
Pointers (Pp Tminimizer)tech4us
 
358 33 powerpoint-slides_3-pointers_chapter-3
358 33 powerpoint-slides_3-pointers_chapter-3358 33 powerpoint-slides_3-pointers_chapter-3
358 33 powerpoint-slides_3-pointers_chapter-3sumitbardhan
 
Programming in C sesion 2
Programming in C sesion 2Programming in C sesion 2
Programming in C sesion 2Prerna Sharma
 
Programming fundamentals 2:pointers in c++ clearly explained
Programming fundamentals 2:pointers in c++ clearly explainedProgramming fundamentals 2:pointers in c++ clearly explained
Programming fundamentals 2:pointers in c++ clearly explainedhozaifafadl
 
Mca 1 pic u-5 pointer, structure ,union and intro to file handling
Mca 1 pic u-5 pointer, structure ,union and intro to file handlingMca 1 pic u-5 pointer, structure ,union and intro to file handling
Mca 1 pic u-5 pointer, structure ,union and intro to file handlingRai University
 

Ähnlich wie ch08.ppt (20)

Pointer in C
Pointer in CPointer in C
Pointer in C
 
Pointers in c - Mohammad Salman
Pointers in c - Mohammad SalmanPointers in c - Mohammad Salman
Pointers in c - Mohammad Salman
 
01 stack 20160908_jintaek_seo
01 stack 20160908_jintaek_seo01 stack 20160908_jintaek_seo
01 stack 20160908_jintaek_seo
 
Pointers and Dynamic Memory Allocation
Pointers and Dynamic Memory AllocationPointers and Dynamic Memory Allocation
Pointers and Dynamic Memory Allocation
 
Unit-I Pointer Data structure.pptx
Unit-I Pointer Data structure.pptxUnit-I Pointer Data structure.pptx
Unit-I Pointer Data structure.pptx
 
btech-1picu-5pointerstructureunionandintrotofilehandling-150122010700-conver.ppt
btech-1picu-5pointerstructureunionandintrotofilehandling-150122010700-conver.pptbtech-1picu-5pointerstructureunionandintrotofilehandling-150122010700-conver.ppt
btech-1picu-5pointerstructureunionandintrotofilehandling-150122010700-conver.ppt
 
CPP Homework Help
CPP Homework HelpCPP Homework Help
CPP Homework Help
 
The best every notes on c language is here check it out
The best every notes on c language is here check it outThe best every notes on c language is here check it out
The best every notes on c language is here check it out
 
C programming
C programmingC programming
C programming
 
See through C
See through CSee through C
See through C
 
Ctutorial-Pointers 1.ppt
Ctutorial-Pointers 1.pptCtutorial-Pointers 1.ppt
Ctutorial-Pointers 1.ppt
 
Improve Your Edge on Machine Learning - Day 1.pptx
Improve Your Edge on Machine Learning - Day 1.pptxImprove Your Edge on Machine Learning - Day 1.pptx
Improve Your Edge on Machine Learning - Day 1.pptx
 
C Programming - Refresher - Part III
C Programming - Refresher - Part IIIC Programming - Refresher - Part III
C Programming - Refresher - Part III
 
Pointers and Memory Allocation ESC101.pptx
Pointers and Memory Allocation ESC101.pptxPointers and Memory Allocation ESC101.pptx
Pointers and Memory Allocation ESC101.pptx
 
Pointers (Pp Tminimizer)
Pointers (Pp Tminimizer)Pointers (Pp Tminimizer)
Pointers (Pp Tminimizer)
 
358 33 powerpoint-slides_3-pointers_chapter-3
358 33 powerpoint-slides_3-pointers_chapter-3358 33 powerpoint-slides_3-pointers_chapter-3
358 33 powerpoint-slides_3-pointers_chapter-3
 
Pointer
PointerPointer
Pointer
 
Programming in C sesion 2
Programming in C sesion 2Programming in C sesion 2
Programming in C sesion 2
 
Programming fundamentals 2:pointers in c++ clearly explained
Programming fundamentals 2:pointers in c++ clearly explainedProgramming fundamentals 2:pointers in c++ clearly explained
Programming fundamentals 2:pointers in c++ clearly explained
 
Mca 1 pic u-5 pointer, structure ,union and intro to file handling
Mca 1 pic u-5 pointer, structure ,union and intro to file handlingMca 1 pic u-5 pointer, structure ,union and intro to file handling
Mca 1 pic u-5 pointer, structure ,union and intro to file handling
 

ch08.ppt

  • 1. 1 Chapter 8 Arrays Pointers Strings ** * * WEEK 8 Lecturer: Hamid Milton Mansaray Phone#: +23276563575 Email: hmmansaray@ccmtsl.com
  • 2. One-dimensional arrays An array stores a set of data of the same type. Note indexing of elements always starts at zero, so the first entry is a[0] not a[1]. It is sometimes useful to define the size of an array as a symbolic constant: #define NPOINTS 100 int a[NPOINTS]; The array is then typically processed with a for loop: for (i = 0; i < NPOINTS; ++i) sum += a[i]; Changes in size are then taken care of all in one place. Declaration: int a[size]; /* space for a[0].... a[size-1] allocated. */ Usage: b=a[expr]; /* expr = integral expression between 0 and size-1 */
  • 3. One-dimensional arrays • The index i is referred to as a subscript. Arrays can be initialized: float a[5] = { 0.0, 1.0, 2.0, 3.0, 4.0 }; If some but not all elements are initialized, others are set to zero. External and static arrays are initialized to zero by default anyway; automatic arrays are not, although some compilers do so. • Arrays can be declared without size! size is set to the number of initializers: float f[] = {0.0, 1.0, 2.0, 3.0, 4.0}; is equivalent to the above. • For character arrays an alternative is available: char s[] = “abc”; is equivalent to char s[] = {‘a’, ‘b’, ‘c’, ‘0’}; The 0 at the end here is the “end-of-character-string” symbol.
  • 4. One-dimensional arrays pointers A common error is to access elements beyond the end of the array; e.g. a[N] in an N-element array. Ensure that subscripts stay within bounds (Remember array subscript starts at zero!). float a[5] = {0.0}, b=555.5; printf(“%fn“,a[5]); Example: Wrong, but compiler may not complain! What do you get for a[5]? How is a stored in memory?
  • 5. top of stack bottom of stack Address space of a program text Code Write protected (segmentation violation!) 0x0000 0xFFFF Local variables Function arguments Return addresses of functions Typically ~10kB heap Dynamically allocated variables top of heap main func1 func2 Stack frames: stack up close stack Global and static variables bss Constants (initialized data) data
  • 6. Addresses in memory – the & operator int main(void) { int a=2, b=5; .... } b 2 5 a ... ... 4 bytes of memory Stack region of memory for a simple program programmer‘s view fa44 fa40 fa5c fa48 computer‘s view ? How to get address of a in memory? &a would return the hex number fa48 in the example Which variable to assign an address to? pointers
  • 7. Pointers • variables are stored in particular locations, or addresses, in memory • if v is a variable then &v is the address in memory of its stored value • pointers are used to access these memory locations directly Declaration: int *p; declares that p is a pointer to the address of an int type variable. If a is an integer, for example, we can then set p = &a; If p holds the address of a variable, the indirection or dereferencing operator * gives the value that is held at that address. think of * as the inverse of & don’t confuse it with the * used in the int *p declaration think of int* as the type of p *p is equivalent to a
  • 8. Pointer example int a=2, b=5, *p; fa48 fa44 fa40 b 2 5 a ? p 2 5 fa48 p = &a; b = *p; now p points to variable a 2 2 fa48 b is set to a p = &b; 2 2 fa44 now p points to variable b *p = 8; *(p+1)=3; *p=(int)p; p=(int*)&p; 3 8 fa44 pointer arithmetic 3 fa44 fa44 typecast to int 3 fa44 fa40 typecast to pointer 2 8 fa44 fa48 fa44 fa40 pointer assignment
  • 9. Pointers Exercise: int i = 3, j = 5, *p = &i, *q = &j, *r; double x; Give values for: *p **&q j* *p j + *&i j/ *p * and & are unary operator (check your table for precedence) Notice the use of a space between / and * to avoid j/*q, which would have looked like the start of a comment... do not point at constants (&3), expressions or register variables
  • 10. Pointer to void void * is a generic pointer, and can be assigned to any variable type. However, for good practice you should always “type cast” it into the appropriate pointer type. This makes sure that the pointer types agree p = (int *) v; If v happens to point to some integer, this is the proper assignement: Pointer must always have a type that they point to. Exception: int *p; void *v; Example:
  • 11. Call-by-reference stack after two nested function calls main func1 func2 0xFFFF a 0x0000 int func1(void) { int a; func2(&a); } int func2(int *p) { .... } func2 could change a in func1, if it had a pointer to it! pass the pointer &a as a function argument! (which itself would of course not be changed) In C, only copies of variables are passed down to functions as values How to use a function to change variables in the calling function? p
  • 12. Call-by-reference #include <stdio.h> void swap(int *, int *); /*----------------------------------*/ int main(void) { int i = 3, j = 5; swap (&i, &j); printf(“%d %dn”, i, j); /* 5 3 is printed */ return 0; } /*----------------------------------*/ void swap(int *p, int *q) { int tmp; tmp = *p; *p = *q; *q = tmp; } • Declare a function parameter to be a pointer • Pass an address as an argument when the function is called • Use the dereferenced pointer in the function body function parameters are pointers to int Pass the addresses of the variables when calling the function Inside the function, use the dereference operator * to access the values stored at the addresses you sent down Exercise: Change this program and make it rotate three variables: i → j, j → k and k → i.
  • 13. Arrays and Pointers If a is an array, i is an int, and p is a pointer, a[i] is equivalent to *(a + i); p[i] is equivalent to *(p + i); if a is an array of int and p an integer pointer, p = &a[0]; can be used to point to the first element, p = &a[1]; to point to the second etc The address operator can also be applied to array elements But there‘s a better way! In C, an array name is an address (or pointer) to the start of the array! p = a; is equivalent to p = &a[0]; p = a+1; is equivalent to p = &a[1]; a is fixed, so that a = p; is illegal! pointer arithemtic
  • 14. Pointer arithmetic If p and q are both pointing to elements of an array, p - q yields the int value representing the number of array elements between p and q. One of the powerful features of C! If p is a pointer to a particular type, then p+1 yields the correct machine address of the next variable of that type. • If p is a pointer to int, then p+1 will point to address ff38 • If p is a pointer to char, then p+1 will point to address ff35 • if p is a pointer to double, then p+1 would point to address ff42 p points to address ff34 Example: double a[2], *p, *q p = a; /* points to base of array */ q = p + 1; /* equiv. q = &a[1] */ printf(“%dn”, q - p); /* 1 is printed */ printf(“%dn”, (int)q - (int)p); /* 8 is printed */ Example:
  • 15. Example: summing an array for (p = a; p < &a[N]; ++p) sum += *p; for (i = 0; i < N; ++i) sum += *(a + i); for (p = a, i = 0; i < N; ++i) sum += p[i]; The following are examples for summing an array a, with p being a pointer of the proper type of the array Note however that because a is a constant pointer, expressions such as a = p; ++a; a += 2 &a; are illegal. We cannot change the value of a in the way that we can for p.
  • 16. Exercise: Bubble sort This is an extremely inefficient sorting algorithm! Compile and run a program containing this function; then go through the code, adding comments to ensure that you understand how it works. (Then forget you ever knew it, and work with a better algorithm instead). void swap(int *, int *); /* same swap function as before */ void bubble(int a[], int n) /* n is size of a */ { int i,j; for (i = 0; i < n-1; ++i) for (j = n - 1; j > i; --j) if (a[j-1] > a[j]) swap(&a[j-1],&a[j]); } Note that the swap function call could also have been written swap(a + j - 1, a + j);
  • 17. heap Dynamic Memory Allocation sizeof(int) finds the right element size calloc returns a pointer to void (i.e. pointer of no particular type) that points to the start of the assigned space (or to NULL if there is not enough space on the heap). You should cast the pointer to the proper type! It is not always known in advance how big an array will be in running a program. Two ways around this: text stack bss data a = (int *) calloc(n,sizeof(int)); 1. Set aside huge amounts of memory when writing the program, and hope that it‘s more than needed 2. Take the memory that is needed “on the fly” from the „heap“ The latter is obviously more intelligent and flexible. If you need memory to store n array elements, each of which is (say) an integer, you do this: calloc stands for “contiguous allocation” of memory: grab the memory in one lump
  • 18. Dynamic Memory Allocation If a is NULL, free has no effect; if it is the base address of the space allocated by calloc( ) or malloc( ), the space is deallocated; ortherwise there is a system-dependent error. If you don’t give the memory back, but keep on taking more, you will eat it all until the program crashes. a = (int *) calloc(n, sizeof(int)); int can be replaced with any other type There is also an alternative: where total_size = n * element_size. a = (int *) malloc(total_size); space allocated by calloc or malloc must be given back explicitly by free(a) /* where a is the pointer name */ before exiting the function. initializes the space with 0 no initialization
  • 19. Example 1 a = malloc(n*sizeof(int)); /* allocates space for array a */ fill_array(a,n); /* fill with random nos 1-10 */ wrt_array(a,n); /* writes out the array */ printf("sum = %dnn", sum_array(a,n)); free(a); Try it and see! Notes about this code: • srand(time(NULL)) “seeds” the random-number generator; • rand() %19 takes the remainder when a random number is divided by 19, to give a random number between 0 and 18, so rand() %19 – 9 gives a random number between –9 and 9)
  • 20. Example 2 -3 4 7 13 1 2 16 -3 1 2 4 7 13 16 /* Merge a[] of size m and b[] of size n into c[]; from K&P */ #include "mergesort.h“ void merge(int a[], int b[], int c[], int m, int n){ int i = 0, j = 0, k = 0; while (i < m && j < n) c[k++]=((a[i] < b[j])? a[i++]:b[j++]); while (i < m) c[k++] = a[i++]; /* pick up any remainder */ while (j < n) c[k++] = b[j++]; } This is the basis for a standard sorting routine, called mergesort. We’ll be looking at it in the problem sheet and in the weeks to come.
  • 21. Pointer basics 1 Pointers contain memory locations declaration: int *p; declares that p is a pointer to the address of an int type variable dereferencing operator * int a=2, b=5, *p; fa48 fa44 fa40 b a p 2 5 fa48 How to access the object that p points to????? *p returns the object that p is pointing to in the example, *p is an integer number Example:
  • 22. Pointer basics 2 How to assign an address to p????? p now points to a p = &a; If the object to be addressed is already declared, use the & operator If the object to be addressed is not declared, use memory allocation p = (int *) malloc(sizeof(int)); free(p) to return memory p now points to the chunk of memory allocated Object can be accessed by a or *p Object can only be accessed by *p because it hasn‘t got a name assigned Memory returned when a goes out of scope, for example when function returns
  • 23. Arrays and pointers Declaration: int b[N]; /* space for b[0].... b[N-1] allocated. */ Usage: p = (int *) calloc(N, sizeof(int)); p = (int *) malloc(N * sizeof(int)); Pointer arithmetic: p+1 Pointer to array: int *p; p = b; element_i=b[i]; element_i=p[i]; element_i=*(p + i); element_i=*(b + i); array name b is a constant pointer to first array element points to next array element Declaration of array with memory allocation: p is a variable pointer to first array element int *p; b = p; is illegal because b is constant p is now equivalent to b!
  • 24. Strings char astring[] = {'t','h','i','s',' ','i','s',' ', 't','e','d','i','o','u','s', 'n','0'}; In C strings are implemented as 1 dimensional arrays. The type of the array elements is char char bstring[] = “this is much better“; In this case, no explicit 0 is needed (it is added automatically) The last element must be the null character 0 This terminates the string, so the end of the string can be found “abc” is a character array of size 4 •“a” is a two-element string, whereas •‘a’ is a character.
  • 25. Strings as pointers Note the difference between arrays and pointer • char *p = “abcde”; here, the compiler puts the string constant abcde0 somewhere in memory, then allocates a pointer that points to its first element. • char s[] = “abcde”; here, s is stored in 6 contiguous bytes along with the other variables of the function. You can’t make “s” point anywhere else than to the start of the string. The difference between the two ways of declaring strings is explained in the next two slides! As with other arrays, strings are treated as pointers: char *p = “abc”; printf(“%s %sn”, p, p+1); /* abc bc is printed */ Before scanning to an address, make sure sufficient memory is allocated char *p = (char*) malloc(21); /* allocate memory to hold string */ scanf(“ %20s”, p); /* reads 20 characters from input */ no & character when pointers are used
  • 26. String literals Expressions like “abcd“ are called string literals. When you include a string literal in your program, two things happen: The array elements a b c d 0 are placed somewhere in the data segment of address space (close to the code, at low addresses). top of stack text 0x0000 0xFFFF heap top of heap stack bss d 0 c b a data this address is returned The address of a is returned. If you want to reuse the string, you must store the address in a pointer variable. (otherwise you will never find it again) 1. 2. char *p; p = “abcd“; p
  • 27. Array of char top of stack text 0x0000 0xFFFF heap top of heap bss data fixed address pointed to by s d 0 c b a stack char s[] = “abcd“; This is how an array of char is initialized Space is created on the stack for 5 characters. 1. Constant pointer s created on the stack. The address it points to can never change! 2. s a b c d 0 are put at the proper addresses s, s+1, s+2, .... on the stack 3. s = “abcd“; is illegal, because it attempts to change s into the address of the string literal
  • 28. /* Count the number of words in a string (from K & P) */ #include <ctype.h> int word_cnt(const char *s) { int cnt = 0; while (*s != ‘0’) { /* repeat until end of string */ while (isspace(*s)) /* skip white space */ ++s; if (*s != ‘0’) { /* must have found a word. */ ++cnt; /* count it, then ignore all the */ /* rest of the characters in it */ while (!isspace(*s) && *s != ‘0’) ++s; /* skip the word */ } } return cnt; } Example: Word count Points to start of array of chars, i.e. a string Keep going as long as not pointing to end- of-string char If char is space, just move s on to next char Not a space or end-of-string, so have found a word... increment the word counter Move on without counting until we find the next space
  • 29. String-handling functions • char *strcat(char *s1, const char *s2) takes two strings and concatenates (joins) them, putting result in s1. Programmer must ensure s1 points to adequate space. A pointer to the string s1 is returned. • int strcmp(const char *s1, const char *s2) Returns an integer that is <, equal or > 0 depending on whether s1 is lexicographically (i.e. alphabetically) less than, equal to or greater than s2. • char *strcpy(char *s1, const char *s2) characters in s2 are copied into s1 until 0 is moved. Pointer s1 is returned. • size_t strlen(const char *s) returns count of number of characters before 0. (size_t is an integral unsigned type; usually unsigned int.) Various string-handling functions are available in the standard library, if you #include <string.h>
  • 30. Implementation of string functions char *strcat(char *s1, register const char *s2) { register char *p = s1; while (*p) ++p; while (*p++ = *s2++); return s1; } char *strcpy(char *s1, register const char *s2) { register char *p = s1; while (*p++ = *s2++); return s1; } size_t strlen(const char *s) { size_t n; for (n = 0; *s != '0'; ++s) ++n; return n; } strcat strcpy strlen return pointer to char register for fast execution iterate until end-of-string character ‘0‘ is reached
  • 31. Assignment of strings char *p; /* Dynamically allocate space */ p = (char*) malloc(37); P = “text with no more than 36 characters“; /* Declare array */ char s[37]; strcpy( s, “text with no more than 36 characters“); If you don‘t want to assign text to an array of char or to a dereferenced pointer during initialization, here‘s how to do it later in the program: For a string represented by a variable pointer: For a string represented by an array name:
  • 32. char str1[ ] = “1 2 3 go”, str2[100], tmp[100]; int a, b, c; sscanf(str1, “%d%d%d%s”, &a, &b, &c, tmp); sprintf(str2, “%s %s %d %d %dn”, tmp, tmp, a, b, c); printf(“%s”, str2); Writing to strings: sprintf, sscanf Read from str1 instead of from keyboard • sprintf() writes to its first argument, which should be a pointer to char (string). • sscanf() reads from its first argument instead of from the keyboard. The functions sprintf()and sscanf()are string versions of the functions printf()and sscanf(), respectively: they write to and from strings instead of to and from the screen/keyboard. Here, sscanf( ) takes input from str1; it reads 3 decimals and a string, putting them into a, b, c and tmp respectively. Then sprintf( ) writes to str2; or, rather, it writes characters in memory, beginning at the address str2. Note that str2 already has adequate memory allocated (100 bytes) to write the whole of the string – if this weren’t the case there would be an access violation (and crash). Its output is two strings and three integers. Using printf() to print str2 to the screen, we see that the output is go go 1 2 3 Note that if we use sscanf() to read from the string again, it starts from the beginning, not from where it left off. Read 3 numbers and a string; put them in the addresses of a, b, c and tmp
  • 34. One-dimensional arrays ... a[1] a[9] a[0] ff64 ff60 ff84 Computer memory is linearly addressed int a[10]; ideal for representing 1-dimensonal arrays a What about 2-dimensional arrays? a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23 a9 ... a1 a0 specify address for first element a=a[0] and get others by offset int *p=a; What is the type of a? a is pointer to int
  • 35. for(i=0;i<3;i++) { for(j=0;j<4;j++) { a[i][j]=i*10+j; printf(" %02d", a[i][j]); } printf("n"); } Two-dimensional arrays in address space a23 a22 a21 a20 a13 a12 a11 a10 a03 a02 a01 a00 a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23 int a[3][4]; declaration: a[i][j] usage: int *b = (int*) a; a[i][j] = *(b+4*i+j); Base address: int *b = &a[0][0]; int a[3][4]; b b+1 b+2 b+3 b+4 a a+1 a+2 int (*p)[4]=a; What is the type of a? a is a pointer to a1D- array of 4 elements
  • 36. Two-dimensional arrays int a[3][4]; Array elements are stored contiguously, one after the other. Alternative interpretation: three arrays of four arrays of int. a[i][j] *(a[i] + j) (*(a + i))[j] *((*(a + i)) + j) *(&a[0][0] + 4*i + j) Different ways to access element i,j: 3 rows and 4 columns The array name a by itself is equivalent to &a[0]; it is a pointer to an array with 4 elements. The base address of the array is &a[0][0]. The mapping between pointer values and array indices is called the storage mapping function. The compiler needs to know sizes in advance, because it needs to know that a new row starts every n elements.
  • 37. Multi-dimensional arrays Initialization: Example for a 3D array: int a[2][2][3] = {{{1,1,0},{2,0,0}}, {{3,0,0},{4,4,0}} }; From here the compiler can work out that the first size is 2. It is possible to initialize all array elements to zero: int a[2][2][3] = {0}; a[i][j] a[i] a int a[M][N]; c[i][j][k] c[i][j] c[i] c int c[L][M][N]; x[i] x int x[N]; array element pointer to element pointer to array of N elements pointer to array of N*M elements declaration
  • 38. Example: Adding array elements int sum (int a[7] [9] [2]) /* 7x9x2 matrix */ { int i, j, k, sum = 0; for (i = 0; i < 7; ++i) for (j = 0; j < 9; ++j) for (k = 0; k < 2; ++k) sum += a[i][j][k]; return sum; } Exercise 3: write a short program in which you initialise a 3x3 matrix (with numbers 1-9, for example), and then call functions that (a) multiply (b) add all of the elements together, and print out the answer.
  • 39. Passing arrays to functions int sumarray(int a[][4]){ int i, j, sum = 0; for (i=0; i<3; i++) for (j=0; j<4; j++) sum += a[i][j]; return sum; } int a[3][4], result; ... result = sumarray(a); Only the address of the first element is passed to the function For the correct calculation of addresses, the array size must be specified for every dimension except the first one int sumarray(int *a,int n, int m){ int i, j, sum = 0; for (i=0; i<n; i++) for (j=0; j<m; j++) sum += *(a + m*i + j) return sum; } int a[3][4], result; ... result = sumarray(a[0],3,4); This can be avoided only by passing a pointer to the first element and calculating the adresses yourself:
  • 40. typedef Use the typedef command to define new data types in terms of old ones: typedef int * pointer_to_int; known type new type Example: typedef double scalar; typedef scalar vector [3]; typedef scalar matrix [3] [3]; typedef vector matrix [3]; or equivalently: scalar dot_product(vector x, vector y) { int i; scalar sum = 0.0; for (i = 0; i < N; ++i) sum += x[i] * y[i]; return sum; } Application:
  • 41. Arrays of pointers w[6] w[4] w[2] pp w[5] w[3] w[1] w[0] w and pp are pointer to pointer w[i] and *PP is pointer to int *w[i] and **pp is int Arrays can be of any type, including pointers int *w[N]; int **pp=w; Example: declaration Arrays of pointers are more flexible and faster to move around than arrays of data. More efficient use of memory Applications: • Alphabetical sorting of words • Memory management by operating system No need to allocate memory in advance
  • 42. Ragged arrays A group of words may be stored as • a two-dimensional array of type char, or • a one-dimensional array of pointers to char. #include <stdio.h> int main(void) { char a[2][9] = {"abc:", "an apple"}; char *p[2] = {"abc:", "an apple"}; printf("%c%c%c %s %sn", a[0][0], a[0][1], a[0][2], a[0], a[1]); printf("%c%c%c %s %sn", p[0][0], p[0][1], p[0][2], p[0], p[1]); return 0; } Example:
  • 43. Ragged arrays char a[2][9] = {"abc:", "an apple"}; a is a 2D array, and its declaration causes space for 2x9 = 18 chars to be allocated. Only the first five elements ‘a’, ‘b’, ‘c’, ‘:’ and ‘0’ are used in a[0]; the rest are initialized to zero. char *p[2] = {"abc:", "an apple"}; p is a 1D array of pointers to char. When it is declared, space for two pointers is allocated. p[0] is initialized to point at “abc:”, a string requiring space for 5 chars. p[1] is initialized to point at “an apple“ which requires space for 9 chars. Thus, p does its work in less space than a; it is also faster, as no mapping function is generated. a b c : 0 a n a p p l e 0 a n a p p l e 0 a b c : 0 An array of pointers whose elements point to arrays of different sizes is called a ragged array. Note that a[0][8] is a valid expression, but p[0][8] is not.
  • 44. Dynamic allocation of arrays Explicitly declared multidimensional arrays have some drawbacks: • Size of the array must be specified in advance in the declaration int a[3][3]; • Functions work only for arrays of a fixed size: function(int a[][3]) Use array of pointers + memory allocation instead To get an arbitrary size array of pointers, we dynamically allocate it, creating a pointer to an array of pointers, each pointing at a 1D array. This is not suitable for working with matrices of arbitrary size
  • 45. Dynamic allocation of arrays int i, j, n; /*i, j matrix indices; n size*/ double **a; a = (double **) calloc(n, sizeof(double *)); for (i = 0; i < n; ++i) a[i] = (double *) calloc(n, sizeof(double)); Allocate space for n elements of size “pointer to double“ Allocate space for the matrix rows (n elements of double), one at a time a[1] ... a[0] a[n-1] n - 1 3 1 2 0 n - 1 3 1 2 0 n - 1 3 1 2 0 a ... matrix isn‘t necessarily stored in a contiguous block in memory!
  • 46. Dynamic allocation of arrays Matrix elements are accessed as usual: a[i][j] is matrix element (double) a[i] is pointer to double Warning: no mapping between pointer values and array indices! (&a[0][0]+i*n+j) Memory must be properly returned (in the right order): int i; for (i = 0; i < n; ++i) free(a[i]); free(a); function( double **a, n); function(a,n); Function calls without a priory knowledge of size: For 3D arrays of arbitrary size, use pointer-to-pointer-to-pointer-to-double: double ***a;
  • 47. Mathematical functions • There are no built-in mathematical functions in C • Functions such as sqrt() exp() log() sin() cos() tan() are built into the mathematics library. • All of these take one arguments of type double, and return a value of type double; • pow() takes two arguments, base and exponent, of type double and returns as double. • In order to use functions from the standard maths library, you should #include <math.h> at the top of the program, and you have to have -lm as an argument in your compilation command: exponent base