I. Function Prototypes - lists function name, return type and parameters - so compiler can do type checking - it is just the declaration of a procedure w/ a semicolon. - important for large programs w/ multiple files - C without prototypes - can use different number of arguments vs. parameters - can omit return value - C uses arbitrary values if not defined II. Variable initialization - local variables/arrays initially have an arbitrary value - must initialize all local variables! III. Basic memory and pointers - computers work in binary (base 2) ex: 101 base 2 = 5 base 10 - bits - the smallest unit of memory, can be either "0" or "1" - bytes - group bits together into a "word" - 8 bits forms 1 byte - size of bits indicates the number of "digits" available for the number your wish to store - the more bits/bytes, the larger the number that can be stored - char = 1 byte, short = 2 bytes, int = 4 bytes - number of values that can be stored is 2^(number-bits) - signed vs. unsigned (do we use one bit as a sign bit?) - char can store -128 to 127 - unsigned char can store 0 to 255 - sizeof() - returns bytesize of a data structure - may be padded for alignment - addresses of memory - each memory location has an "address" associated with it - currently a 4-byte number - &x returns the address of variable x - can store the address as an int - the pointer - like a Java reference, but pointer can point to anything (simply an address to a memory location) - type of pointer lets C compiler know how to deference - declarations (int *p) ex: int *p = &x; - accessing the contents of the pointer: p - accessing the contents of the memory location pointed to by the pointer: *p - pointers and arrays - the array name is really a pointer to the first element of the array int a[10]; int p*; p = a; or p = &(a[10]); - when passing an array as a parameter - are only passing a pointer to the array - pointer arithmetic (p++) - increments p by the size of the data type p references ex: char string[6] = "hello"; char *ptr = string; *ptr == 'h' *(ptr + 1) = 'e'; *(ptr + 2) = 'l'; what about *ptr + 3? - Example: write strcpy: char string1[80], string2[80]; strcpy(string1, string2); void strcpy(char *to, char *from) { int i; while (from[i] != '\0') { to[i] = from[i]; i++; } to[i] = '\0'; } - in C, every expression returns a value. - for "=", value returned is value set void strcpy(char *to, char *from) { int i; while ((to[i] = from[i]) != '\0') i++; } - if we use pointers, we can remove i void strcpy(char *to, char *from) { while ((*to = *from) != '\0') to++; from++; } - i++ increments i after using value in command ++i increments i before using value in command (value of i++ is value of i before it is incremented) - ++ and * are evaluated right to left, so *i++ equiv to *(i++) void strcpy(char *to, char *from) { while ((*to++ = *from++) != '\0') ; } - a last version: void strcpy(char *to, char *from) { while (*to++ = *from++) ; } IV. Structures - for creating larger, more complicated data types - the closest thing C has to Java classes and objects - structure definitions Example: struct point { int x; int y; }; - structure variable declarations and usage Example: struct point p; p.x = 10; p.y = 5; - we can nest different structures Example: struct line { struct point p1; struct point p2; }; - using structures Example: get the slope of a line slope = (p1.y - p2.y) / (p1.x - p2.x) - self-referential structures: - can not next a structure within itself - no recursive data types! - must use pointers Example: struct linked_list { int value; struct linked_list *next; } V. Defining types - the typedef command can be used to simplify declarations Example: typedef struct linked_list LINKED_LIST; typedef struct line LINE; - usage: LINKED_LIST llint; LINE line1; LINE line2; VI. Input/Output - single character input/output: getchar/putchar - int getchar(); - gets next character from stdin - takes int because EOF == -1 - int putchar(int c); - writes character to stdout - how to read in a line of input: getline int getline(char *line, int maxlen) { int c, i; for (i = 0; i < maxlen-1 && (c=getchar() != EOF) && c != '\n'; i++) line[i] = c; line[i] = '\0'; return i; } - C has built in functions to input/output a line - char *gets(char *s); - int puts(const char *s); - but gets is unsafe and should not be used - formatted input/output: scanf/printf - formatted output: printf Example: int lineno, linelength; double wordsize; printf("Line %d has %d words with avg length %.2f\n", lineno, linelength, wordsize); - the % is a place holder indicating that the spot in the string is to be filled by the next parameter - % conversions %d = int as decimal %x = int as hexadecimal %c = int as character %s = char * - prints as string until '\0' encountered %f = double in decimal notation m.ddddd %e,E = double in scientific notation m.ddde+xx %g,G = double using either f or e %% = % %.10 -> trucate output after 10 characters %10 -> use at least 10 characters in output %-10 -> use at least 10 characters, flush left - formatted input: scanf Example: int day, year; char month[20]; scanf("%d of %s in %d", &day, month, &year); - scanf will skip over white space to match the format string - scanf returns number of items matched - % conversions for scanf are same as for printf EXCEPT: %e,%f,%g read in a float in any format the numbers have no meaning for scanf - can input/output to strings sscanf(char *string, "%d %d", &x, &y); sprintf(char *string, "hello there\n"); - can input/output to files FILE *fp - a file pointer fprintf(fp, "Dear %s\n", name); fscanf(fp, "Rating %c", &c); - SEE EXAMPLE filecopy.c - there are 3 standard C files - stdin, stdout, stderr - printf(...) == fprintf(stdout, ...); - scanf(...) == fscanf(stdin, ...); - Example: fprintf(stderr, "Error in data\n"); - fgets(), fputs() are safe versions of gets() and puts()