View
225
Download
0
Category
Tags:
Preview:
Citation preview
ספטמבר 04 Copyright Meir Kalech 1
C programming Language
Chapter 4 :Arrays and Strings
ספטמבר 04 Copyright Meir Kalech 2
Assume a C program stores the ages of 3 children. Which variables should we define?
Very good! But defining 3 variables is petty easy. Let’s think
about say 10 children (to be continued ), so should the programmer define 10 variables, or more…???
An array can better solve this problem by defining multiple similar variables using a single definition.
The definition contains: type, name and number of requested elements.
All the variables will be created sequentially in the memory.
Array Structure
ספטמבר 04 Copyright Meir Kalech 3
int ages[10];
Name of the array = First address of the array
Array Definition
Elements type Array name Number of elements
100104108112116120124128132136
??????????
0123456789
address
value
index
ספטמבר 04 Copyright Meir Kalech 4
sizeof() operator gets a type or variable and returns its size in bytes. For example:
int x;printf(“%d”, sizeof(int)); // print 4printf(“%d”, sizeof(x)); // print 4
Array subscripting operator [] denotes an index in an array and enables access to the value of the addressed array index. For example:
int ages[10]; // definitionages[3] = 23; // access printf(“%d”, ages[3]); // access
What is sizeof(ages)?
Array Definition
4 * 10 = 40
ספטמבר 04 Copyright Meir Kalech 5
Array Subscripting Operator][
100104108112116120124128132136
???23??????0123456789
ages[3] ages[5]
Explanation: “ages” is the first address of the array (100) .ages[3]: ages+3*sizeof(int)
We get the address of the fourth element. Then operator [] accesses the value of that address.
ספטמבר 04 Copyright Meir Kalech 6
DANGEROUS!!!Be careful!!! This address is not
allocated to your program
Array Subscripting Operator][
100104108112116120124128132136140
???23???????012345678910
What happens when accessing the 10’th place of ages: ages[10] = 30???
ages[10]
ספטמבר 04 Copyright Meir Kalech 7
No boundary checks are performed by the computer. Size (number of elements) must be constant – requested
amount of memory must be known at compilation time:int i = 5;int array[i]; // wrong, i is not a constant!
However:
#define SIZE 5
int array[SIZE]; // OK, SIZE is a symbolic constant! C does not have any operator to work with an array “as a
whole”: For instance: we can’t assign into an array multiple values at
once; we can’t print all the array at once, etc… question: what is the output of - printf(“%p”, ages);
Notes on Arrays
100printf(“%p”, ages);
ספטמבר 04 Copyright Meir Kalech 8
Array Initialization Within declaration (using an initialization list):
int array[5] = {5,8,2,7};
If the size of array is not specified, size is determined by the number of initializing values provided:
int array[] = {5,8,2,7};
Looping through the elements and assigning them a value:int array[5], i;for (i = 0; i < 5; ++i) array[i] = i; // or scanf(“%d”, &array[i]);
58270
01234
5827
0123
Automatically initialized to 0
ספטמבר 04 Copyright Meir Kalech 9
ExampleReverse an array:#define SIZE 5int array[SIZE]={1,2,3,4}, temp, i, j;for (i=0,j=SIZE-1; i<j; i++,j--)
{ temp = array[i];
array[i] = array[j];
array[j] = temp;
}
1234001234
Array initialization
ספטמבר 04 Copyright Meir Kalech 10
Example First iteration:
1234001234
temp
i=0 j=4
ספטמבר 04 Copyright Meir Kalech 11
Example First iteration:
1234001234
1 temp
i=0 j=4 temp = array]i[;
ספטמבר 04 Copyright Meir Kalech 12
Example First iteration:
0234001234
1 temp
i=0 j=4
array]i[ = array]j[;
ספטמבר 04 Copyright Meir Kalech 13
Example First iteration:
0234101234
1 temp
i=0 j=4
array]j[ = temp;
ספטמבר 04 Copyright Meir Kalech 14
Example First iteration:
0234101234
1 temp
i=1 j=3
i++, j--
ספטמבר 04 Copyright Meir Kalech 15
Example Second iteration:
0234101234
2 temp
i=1 j=3 temp = array]i[;
ספטמבר 04 Copyright Meir Kalech 16
Example Second iteration:
0434101234
2 temp
i=1 j=3
array]i[ = array]j[;
ספטמבר 04 Copyright Meir Kalech 17
Example Second iteration:
2 temp
i=1 j=3
array]j] = temp;
0432101234
ספטמבר 04 Copyright Meir Kalech 18
Example Second iteration:
0432101234
2 temp
i=2 j=2
i++, j--
i is not smaller than jso STOP!!!
ספטמבר 04 Copyright Meir Kalech 19
Two-dimensional Array Two-dimensional (2D) array is an array of arrays. For instance:
the definition int matrix[3][4] means 3 arrays of 4 integers each.
As for a one-dimensional (1D) array, the elements will be created sequentially in memory (in row-major order).
So what is the difference between the two???
?????43210
?????98765
??1110
116112108104100 136132128124120 144140
ספטמבר 04 Copyright Meir Kalech 20
Two-dimensional Array The difference is in the way of access to the elements. Single operator [] is used for access to elements
in a one-dimensional array. Double operator [][] (not [ , ]) is used for access to a
two-dimensional array: The first [] locates the requested array (the line). The second [] locates the requested element in the line array
(the column). Conclusion:
physically: one-dimensional and multi-dimensional arrays are the same.
Logically: one-dimensional is used as a single list of elements while two-dimensional is used as a multi-list of elements.
ספטמבר 04 Copyright Meir Kalech 21
Two-dimensional Array Example
int matrix]3[]4[;
0123
0????
1????
2????
Columns’ index
Lines’ index
matrix[1][3]:Line: 1
Column: 3
matrix[0][0]:Line: 0
Column: 0
matrix[3][4]:Line:3
Column: 4
What is the address of this
element?
Address:100
124Not accessible
ספטמבר 04 Copyright Meir Kalech 22
Two-dimensional Array Example
Usually, a two-dimensional array stores multiple sets of elements. For instance, suppose I have only 10 students (wish I had ) and each student has 5 courses. The goal is to store the courses’ grades of students. We have 3 options:
1. Defining an array of 50 grades.2. Defining 10 arrays of 5 grades each.3. Defining a matrix of 10 lines and 5 columns.
Obviously the third option is the best. It is easier for the programmer to access the elements of a matrix. For example, getting an input to the third course of the fourth student is:int grades[10][5];scanf(“%d”, &grades[3][2]);
ספטמבר 04 Copyright Meir Kalech 23
Two-dimensional Array Initialization
Looping through the elements and assigning them a value (or input):
int matrix[4][3], i, j; for (i=0; i<4; i++)
for (j=0; j<3; j++) matrix[i][j] = i * j;
In definition (using an initialization list): int matrix[4][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
OR int matrix[4][3] = {{1, 2, 3},
{4, 5},{7, 8, 10},{11}};
ספטמבר 04 Copyright Meir Kalech 24
String String is an array of characters. It is treated separately because it is very
common to define characters sequentially. When we store a word in an array (string)
it is uncomfortable to take care of each character separately. For instance, to go over the characters to be inserted or to print a word.
There are library functions which enable simple access to strings.
ספטמבר 04 Copyright Meir Kalech 25
String Definition String definition:
char name[10]; Name consists of 10 chars. But actually we can store
only 9 chars, because one char is saved for the null terminator.
What is a null???
The null value is 0 or ‘\0’ in the ASCII table. It indicates where is the end of a meaningful string.
ספטמבר 04 Copyright Meir Kalech 26
String Initializationchar name[13] = “Im a donkey”;
Imadonkey\0?
char name[] = “Im a donkey”;
char name[] = {‘I’,’m’,’ ‘,’a’,’ ‘,’d’,’o’,’n’,’k’,’e’,’y’,’\0’};
Imadonkey\0
Im\0??????????
Im a donkey\0?
char name[13];scanf(“%s”, name); //Im a donkey
gets(name); //Im a donkey
ספטמבר 04 Copyright Meir Kalech 27
String Initializationchar name[13] = “Im a donkey”;
Comment:The assignment is permitted only
during declaration. There is no assignment operator between strings:char name1[10], name2[10];name1 = name2;
CompilationError!!!
ספטמבר 04 Copyright Meir Kalech 28
String Library String manipulations can be done using the <string.h> library
(#include <string.h>). This library contains several functions that enable copy,
comparison, search, etc… on strings. Comment: strings that are sent to functions as arguments,
must be initialized (at least) with null. The following functions are defined for strings: int strlen(char str[])
Returns the length of string str (not including the null terminator).
int length;char str1[10] = “Arie”;length = strlen(str1); // length = 4
ספטמבר 04 Copyright Meir Kalech 29
String Library int strcmp(char str1[], char str2[])
Compares two strings (lexicographically); Returns:• 0 - the strings are equal.• >0 - the first string is greater.• <0 - the second string is greater.int compare;char str1[10] = “Arie”, str2[] = “arie”;compare = strcmp(str1, str2); // compare<0
char *strcpy(char str1[], char str2[])Copies str2 to str1 (overwriting). (Used instead of: str1=str2;).Comment: str1 does not have to be necessarily initialized.
char str1[10] = “Ariela”, str2[] = “dana”;strcpy(str1, str2);// str1 must be longer than str2
Ariela\0???str1
ספטמבר 04 Copyright Meir Kalech 30
String Library int strcmp(char str1[], char str2[])
Compares two strings (lexicographically); Returns:• 0 - the strings are equal.• >0 - the first string is greater.• <0 - the second string is greater.int compare;char str1[10] = “Arie”, str2[] = “arie”;compare = strcmp(str1, str2); // compare<0
char *strcpy(char str1[], char str2[])Copies str2 to str1 (overwriting). (Used instead of: str1=str2;).Comment: str1 does not have to be necessarily initialized.
char str1[10] = “Ariela”, str2[] = “dana”;strcpy(str1, str2);// str1 must be longer than str2
dana\0a\0???str1
ספטמבר 04 Copyright Meir Kalech 31
String Library char *strcat(char str1[], char str2[])
Concatenating str2 to str1.Comment: make sure that str1 is sufficiently long.char str1[10] = “Arie”, str2[] = “dana”;
strcat(str1, str2);
Arie\0????? dana\0
str1 str2
ספטמבר 04 Copyright Meir Kalech 32
String Library char *strcat(char str1[], char str2[])
Concatenating str2 to str1.Comment: make sure that str1 is sufficiently long.char str1[10] = “Arie”, str2[] = “dana”;
strcat(str1, str2);
Ariedana\0? dana\0
str1 str2
char str1[10] = “Arie”, str2[] = “daniela”;
strcat(str1, str2);
?????\0eirA l a \0einad
str1 str2
ספטמבר 04 Copyright Meir Kalech 33
String Library char *strcat(char str1[], char str2[])
Concatenating str2 to str1.Comment: make sure that str1 is sufficiently long.char str1[10] = “Arie”, str2[] = “dana”;
strcat(str1, str2);
Ariedana\0? dana\0
str1 str2
char str1[10] = “Arie”, str2[] = “daniela”;
strcat(str1, str2);
leinadeirA l a \0einad
str1 str2
DANGEROUS!!!
ספטמבר 04 Copyright Meir Kalech 34
Array as Parameter to Function
When an array is passed as an argument to a function, only its address is sent.
There are 2 ways to indicate types of (array) addresses: type[] (examples: char[], int[], etc…) type * (examples: char *, int *, etc…)
What does an array name indicate ???An ADDRESS!!!
ספטמבר 04 Copyright Meir Kalech 35
Array as Parameter to Function - Definition
void print_reverse(char *string);int sum_array(int vector[], int size);
void main(){ int sum, size, arr[]={1,2,3}; char str[]=“sharon”; size = sizeof(arr)/sizeof(int); sum = sum_array(arr, size); print_reverse(str);}
void print_reverse(char *string){ int i, size = strlen(string); for(i=size-1; i>=0; i--)
printf(“%c”, string[i]);}int sum_array(int vector[], int size){ int sum = 0, i; for(i=0; i<size; i++)
sum += vector[i]; return sum;}
sizeof(arr) is the number of
bytes in arr (12)
sizeof(vector) is only 4 since
only the address of arr is
sent, and address is 4
bytes
BUT…
ספטמבר 04 Copyright Meir Kalech 36
Array as Parameter - Stack An array address enables access to its
elements using the operator []. With operator [] we can even change the
values of the array, although the array is defined in main.
Comment: It’s not possible to change primitive types (char, int…) variables that are passed as arguments to a function.
ספטמבר 04 Copyright Meir Kalech 37
Array as Parameter – Stack: Example
i
first
len
vector
Return address
Returned value
size=3
void main(){ int arr[4]={1,2,3,4}, size=3; initialize(arr, size, arr[0]);}
int initialize(int vector[], int len, int first){ int i; for(i=1; i<len; i++)
vector[i] = first; len = first = 8; return len;}
initialize
main 1234arr 100
initialize gets arr, size and arr[0]. It assigns arr[0] to the first size
elements of arr
ספטמבר 04 Copyright Meir Kalech 38
Array as Parameter – Stack: Example
i
first=1
len=3
vector=100
1024
Returned value
size=3
void main(){ int arr[4]={1,2,3,4}, size=3; initialize(arr, size, arr[0]);}
int initialize(int vector[], int len, int first){ int i; for(i=1; i<len; i++)
vector[i] = first; len = first = 8; return len;}
initialize
main 1234arr 100
After passing of arguments
ספטמבר 04 Copyright Meir Kalech 39
Array as Parameter – Stack: Example
i=3
first=8
len=8
vector=100
1024
Returned value
size=3
void main(){ int arr[4]={1,2,3,4}, size=3; initialize(arr, size, arr[0]);}
int initialize(int vector[], int len, int first){ int i; for(i=1; i<len; i++)
vector[i] = first; len = first = 8; return len;}
initialize
main 1114arr 100
After initial execution
vector[i]:100+i*sizeof(int) []
ספטמבר 04 Copyright Meir Kalech 40
Array as Parameter – Stack: Example
i=3
first=8
len=8
vector=100
1024
8
size=3
void main(){ int arr[4]={1,2,3,4}, size=3; initialize(arr, size, arr[0]);}
int initialize(int vector[], int len, int first){ int i; for(i=1; i<len; i++)
vector[i] = first; len = first = 8; return len;}
initialize
main 1114arr 100
After returned value updating
ספטמבר 04 Copyright Meir Kalech 41
Array as Parameter – Stack: Example
8
size=3
void main(){ int arr[4]={1,2,3,4}, size=3; initialize(arr, size, arr[0]);}
int initialize(int vector[], int len, int first){ int i; for(i=1; i<len; i++)
vector[i] = first; len = first = 8; return len;}
main 1114arr 100
After return of value
8
Conclusion:
size wasn’t changedarr was changed
ספטמבר 04 Copyright Meir Kalech 42
Call by Value Passing arguments by value:
the arguments are copied to the local parameters of the function.
Conclusion: if we want to pass an argument so as to change its value in the function, we can not pass it by value.
ספטמבר 04 Copyright Meir Kalech 43
Call by Address Passing an array as argument: its
address is passed by value (a local parameter stores the address). But, the array’s elements are accessible by using the operator [].
Conclusion: if we want to pass an argument in order to change it in the function, we should pass it by address.
ספטמבר 04 Copyright Meir Kalech 44
2D-array as Parameter 2D array name is also an address. Its type is: type[][]. When defining a function that gets a 2D array, it’s
necessary to add the size of the second [] (columns). Explanation: let’s describe what happens with access to
an element by [][]:int matrix[2][4];matrix[1][2] = 4;
matrix is a vector of two 1D vectors. matrix[1]: matrix+1*sizeof(matrix[0]) – assume matrix is
at address 100; then matrix[1] is at address 100+16. (matrix[1])[2]: 116+2*sizeof(int). The operator []
accesses the value of the address 124 (4 is assigned to this value).
ספטמבר 04 Copyright Meir Kalech 45
2D-array as Parameter When passing an array to a function, only its address is passed. When accessing an array in the function with the following command:
matrix]1[]2[ = 4;
The compiler doesn’t know to decode the term matrix[1], because itsaddress is known but sizeof(matrix[0]) depends on 1D vector length.
void func(int mat[][]);void main(){ int matrix[2][4]; func(matrix);}void func(int mat[][]){ mat[1][2] = 4;}
????
????
matrix address
100
100mat
The compiler shouts thatit doesn’t know the size of each vector in mat!!!
ספטמבר 04 Copyright Meir Kalech 46
2D-array as Parameter So note the correct declaration now.
void func(int mat[][4]);void main(){ int matrix[2][4]; func(matrix);}void func(int mat[][4]){ mat[1][2]=4;}
????
????
matrix address
100
100matNow the compiler
knows that sizeof(mat]0[)is 4*4=16
Recommended