We began by discussing headers from last class.
When we make a change to a function, we need to recompile, change the header file, and recompile the program that uses the library again.
When compiling, g++ will generally clean up the object file. To avoid this, we use the -c argument (c stands for compile only). For example:
vc13:berman_moshe> g++ mySourceFile.cpp -o
This will produce mySourceFile.o.
You can redirect the output of g++ into a text file to see the entire preprocessed source. To do so:
vc13:berman_moshe> g++ -E mySourceFile.cpp > junk
Now, our entire expanded source file, with the include statements replaced, will be inside of a file called junk. By the way, -E tells g++ to preprocess the file, but not compile it. We can use another program, called wc to count the number of lines.
Another thing we can do is use the vertical bar, the pipe symbol [|], to send the output of one program, to the input of another program. We could pipe the output of g++ to wc like so:
vc13:berman_moshe> g++ -E mySource.cpp | wc
This will count the number of words in the file.
We can use a Unix program called sort in a similar fashion:
vc13:berman_moshe> ls -l | sort
You can do the same with cat.
vc13:berman_moshe> cat mySource.cpp | sort
This outputs the source file, with the lines sorted in order.
There’s also grep, which allows us to search for patterns in a file. Professor Weiss’ example:
vc13:student_weiss> g++ -E test.cpp | grep cout
This will show us all of the occurrences of cout in our file.
There is a unix command to read a file. There’s a unix command to sort a file. We can use another unix command to count duplicates. In about four or five piped commands, you get a sorted, counted, zip code file. Sweet.
A programmer is a McGyver. You want to use the tools at your disposal no matter what.
Professor Weiss is talking about recursive code. He told an amusing a story about the time he tried to make a computer blow up by writing a recursive program. Of course the mainframe was smarter than that and shut down after 30 seconds of CPU time.
Demo…
self_includer.h:1:27: #includes are nested too deeply.
Think about how to have a function call itself without running into infinite loops.
Datatypes are only there for the compiler to know things about your variable, such as size. The notion of a class does not go into a compiled program. It’s only there for the compiler. At runtime, C++ has no data types. You trust the compiler to generate the proper code. Professor Weiss gave a long description of this, but now we’re writing a min function.
We’re using basketball scores, in pairs.
We initially tried to use a ternary operators:
int min(int x, int y){
return x>y ? y : x;
}
This won’t work if the values are equal. So, we modify it like so:
int main(int x, int y){
if(x
We still don't have a way to handle equal values though. The correct way to handle this is with a flag. The next iteration of our function looks like this:
int min(int x, into, bool &isCorrupt){
if(x==y){isCorrupt = isTrue; return;}
return x>y ? y : x;
}
To use this code:
bool isCorrupt;
int result = min(team1,team2,isCorrupt);
if(isCorrupt)
cout << "Corrupt";
else
cout << "Loser: " << result;
There are other was of doing this as well. The function can return a bool and the lowest score will have the reference parameter. The function header looks like this:
bool min(int x, int y, bool &lowest);
This is like eating soup before the main course, or the main before the soup. Yet another way to do this is as follows:
void min(int x, int y, int &lowest, bool &isCorrupt);
There's no penalty for adding parameters, and it's not a good idea to play favorites.
