Lab 2: More Advanced C CIS*2520 Data Structures (S08) TA: El Sayed Mahmoud This presentation is created by many TAs of previous years and updated to satisfy the requirements of the course in this semester.
Outline Part 1 The exercise "squish" Part 2 Pointers Typedef Advanced Aggregate Data Types Unions More structs Makefiles
The exercise : "squish" Write a program called "squish" that replaces sequences of one or more blanks with a single blank. This program reads its input from standard input, and writes its output to standard output (in the process of copying its input to its output it replaces the sequences of multiple blanks by a single blank.
Hints for The exercise : "squish" Use Character by character processing. Read from stdin like any other stream Redirect a file on the command-line if desired; i.e. squish < somefile.txt Use gets to read string from user input or getchar to read a character by character. Process the entire input not just a single string. Print the result back using printf or puts.
Part2 : Pointers Essentially an unsigned integer type Stores the address of data in memory The offset from the first byte of memory Consider: int x = 42; int *p = &x; Pointer p stores the address of variable x
What about different variable sizes? But variables are different sizes Integers are 4 bytes Strings (character arrays) are long In the previous example, p stores the address of the first byte of x
Using Pointers Consider: int y = *p; Take the 4 bytes pointed to by p and store them in variable y Consider: *p = 24; Store the value 24 in the 4 bytes pointed to by p The old variable x is now 24
Pointer Manipulation Let p be a pointer. Consider: p = 1000; p++; What value does p have? It depends on the type of pointer! (int *) then 1004 (char *) then 1001 (void *) then a runtime error
Void pointers? Just a generic address No size information Cannot be used without casting Sidebar: The value NULL is #define NULL ((void*)0) Located in stddef.h
Arrays of Pointers Can be declared dynamically or statically Static: int * arr[2]; arr[0] = &x; Dynamic: int ** arr = (int**)malloc(sizeof(int*)*2); arr[0] = &x; free(arr);
Pointers and Parameters By default, C uses pass-by-value Function creates a copy of the value you pass in Changes to the value within the function don t change the original Can use pointers to pass-by-reference Function receives pointer to original value Changes made within the function are retained after Not truly pass-by-reference because a copy is made of the pointer, but it the result is the same
Pointers and Parameters (cont) Example: void foo (int x, int * y) { x = 3; (*y) = 4; } void main () { int a = 1; int b = 2; foo (a, &b); /* a == 1 */ /* b == 4 */ }
Typedef Allows you to create your own custom types typedef <custom type> <new identifier> Not-useful example: typedef int CustomInt; Somewhat-useful example: typedef int* IntPtr; Most useful example: typedef struct rec record;
Combining Typedef with Struct Why use 2 lines when you could use 1? typedef struct rec { char[10] name; } record;
Unions Similar to struct in form Uses overlapping memory While structure enables us treat a number of different variables stored at different in memory, a union enables us to treat the same space in memory as a number of different variables Example: union PersonalID { char [30] name; long sin; }
Unions (cont.) Continuing example: union PersonalID pid; pid.name = Andrew Baker ; pid.sin = 123456789; At the end of this execution, accessing pid.name will not give you Andrew Baker
Copying Structs Example: struct TA { char * name; int empnum; } struct TA ab, jn; ab.name = (char*)malloc(10); strcpy (ab.name, Andrew ); ab.empnum = 123; jn = ab; strcpy (jn.name, JingBo ); jn.empnum = 234; At the end of this execution? What are the values of the following: ab.name? ab.empnum? jn.name? jn.empnum?
Copying Structs Example: struct TA { char * name; int empnum; } struct TA ab, jn; ab.name = (char*)malloc(10); strcpy (ab.name, Andrew ); ab.empnum = 123; jn = ab; strcpy (jn.name, JingBo ); jn.empnum = 234; At the end of this execution? What are the values of the following: ab.name? JingBo ab.empnum? 123 jn.name? JingBo jn.empnum? 234 Assignment (=) only does a shallow copy Pointers are copied, but end up pointing to the same place
Single Source file Compilation prg.c - Source Code -Variable def. Lib.h - Struct -Constant def. -Function declarations Compile prg.s Assemble Compiling a Source File prg.o Link prg.out
Several Source file Compilation prg.c - Source Code -Variable def. gcc prg.c Lib.h - Struct -Constant def. -Function declarations prg.s prg1.s prg.o prg1. o proj.out prg1.c - Source Code -Variable def. gcc prg1.c gcc prg.o prg1.o
Makefiles A makefile is a file (script) containing : Project structure (files, dependencies) Instructions for files creation Basic structure: Variables <target> : <dependencies> <\tab> <command> Can list numerous variables Can list multiple targets, each with multiple dependencies and commands By default, the first target is run when you type make in the console
Makefile Variables Generally, use all capitals Declared as: CC = gcc (compiler selection) LIBS= -lm (Lib files used) OPTIONS= -g - Wall To use: $(CC)$(LIBS)$(OPTIONS)
Sample Makefile CC = gcc LIBS = -lm FLAGS = -Wall -std=c99 - ansi OBJFILES = main.o util.o PROJFILES = main.h main.c util.h util.c PROGNAME = myprog all: $(PROGNAME) $(PROGNAME): $(OBJFILES) $(CC) $(OBJFILES) -o $(PROGNAME) $(LIBS) #build the main object main.o: main.c pgm.h util.h $(CC) $(FLAGS) -c main.c #build the utility object util.o: util.c util.h $(CC) $(FLAGS) -c util.c #remove files of compilation clean: rm $(OBJFILES) $(PROGNAME) #creates a date/time-stamped #backup backup: $(PROJFILES) mkdir 00-backup-`date +'%Y- %m-%d-%h%m'` cp $(PROJFILES) 00-backup- `date +'%Y-%m-%d-%H%M'`
Thank you Any questions?