C Programming lecture 2 Beautiful programs Greek algorithms
C Programming lecture 2 • • • Beautiful programs Greek algorithms Arrays of numbers Strings of characters Pointers (the really difficult bit of C)
Beauty is truth and truth beauty • A program which is neatly formatted is easier to understand • If you're staring in confusion at a load of {s and }s and don't know whether you need another } your program is probably UGLY • Indenting consistently is especially important. (in functions, for, while if and else). • One of our most important goals as a programmer is to write something that other people can read.
Layout of a program (brace style) int main() { Always indent after int i, x, y; float z; a left bracket. . if (x < 7) { Right bracket Start a y= 3; level with z= 4. 2; left bracket after } else if (x > 23) { statement which a statement y= 5; started it z= 7. 2 } for (i= 1; i < 200; i++) { for (j= 1; j < 200; j++ { NOTE: Not all /* Inside both loops */ code on these } /* Inside only the first loop */ overheads follows } this style for space return 0; reasons }
MAGIC numbers in programs • A lot of programs contain what programmers sometimes call MAGIC nos g= 43. 2 * a + 7. 1; for (i= 7; i < 103; i+=2) { printf ("%dn", i*7); } This makes code look UGLY and it is confusing to the reader. It is better to give some idea of what these numbers mean in the program.
enum • We can use the enum command to define int s and chars. It looks like this: enum { MAX_LEN= 100, LETTERX= 'x', NEWLINE= 'n' }; By convention we use all capitals for enum constants. That way we can tell them from variables. We can now use the enum constant wherever we could use an int or char a[MAX_LEN]; for (i= 0; i < MAX_LEN; i++) a[i]= LETTERX;
#define • This preprocessor command replaces one thing with another before compilation NOTE – NO semi colon here! #define PI 3. 14 #define GRAV_CONST 9. 807 #define HELLO_WORLD "Hello World!n" Now, anywhere in the program we use PI or GRAV_CONST it will be replaced with the replacement string BEFORE the real compiler starts (that's why we call it pre-processing) c= 2. 0 * PI * r; a= GRAV_CONST * (m 1*m 2)/ (r * r); printf (HELLO_WORLD);
This lecture's program • The sieve of Eratosthenes is an algorithm of greek origin. • It is a relatively efficient way of constructing a list of small prime numbers • It is defined in your notes in the section "going from algorithm to program". • It is also going to be used in the next worksheet.
The sieve 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 After appropriate crossing out we have prime numbers But how can we represent the sieve in C? The goal of this is to find another way to write our is_prime function.
Choosing a data representation • When going from an algorithm to a program, one of the first questions is "How can I represent my data? ". • If the program has to store anything then what is the best way to store it? • In the case of the sieve of Eratosthenes, we need to store a table of numbers. • In this case, a good storage mechanism is an array – a list of numbers.
The ARRAY • An array in C is a group of similar variables. For example 200 ints or 45 chars • Arrays use square brackets like so: int some_nums[200]; char bunch_o_chars[45]; some_numbers[3]= 5; printf ("Element 3 is %dn", some_nums[3]); bunch_o_chars[0]= 'a'; Unfortunately, in C, we must give the length when we declare the array (see lecture notes). ARRAYS CAN BE MODIFIED BY FUNCTIONS! For the reason see later in the lecture
Great C muck-ups: #5 in a series of 100 • If we declare an array in C to be 100 elements the array is numbered from 0 to 99. EVERYBODY at some point makes this mistake: int a[100]; /*Declare 100 ints */ a[0]= 52; a[1]= 3; a[100]= 5; /* This is a common error There is NO element 100 but your program will compile and run*/
Passing arrays to functions • We prototype a function which accepts an array like this: void process_array (int []); int calc_array (char[]); • And write the function like this: void process_array (int all_nums[]) { all_nums[1]= 3; . . } • And call the function like this: int some_numbers [100]; process_array(some_numbers); • Note that we CAN’T return an array from a function (but see later).
So what does this mean for our sieve? • We could use an enum to define how many primes we want our array to be. • We can use an array to store whether or not it has been crossed (it only needs to be a 1 D array - think about this) • We can have an enum to say whether it is crossed or not crossed (instead of storing the number) • Write something to uncross all the array
Look for some obvious sub-tasks which might be functions • What bits of our algorithm are obvious candidates for becoming functions? • What data do we need to pass to and from each function? • Write the bits that call the function and the prototype • Then write the function
Look for some obvious LOOPS • Two of the most used workhorses in C are the for and while loops. • Which is clearer in this case? A for or while loop? • What indeed is the difference? for (initialiser ; condition ; increment) { code; Generally we use for when } the initialiser, condition and initialiser; increment are all on the same while (condition) { variable. code; There is ONE difference – can you increment; work out what? }
Great C muck-ups: #51 in a series of 100 • We must get the order right in a for statement. Oops - wrong order for (i < 7; i++; i= 0) { printf ("i is %dn", i); } And don't use commas instead of ; for (i= 0, i < 7, i++) wrong And remember, if you miss out the { } s then only the one next statement will be executed. Oops - only for (i= 0; i < 7; i++) see this once printf ("i is %dn", i); printf ("i squared %dn", i*i);
Checking the sieve works • Don't just TRUST your program - check it. • In a big program it is good to check functions as they are written - not the whole program. Check as you write. • The best way to check something is working is to get some print out from it. • So add something to the sieve to print all the primes which have been found so far.
Strings in C • When we want to store and print text in C we use a string • A string is an array of type char which has '