200 likes | 290 Views
Assignment 1 Debrief. Andy Wang Data Structures, Algorithms, and Generic Programming. makefile. Reasons for using a makefile: Standard practice in the UNIX world Describe dependencies among files Easy to rename files, change include paths, and so on…
E N D
Assignment 1 Debrief Andy Wang Data Structures, Algorithms, and Generic Programming
makefile • Reasons for using a makefile: • 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 Simplemakefile 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.o bitvector.cpp sieve.o: sieve.cpp bitvector.h sieve.h g++ -g –ansi –Wall –I/usr/include –c –o sieve.o sieve.cpp main.o: main.cpp sieve.h g++ -g –ansi –Wall –I/usr/include –c –o main.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.o bitvector.cpp sieve.o: sieve.cpp bitvector.h sieve.h g++ $(FLAGS) –I/usr/include –c –o sieve.o sieve.cpp main.o: main.cpp sieve.h g++ $(FLAGS) –I/usr/include –c –o main.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.o bitvector.cpp sieve.o: sieve.cpp bitvector.h sieve.h g++ $(FLAGS) –I/usr/include –c –o sieve.o sieve.cpp main.o: main.cpp sieve.h g++ $(FLAGS) –I/usr/include –c –o main.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 – makedepend depends 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 $*.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 – makedepend depends 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 $*.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 – makedepend depends on it.
BitVector 23…….16 15………8 7………0 unsigned char array array[2] array[1] array[0] ByteNumber(17) = 2 Mask(17) = 00000010(2)
ByteNumber(bit_index) • Bad name • Should be BasictypeArrayIndexNumber() • Goal: • Return the index of the Basictype array that holds the bit
Set() • Goal: • 10100…010010 1111…..11111 • Array[j] = 0x01; // use only 1 out of n bits • Array[j] |= 0xFF; // OK only for unsigned char • Array[j] |= 0xFFFFFFFF; • Array[j] |= ~0x0;
Set(bit_index) • Goal: • 10100…010010 10110…010010 • To set a bit to 1 • 0 | 1 1 • 1 | 1 1 • To preserve remaining bits: • 0 | 0 0 • 1 | 0 1
Set(bit_index) 10100…010010 | 00010…000000 10110…010010 Array[ByteNumber(bit_index)] |= Mask(bit_index);
Unset() • Goal: • 10100…010010 00000….000000 • 0 & 0 = 0 • 1 & 0 = 0 • Array[j] &= 0x0; • 0 ^ 0 = 0 • 1 ^ 1 = 0 • Array[j] = Array[j] ^ Array[j];
A Neat Trick • A = 11001010 • B = 00100101 • A = A ^ B • B = A ^ B • A = A ^ B
Unset(bit_index) • Goal: • 10100…010010 10000…010010 • To set a bit to 0: • 0 & 0 0 • 1 & 0 0 • To preserve remaining bits: • 0 & 1 0 • 1 & 1 1
Unset(bit_index) 10100…010010 & 11011…111111 10000…010010 Array[ByteNumber(bit_index)] &= ~Mask(bit_index);
Flip() • Goal: • 10100…010010 01011….101101 • ~1 = 0 • ~0 = 1 • Array[j] = ~Array[j]; • 1 ^ 1 = 0 • 0 ^ 1 = 1 • Array[j] = Array[j] ^ ~0x0;
Flip(bit_index) • Goal: • 10100…010010 10101…010010 if (Test(bit_number)) { Unset(bit_number); } else { Set(bit_number); }
Common Errors • Basictype vector vs. bit vector • != vs. |= • == vs. = • Mask() vs. BitVector::Mask() • #include <bitvector.h> vs. #include “bitvector.h”
Common Errors Foo(); { } vs. Foo() { } Personally, I prefer… Foo() { }