Assignment 1 Debrief Andy Wang Data Structures Algorithms
Assignment 1 Debrief Andy Wang Data Structures, Algorithms, and Generic Programming
makefile w Reasons for using a makefile: n n Standard practice in the UNIX world Describe dependencies among files Easy to rename files, change include paths, and so on… Automatically generate header file dependencies
A Simple makefile all: libbit. a sieve. x libbit. a: bitvector. o ar cr libbit. a bitvector. o ranlib libbit. o sieve. x: main. o sieve. o libbit. a g++ -g –ansi –Wall main. o sieve. o –I/usr/include –L. –lbit –o sieve. x bitvector. o: bitvector. cpp bitvector. h g++ -g –ansi –Wall –I/usr/include –c –o bitvector. cpp sieve. o: sieve. cpp bitvector. h sieve. h g++ -g –ansi –Wall –I/usr/include –c –o sieve. cpp main. o: main. cpp sieve. h g++ -g –ansi –Wall –I/usr/include –c –o main. cpp clean: rm –f *. o libbit. a sieve. x core *~ *. bak
To ease changing flags FLAGS = -g –ansi –Wall -O all: libbit. a sieve. x libbit. a: bitvector. o ar cr libbit. a bitvector. o ranlib libbit. o sieve. x: main. o sieve. o libbit. a g++ $(FLAGS) main. o sieve. o –I/usr/include –L. –lbit –o sieve. x bitvector. o: bitvector. cpp bitvector. h g++ $(FLAGS) –I/usr/include –c –o bitvector. cpp sieve. o: sieve. cpp bitvector. h sieve. h g++ $(FLAGS) –I/usr/include –c –o sieve. cpp main. o: main. cpp sieve. h g++ $(FLAGS) –I/usr/include –c –o main. cpp clean: rm –f *. o libbit. a sieve. x core *~ *. bak
make depend FLAGS = -g –ansi –Wall -O all: libbit. a sieve. x libbit. a: bitvector. o ar cr libbit. a bitvector. o ranlib libbit. o sieve. x: main. o sieve. o libbit. a g++ $(FLAGS) main. o sieve. o –I/usr/include –L. –lbit –o sieve. x bitvector. o: bitvector. cpp bitvector. h g++ $(FLAGS) –I/usr/include –c –o bitvector. cpp sieve. o: sieve. cpp bitvector. h sieve. h g++ $(FLAGS) –I/usr/include –c –o sieve. cpp main. o: main. cpp sieve. h g++ $(FLAGS) –I/usr/include –c –o main. cpp clean: rm –f *. o libbit. a sieve. x core *~ *. bak depend: makedepend -- $(FLAGS) –I/usr/include bitvector. cpp sieve. cpp main. cpp bitvector. h sieve. h # DO NOT DELETE THIS LINE – makedepends on it.
Systematic Conversion FLAGS = -g –ansi –Wall -O all: libbit. a sieve. x libbit. a: bitvector. o ar cr libbit. a bitvector. o ranlib libbit. o sieve. x: main. o sieve. o libbit. a g++ $(FLAGS) main. o sieve. o –I/usr/include –L. –lbit –o sieve. x. cpp. o: g++ $(FLAGS) –I/usr/include –c –o $*. cpp clean: rm –f *. o libbit. a sieve. x core *~ *. bak depend: makedepend -- $(FLAGS) –I/usr/include bitvector. cpp sieve. cpp main. cpp bitvector. h sieve. h # DO NOT DELETE THIS LINE – makedepends on it.
To ease changing include paths INC = -I/usr/include FLAGS = -g –ansi –Wall -O all: libbit. a sieve. x libbit. a: bitvector. o ar cr libbit. a bitvector. o ranlib libbit. o sieve. x: main. o sieve. o libbit. a g++ $(FLAGS) main. o sieve. o $(INC) –L. –lbit –o sieve. x. cpp. o: g++ $(FLAGS) $(INC) –c –o $*. cpp clean: rm –f *. o libbit. a sieve. x core *~ *. bak depend: makedepend -- $(FLAGS) $(INC) bitvector. cpp sieve. cpp main. cpp bitvector. h sieve. h # DO NOT DELETE THIS LINE – makedepends on it.
Bit. Vector 23……. 16 15……… 8 7……… 0 10010101 001010010010 array[2] array[1] array[0] Byte. Number(17) = 2 Mask(17) = 00000010(2) unsigned char array
Byte. Number(bit_index) w Bad name w Should be Basictype. Array. Index. Number() w Goal: n Return the index of the Basictype array that holds the bit
Set() w Goal: n w w 10100… 010010 1111…. . 11111 Array[j] = 0 x 01; // use only 1 out of n bits |= 0 x. FF; // OK only for unsigned char |= 0 x. FFFF; |= ~0 x 0;
Set(bit_index) w Goal: n 10100… 010010 10110… 010010 w To set a bit to 1 n n 0 | 1 1 1 | 1 1 w To preserve remaining bits: n n 0 | 0 0 1 | 0 1
Set(bit_index) | 10100… 010010 00010… 000000 10110… 010010 Array[Byte. Number(bit_index)] |= Mask(bit_index);
Unset() w Goal: n w w w 10100… 010010 00000…. 000000 0 & 0 = 0 1 & 0 = 0 Array[j] &= 0 x 0; 0 ^ 0 = 0 1 ^ 1 = 0 Array[j] = Array[j] ^ Array[j];
A Neat Trick w A = 11001010 w B = 00100101 w. A=A^B w. B=A^B w. A=A^B
Unset(bit_index) w Goal: n 10100… 010010 10000… 010010 w To set a bit to 0: n n 0 & 0 0 1 & 0 0 w To preserve remaining bits: n n 0 & 1 0 1 & 1 1
Unset(bit_index) & 10100… 010010 11011… 111111 10000… 010010 Array[Byte. Number(bit_index)] &= ~Mask(bit_index);
Flip() w Goal: n w w w 10100… 010010 01011…. 101101 ~1 = 0 ~0 = 1 Array[j] = ~Array[j]; 1 ^ 1 = 0 0 ^ 1 = 1 Array[j] = Array[j] ^ ~0 x 0;
Flip(bit_index) w Goal: n 10100… 010010 10101… 010010 if (Test(bit_number)) { Unset(bit_number); } else { Set(bit_number); }
Common Errors w Basictype vector vs. bit vector w != vs. |= w == vs. = w Mask() vs. Bit. Vector: : Mask() w #include <bitvector. h> vs. #include “bitvector. h”
Common Errors Foo(); { } vs. Foo() { } Personally, I prefer… Foo() { }
- Slides: 20