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