MESSAGE
DATE | 2008-06-29 |
FROM | Ruben Safir
|
SUBJECT | Subject: [NYLXS - HANGOUT] C++ Workshop session 1
|
Starting the C++ Workshop withthe Lippman and Lajoie book one of the first things one notices is that C++ is a very involed language, and not the best language to start learning with. I'm sure there are objections to this statement as also many people believe that Java is also a good first language to learn, but I strongly disagree. I think it is counter productive for a new programmer to skip over forgiving procedural languages and just jump into an object orientated language to be innundated with conceptual "objects" of all sorts before understanding basic varriable types, data types flow control operators and operator precedence.
C++ makes it even harder because it learns on C programming for a foundation, C programming itself a difficult language to truly master. One can teach a programming language in one of two ways. First is to break it down, each step, learned logically in sequence, slowly development a complete definition of each step and building on that. The second way is to get the student into the batters box quickly, with little instruction, and based on their general knowledge, let them pick up on things as they can, leaving precise definition for later if at all. You might call this the tap dancing method.
This C++ book uses the second method, probably for a number of reasons. It assumes that you have some basic knowledge of C programming, or programming in the general. The first chapter throws quite a bit at the reader. For one thing it begins by giving an example of a problem that you might want to solve and the logical methodology that would be used to solve the problem theoretically prior to any kind of code. It doesn't define the form of a C++ program, fails to mention that semi-colons are needed after most statments, nor does it really discuss the need for the function main(), or the basic structures of functions or methods which are immediately used in the opening example. It does discuss how the suffix of a source code file affects the compiler.
On the note of the file suffix, in theory the gcc compiler needed to make C++ programs on a GNU/Linux system fails to link correctly. This seems to be not documented in the man page of gcc. There is a shell script wrapper for gcc called g++ which can be used to compile your C++ program. I spend a bit of time on this last night learning this the hard way.
Let's look at the first example program from the text, slightly modified by me for learning purposes.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 #include 2 using namespace std; 3 4 void read(){ cout << "read()\n";} 5 void sort(){ cout << "sort()\n";} 6 void compact(){ cout << "compact()\n";} 7 void write(){ cout << "write()\n";} 8 9 int main(){ 10 read(); 11 sort(); 12 compact(); 13 write(); 14 15 return 0; 16 } 17
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The #include is correctly termed a "preprocessor directive". Preprocessor directives are poorly understood by beginning C and C++ programs, but often vital. One thing not mentioned here is that unlike in C, the Preprocessor directive "include" in C++ does not have a suffix .h unless it is a local header or a C specific header. In C you would have
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #include
int main(){ printf("To C, or not to C: that is the question \n"); return 0; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Notice the 'h' after stdio where as in C++ you have no h in It explains that if you want a regular C library header file you need to either call is with a c in front of it
#include
or include the 'h'
#include
If you call for a local non-system header file, one you might have cooked up, you would use double quotes:
#include "rubens_special_bird_soup.h"
Not that preprocessor command do not use semi-colons on the end of the line.
From the prespective of a C Programmer, the use of the 'cout' object (function, method, class instance, whatever it is) is very different then what your used to looking at, and the operator '<<', which serves almost as a cat operator, is unlike any C function you would expect. In sort, what ever is to the right of the '<<' operator is concatonated to its current value and returned to the left into 'cout' which pumps everything to STDOUT.
iostream makes this all happen.
Namespaces are immediately introduced. Until recently, the namespace functionality in C++ has been hit or miss. I know when I originally learned this language at NYU, it didn't work with gcc. It seems to now, and although it was introduced as a preprocessor directive, which doesn't sound right to me for two reasons, the "using namespace" syntax is called specifically a "using directive". To me it doesn't look like a using directive doesn't look like a prepocessor directive because:
A) it requires a semi-colon on the end B) it would directly affect scope in the code, something that would seem to me to be a function of guinine code.
It's also odd to me that namespace developed as late as it did in C++ because it seems to me to a vital tool to creating efficient classes and objects, not that it can't be done without a specific call for namespace, but the scoping affect of a name space is still required for an object to be built. But all this will be looked at later.
C++ like C is a typed language. Unlike C, C++ allows for the creation of new types. The closest C comes to that is with typedef struct or union. C++ is much more flexible, so in addition to the core types, which will be covered more deeply later, C++ also has new types like "string" and "vector". Handling strings is one of the great difficult feats in C. Having a string data type which can be imported from the library can be very helpful.
For vectors, note the syntax
#include vecortor somegroupofstrings(20);
I wonder if vector needs the string library to be called, or if calling in vector with the preprocessor automatically brings in the string library.
In the discussion of Preprocessors, note the handy command line ability to declare a preprocessor constant
gcc -D
So for example in the second program of this chapter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 #ifndef HEAD 2 #define HEAD 3 #include 4 #include 5 6 #endif 7 8 /********************************************************** 9 * Second example C++ program in Lippman on page 21 of text* 10 * Preprosor commands added for practice * 11 * namespace directive added for completeness * 12 * \n is replaced with the macro endl * 13 * Ruben Saifr June 29th, 2008 * 14 **********************************************************/ 15 16 using namespace std; 17 18 int main(){ 19 string word; 20 while( cin >> word) 21 cout << "word read is: " << word << endl; 22 #ifdef DEBUG 23 cout << "what was that word?\n" << word << '\n'; 24 #endif 25 26 cout << "ok: No more words to read: bye!" << endl; 27 return 0; 28 }
When we compile this program and run it...
ruben-at-www2:~/cplus> g++ -Wall -o file2 file2.C ruben-at-www2:~/cplus> ./file2 hello my friend this is the end word read is: hello word read is: my word read is: friend word read is: this word read is: is word read is: the word read is: end
ok: No more words to read: bye! ruben-at-www2:~/cplus>
Everything seems normal enough. Now compile it with DEBUG, which btw is a random constant that otherwise has no meaning....
ruben-at-www2:~/cplus> g++ -Wall -DDEBUG -o file2 file2.C ruben-at-www2:~/cplus> ./file2 The long and winding road word read is: The word read is: long word read is: and word read is: winding word read is: road
what was that word? road ok: No more words to read: bye!
Note, CTL-D is the Control Char and a d together on the keyboard which is an eof marker for the program. This was a mistake in the text. This program will not end without a CTL-D or a CTL-C. CTL-C will just kill the program. CTL-D send an EOF - close input stream.
Other prepossor names that are listed are
__cpluslpus <==== Defines the program as a C++ program for the compiler __STDC__ <==== Defines the program as a C program for the compiler __LINE__ <==== Defines the line number the the compiler is up to __FILE__ <==== Defines the file name that is being compiled by the compiler __TIME__ <==== Defines the Time of compilation __DATE__ <==== Defines the Date of compilation
I'm not a fan of assertions, but they are explained here. Part of the C library then have to be imported with the include statment of either
#include or #include
This complies with the rules for using C libraries in a C++ program.
An assertion is a condition which, if not met, the program is fundementally broken and should end. I've rarely used these when I lost tract of where all my data was coming from, and before proceeding I needed to know that some data was properly aquired from user interaction, knowing that it logically should have been, but hedging that I might have missed some interactive route by which it could have been called that I didn't anticipate. Of course, this all spells bad news from a security perspective. Security holes happen when programs are used in unexpected ways and produce unexpected results. But asserts aren't generally security tools, but debugging tools.
#ifdef DEBUG assert( x == y ); #endif
The first chapter also discussed STDIN, STDOUT, STDERR and file handles, which is unusual. While STDIN, STDOUT and STDERR need to be discussed from the start discussing file handle access is usually an advanced topic until students are used to the whole concept of STREAMS, let alone, the three standard streams and then streams to other devices, like the file system. However, it is a good preliminary introduction.
There are two libraries involed
#include and #include
iostream gives us 3 objects
cin cout cerr
which have been discussed
fstream imports into the namespace two more functions which look very Perl like
ofstream FILEHANDLE outfile_name_with_path ifstream FILEHANDLE infile_name_with_path
The side affect of these functions is that they create filehandle objects FILEHANDLE that can then function like cin and cout
The third program from this chapter shows their use. I altered it a little for our purposes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 #ifndef HEAD_H 2 #define HEAD_H 3 4 #include 5 #include 6 #include 7 8 #endif 9 10 /***************************************************** 11 * Program file3.C from page 22 of Lippman * 12 * Modified to include namespace, preprossor commands * 13 * and endl macro as called for * 14 * Ruben Safir June 29th, 2008 * 15 *****************************************************/ 16 using namespace std; 17 18 int main(){ 19 20 ofstream OUTFILE("/home/ruben/cplus/testpass.txt"); 21 ifstream INFILE("/etc/passwd"); 22 if(! INFILE ){ 23 cerr << "Can't open password file"; 24 return -1; 25 } 26 if(! OUTFILE ){ 27 cerr << "Can't open testpass.txt file"; 28 return -2; 29 } 30 31 string word; 32 while( INFILE >> word) 33 OUTFILE << word << ' '; 34 35 return 0; 36 } 37
Enjoy ~~~ Comments welcome, Questions VERY welcome and I'll be posting the next message in a day or so. In the middle of the week we can meet on line. If anyone needs help, email me or the list.
Ruben -- http://www.mrbrklyn.com - Interesting Stuff http://www.nylxs.com - Leadership Development in Free Software
So many immigrant groups have swept through our town that Brooklyn, like Atlantis, reaches mythological proportions in the mind of the world - RI Safir 1998
http://fairuse.nylxs.com DRM is THEFT - We are the STAKEHOLDERS - RI Safir 2002
"Yeah - I write Free Software...so SUE ME"
"The tremendous problem we face is that we are becoming sharecroppers to our own cultural heritage -- we need the ability to participate in our own society."
"> I'm an engineer. I choose the best tool for the job, politics be damned.< You must be a stupid engineer then, because politcs and technology have been attached at the hip since the 1st dynasty in Ancient Egypt. I guess you missed that one."
© Copyright for the Digital Millennium
|
|