Programs

A program is a collection of functions. One of those functions must have the name main(). When program execution begins, main() will be called automatically, together with any parameters. The function main() must return an int.

The Function main()

After main() has been defined, the UnderC command #r (that is, run) causes a new console window to be created, showing the output generated by the program (see Figure 4.1), as in the following example:

;> int main() {
;1} cout << "Hello World
";
;1} return 0;
;1} }
;> #r

Figure 4.1. An example of the output generated by the program.


If main() is not defined, #r produces a “cannot find 'main'” error. The function main() is called the entry point of the program, and it should return a value, unlike in C. C++ compilers (like GCC, but not UnderC) are usually tolerant about returning a value from main(), but it's good to get into the habit of writing main() as a proper function.

main() can optionally have arguments, like this. The arguments follow the run command in UnderC:


;> int main(int argc, char *argv[]) {
;1}  for(int i=0; i < argc; i++)
;2}    cout << argv[i] << endl;
;1}  return 0;
;1} }
;> #r One Two Three


CON
One
Two
Three

The second argument of main(), argv, is basically an array of C-style strings. Notice that argv[0] is not the first argument passed; the command-line arguments are argv[1] to argv[argc-1]. The first value, argv[0], is the name of the file that contained the main() function (in this case, just CON, the console).

Building Your First Program

It's finally time to compile and run a complete C++ program. Before the code shown in the previous section will compile correctly, it needs the <iostream> header for the output stream. Save the following code as args.cpp using your favorite text editor, load it, and run the program:

// args.cpp
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
  for(int i=0; i < argc; i++)
    cout << argv[i] << endl;
  return 0;
}

If you installed the software from the CD, you should have a fully functioning version of the GNU C++ compiler on your system. The compiler's name is c++, and here is the result of compiling and running args.cpp on my system, at the command prompt (user input is bold):


C:olshucwchap4>c++ args.cpp
C:olshucwchap4>a
							One Two Three
C:BOLSHUCWCHAP4A.EXE
One
Two
Three

The compiler will work for a second or two, and the resulting compiled program will be called a.exe. (This name is an old Unix tradition.) You then run a.exe with three command-line arguments, and you get the expected output, except now argv[0] is the full path to the program. An interesting property of this program is that it does wildcard expansion: Any command-line arguments that contain wildcard characters (such as *) are expanded into a full list of files matching those wildcards. You can use this simple little program to list all the .cpp files you have in this directory:

C:olshucwchap4>a
							*.cpp
C:BOLSHUCWCHAP4A.EXE
args.cpp
basic.cpp
dll1.cpp
stack.cpp

NOTE

UnderC currently doesn't do wildcard expansion. The Borland compiler does not include this facility by default, but you can specify it as an option. See Appendix D for details on how to use other compilers.


Separate Compilation

Programmers often seem to be obsessed with the number of lines of code in their programs. Unfortunately, Windows doesn't come standard with an lc (for line count) command, but you can write a small function to count the number of lines in an input stream:


// count.cpp
#include <iostream>
using namespace std;

const int LINESIZE = 512;

int count_lines(istream& in)
{
 char buff[LINESIZE];
 int k = 0;
 while (in.getline(buff,LINESIZE)) ++k;
 return k;
}

;> #l count.cpp
;> ifstream ifs("args.cpp");
;> count_lines(ifs);
(int) 9

Note that this example does not pass count_lines() a file, but a reference (istream&) to an input stream. If you are not particularly interested in the text for each line, you can use the getline() method that quickly fetches the line into an array of characters. You can then compile count.cpp directly, but with the -c command-line flag, which means “don't attempt to link.” If you leave out this flag, the linker complains that it cannot find main(). The output is an object file count.o, which is the machine code. (If you use the Borland or Microsoft compilers, this file has a different extension: .obj. Object files from different compilers are in general not compatible.) Here I have compiled count.cpp into an object file and shown the resulting output file count.o (which will not be ASCII):

C:olshucwchap4>c++ -c count.cpp
C:olshucwchap4>dir count.o

 Volume in drive C has no label
 Volume Serial Number is 11F3-3136
 Directory of C:olshucwchap4

COUNT    O           4,629  26/07/01  12:59 count.o
         1 file(s)          4,629 bytes
         0 dir(s)     733,261,824 bytes free

You can compile and link this with a file that contains a main() function to produce an executable:


// main1.cpp
#include <iostream>
#include <fstream>
using namespace std;

int count_lines(istream& in);  // definition in count.cpp!

int main(int argc, char *argv[])
{
  ifstream in(argv[1]);
  cout << "lines " << count_lines(in) << endl;
  return 0;
}
C:olshucwchap4>c++ main1.cpp count.o
C:olshucwchap4>a
							main1.cpp
lines 12

You need lc to operate on standard input if there are no files and on all the supplied files. It is fairly easy to write a more sophisticated main() function that does this. Note that you can pass both the standard input stream (cin) and a file stream (ifstream object) to count_lines() because they are both istreams. In compiling this version I've used the -o option to name the output file lc.exe rather than a.exe:


// main2.cpp
#include <iostream>
#include <fstream>
using namespace std;

int count_lines(istream& in);  // definition in count.cpp!

int main(int argc, char *argv[])
{
 int lcount = 0;
 if (argc == 1)
   lcount = count_lines(cin);
 else for(int i = 1; i < argc; i++) {
   ifstream in(argv[i]);
   if (!in) cerr << "Can't open '" << argv[i] << "'
";
   else lcount += count_lines(in);
 }

 cout << lcount << " lines
";
 return 0;
}
C:olshucwchap4>c++ -o lc.exe main2.cpp count.o
C:olshucwchap4>dir | lc
52 lines
C:olshucwchap4>lc *.cpp *.h
289 lines

In the first command, the output of dir is 'piped' to lc as its standard input, which is then counted. Because the second command is given wildcard parameters, lc is actually passed a list of all .cpp and .h files.

In preparing the second version of lc, you don't have to recompile count.cpp, which shows the advantage of separate compilation. In a large project there may be dozens of files, each with many functions. Recompiling all these files would take minutes or even hours. But deciding what needs to be recompiled can be tricky (remember that if the include files change, the source file must also be recompiled). You need to either create a project in an integrated development environment (IDE) such as Quincy or write a make file. Appendix D, “Compiling C++ Programs and DLLs with GCC and BCC32,” describes this process in detail.

Usually, for each source file there is an include file (otherwise known as a header file) that has prototypes for all functions that need to be exported from that file. In this case it would be very short, because count.cpp only exports one function.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.123.155