COP 3223H meeting -*- Outline -*- * Constructing loops ** Background: Arrays in C ------------------------------------------ ARRAYS IN C - declaration (creation): - constant time element access: trajectory[0], ..., trajectory[19] trajectory[0] = 7; - minimal space overhead: arrays do not store ------------------------------------------ ... double measures[100]; int trajectory[20]; ... no bounds checking, so the access to elements is very fast, just indirect access through the array base + offset ... their length (the programmer must track that separately) (this can cause security problems) ------------------------------------------ STRINGS ARE CHAR ARRAYS IN C In C a string is an array of chars that char greeting[] = "hello!"; greeting[0] == 'h' greeting[1] == 'e' greeting[2] == 'l' greeting[3] == 'l' greeting[4] == 'o' greeting[5] == '!' greeting[6] == ------------------------------------------ ... ends with a null char ('\0') thus an empty string is represented by an array with 1 char ... '\0' ** tabular method for constructing loops *** accumulators often need to be introduced into a program with loops ------------------------------------------ ACCUMULATORS What is an accumulator? Uses: ------------------------------------------ ... A variable used to track state in a loop (or recursion) ... build up state towards a final answer (as in a calculator) ... track a position in a data structure (like an index into an array) if the data structure doesn't track where position itself ... save informtion for later use *** questions to ask this also works for tail recursions, which are strongly related ------------------------------------------ TABULAR METHOD FOR CONSTRUCTION OF LOOPS 0. Should we use a loop? 1. What kind of loop? (while or for?) 2. What information is needed for the steps? 3. Up or down? 4. When should the loop stop? 5. What would be the steps for an example? 6. Generalize from those steps ------------------------------------------ ... yes, if there is no clear way to get to the desired next state in 1 or 2 steps, or if the number of steps is unknown ... use a while loop if the number of steps is unclear or if the steps are irregular, use a for loop if the number of steps is clear and regular (e.g., with an array) ... what types of accumulators are needed? ... direction may depend on what is easiest to initalize, it may not matter much, but you need to decide ... need this for while loops especially, and for loops in C ... make a table showing the accumulators over time how do we compute the next step from the available information? ... the code can't be for a specific example, has to work in general *** examples **** sum elements of an array ------------------------------------------ EXAMPLE: SUMMING AN ARRAY Write a function int sum(int a[], int sz); that returns the sum of the elements in a at indexes a[0], ..., a[sz-1]. 0. Should we use a loop? 1. What kind of loop? (while or for?) 2. What information is needed for the steps? 3. Up or down? 4. When should the loop stop? 5. What would be the steps for an example? 6. Generalize from those steps ------------------------------------------ ... yes ... for, we know how many elements there are ... an index (i), the total of all elements seen so far (acc) ... up (but down also works) ... when we have processed all elements (i >= sz) i.e., when i is not a legal index ... make progress to ending (i++) and add a[i] into the acc ... a | i | acc ================= [3,2] | 0 | 0 [3,2] | 1 | 3 [3,2] | 2 | 5 ... // $Id$ int sum(int a[], int sz) { int acc = 0; for (int i = 0; i < sz; i++) { acc = acc + a[i]; } return acc; } ------------------------------------------ EXAMPLE: ADDING TO EACH ARRAY ELEMENT Write a function void addToEach(int a[], int sz, int v); that modifies each element a[i] of to be a[i] + v. 0. Should we use a loop? 1. What kind of loop? (while or for?) 2. What information is needed for the steps? 3. Up or down? 4. When should the loop stop? 5. What would be the steps for an example? 6. Generalize from those steps ------------------------------------------ ... yes ... for, we know how many elements there are ... an index (i), to keep position ... up (but down also works) ... when we have processed all elements (i >= sz) i.e., when i is not a legal index ... make progress to ending (i++) and add v into each a[i] ... a | i | v ==================== [3,2] | 0 | 5 [8,2] | 1 | 5 [8,7] | 2 | 5 // $Id$ void addToEach(int a[], int sz, int v) { for (int i = 0; i < sz; i++) { a[i] = a[i] + v; } } ------------------------------------------ LENGTH OF A STRING Write a function int mystrlen(char s[]); that return the number of chars in s up to the first null char ('\0'). 0. Should we use a loop? 1. What kind of loop? (while or for?) 2. What information is needed for the steps? 3. Up or down? 4. When should the loop stop? 5. What would be the steps for an example? 6. Generalize from those steps ------------------------------------------ Note, strlen in is like this, but returns a size_t instead of an int. ... yes ... while, since we don't know the number ... a count of chars seen, which is a position (i) ... up (since that is part of the problem) ... when s[i] == '\0' ... s | i ================ "hi" | 0 "hi" | 1 "hi" | 2 // $Id$ int mystrlen(char s[]) { int i = 0; while (s[i] != '\0') { i++; } return i; }