CS152
Chris Pollett
Feb. 9, 2009
C has a mechanism for collecting together a bunch of existing data types into a new one using struct's. These can be thought of as classes without member functions.
struct Person { char name[12]; int age; }; //notice the ; struct Person p, *ptr; strcpy(p.name, "Bob"); //in string.h. Note p.name[3] = '\0' after // many useful string functions like strlen, strcmp, etc are in string.h p.age = 5; ptr = &p; printf("%d %s %s", p.age, (*ptr).name, ptr->name);
You can also declare:
struct { int a,b; } test; test.a = 5; /* so have declared a variable test but have not given the kind of struct it is a name */
The syntax struct Person p; of the last slide is sometimes awkward. To simplify it you can write:
typedef struct Person person_type; person_type a,b,c;
Using structs and pointers you can create recursive data structures:
struct mylist { int a; struct mylist *next, *prev; } test;
Remark: You can fake classes by using struct's which have function pointers as members.
union int_or_char { int my_int; //can hold either an int or a char but not both at the same time char my_char; // union allocates enough memory for the larger of the two possibilities } test; test.my_int = 8; typedef union int_or_char IntOrChar; IntOrChar test2;
enum suit {CLUBS, DIAMONDS, HEARTS, SPADES} suit_test; suit_test = DIAMONDS; typedef enum suit CardSuit; CardSuit suit_test2 = SPADES;
Consider the following C snippet:
int i = 5, *p; i--; p = &i; *p = 10;
What is the value of i after the last line?
#include <stdio.h> #include <stdlib.h> //for malloc and free int main() { int *p; p = (int *)malloc(10*sizeof(int)); /*sizeof returns number of bytes an int takes (could do sizeof(person_type) for person_type of a couple slides back) */ if( p == NULL) { return 1; //bail out } /* do stuff. To refer to the location of ith int can do (p + i), its value is *(p + i) or p[i] */ free(p); // got to free or create a memory leak -- unlike Java no garbage collection return 0; }Notice we cast the result of malloc to be of type int rather than void*.
int a; scanf("%d", &a); //reads from stdin one int into a.
#include <stdio.h> int main(int argc, char * argv[]) //notice getting command-line args { int c; FILE *fp; if(argc < 2) { return 1; //bail if no file specified } fp = fopen(argv[1], "r"); // r is for reading, w for write, rb for binary, etc while ((c = fgetc(fp)) != EOF) { printf("%c", (char)c ); } fclose(fp); return 0; }
printf("Hit a key to continue"); c= getchar();
#include <termios.h> //... struct termios tio; tcgetattr( 0, &tio ); tio.c_lflag &= ~ICANON; tcsetattr( 0, TCSANOW, &tio ); printf("Hit a key to continue"); c= getchar();
make targetThe make utility would then search the current directory for a file called Makefile and then tries to satisfy the target goal.
A Makefile consists of rules of the form:
target1: depends_on1 depends_on2 ... <tab>command1 <tab>command2 ... <blankline> target2: depends_on1 depends_on2 ... #etc # is used for a single-line comment
Notice the use of tabs is important!
myprog: myprog.o cc -o $@ $< myprog.o: myprog.c cc -c -o $@ $< # $@ refers to the target $< refers to the first dependency clean: rm -f myprog myprog.o
You can declare variables in a Makefile using the format varname = value like:
CC = gcc SUBDIRS = io linkedlist
These variables could then be used:
all : $(SUBDIRS) $(CC) historylesson.c -o historylesson
An example of a multi-line make rule might be something like:
io : @echo "Making io..." cd io make all
%.o : %.c