text:
User:Jimregan/C Primer chapter 5

Programming In C++: Elementary Features
The C++ language is an "object-oriented" extension to C that supports fundamental C syntax but adds many new elements. This chapter provides an overview of its differences from C, while the next chapter discusses its central concept, classes.

C++ Fundamentals
A C++ program may at first look a great deal like a C program, and in fact most ANSI C programs can be compiled just fine under C++, but there are some differences.

The first and most obvious is that comments have a simplified form. While in C you would state:

/* This is a comment. This is a second comment. This is the last comment here. */

-- in C++ you would say:

// This is a comment. // This is a second comment. // This is the last comment here.

The second thing you notice in C++ is that simple I/O is performed differently than in C. C++ defines three standard I/O files:

cin:     Console input. cout:    Console output. cerr:    Console error output device.

-- and input and output operators ("<<" and ">>") to go along with them. For example, the following program adds two numbers:

// getxy.cpp

#include

void main {     double x, y;

cout << "Please enter X and Y.\n"; cin >> x;     cin >> y;      cout << "The sum of X and Y is " << x + y << ".\n"; }

This form of C++ I/O is not fussy about data types, and data formatting can be performed. For example, you can print data in different number formats:

// prbase.cpp

#include

void main {     int n = 666; cout << dec << n << ' ' << oct << n << ' ' << hex << n << '\n'; }

This prints the value as follows:

666 1232 29a

There is much more that can be said about C++ "stream I/O", but it will have to wait for a later section.

While C++ supports the ANSI C function definition style:

int example( int x, int y );

-- it also has some enhancements. Default parameter values can be specified:

int example( int = 0, int = 100 );

This means that if you call "example" as follows:

example;

-- then the default parameter values 0 and "100" will be specified. If you call it as:

example( -100 );

-- the parameter values will be -100 and 100. If you specify both parameters:

example( 1, 1000 );

-- then the values are "1" and "1000". You cannot specify only the second parameter:

example( ,1000 );

There are some other enhancements in function handling that will be discussed in a later section.

C++ incorporates the following additional keywords:

class delete friend inline new operator private protected public this virtual

These new keywords will be discussed in detail later in this document.

C++ Extensions to C

 * One unusual difference of C++ relative to C is that it allows function prototyping within the "main" program. C++ is not picky about placement of declarations, although a function has to be prototyped before it is used.

Similarly, C++ is not fussy about the placement of variable declarations, and they can be declared within a block if need be. For example, the following is perfectly legal in C++:

// vardec.cpp

#include

void main {     for( int l = 0; l < 5; l++ )  // Notice declaration of "l". {        cout << l << '\n'; }  }

There are some peculiarities in this declaration with respect to scope, however. The scope of the variable "l" is the current block, but only the portions of the current block after the declaration. Statements before the declaration cannot refer to that variable.

Another new feature of C++ is that you can refer to a global variable and a local variable that have the same name by using the "scope resolution operator", or "::". For example:

// prglob.cpp

#include

int n = 42;                         // Global variable.

void main {    int n = 666;                       // Local variable. cout << ::n << ' ' << n << '\n';  // Print global, then local variable. }

This displays:

42 666

C++ has a new mechanism to replace the function macros of C, which you may recall can have unpredictable behavior. In C++ you can define "inline functions" with the syntax:

inline ifunc( int x ) {    ...   }

The code for this function is inserted in the program wherever the function is invoked, allowing for faster execution at the expense of memory usage.

C++ also features some improvements in the "const" keyword. In C the "#define" preprocessor metacommand is used to define constants:

#define PI 3.141592654

In C++, the "const" keyword is preferred:

const double PI 3.141592654;

If you don't specify the data type, C++ will assume "int". The advantage of the "const" keyword is that it allows constant declarations to be made inside functions, resulting in constant values that are "local" to that function. (Of course, they can be used to define global constants as well.)

Another (minor) difference is in C++ handling of enumerated types. If you declare an enumerated type:

enum Color { Red, White, Blue, Green, Cyan, Magenta, Yellow, Black };

-- and then you declare a variable of that type, you don't have to specify it as an enum type:

Color cvar;

You can still use standard C libraries in C++, but you must provide a "linkage specification" to tell the C++ compiler that it is using functions compiled for C. For example, if you want to use a function from the C standard library in a C++ program, you would have to write:

// prnrnd.cpp

#include

extern "C" {    #include    }

void main {    cout << rand; }

C++ Memory Allocation -- Free & Delete
C++ has two new keywords, "new" and "delete", to perform variable memory allocation, in place of the C "malloc" and "free" routines. The "new" operator returns a pointer to memory allocated for a specified variable type from the "free store" reserved for the program, and the "delete" operator returns that memory to free store:

// alloc.cpp

#include

struct Date {    int month; int day; int year; };

void main {    Date *event = new Date;   // Allocate memory for variable of type Date. event->month = 7; event->day = 4; event->year = 1863; cout << "What happened on " << event->day << '/' << event->month << '/' << event->year << "?\n"; delete event;            // Deallocate memory. }

You don't have to specify "struct Date", as you would in C. The "new" and "delete" operators provide a much cleaner interface than "malloc" and "free".

For another example, consider the dynamic allocation of arrays:

// dynaloc.cpp

#include   #include

void main {     cout << "Array size: "; int size; cin >> size;                     // Get array size. int *array = new int[size];      // Allocate an array. for( int i = 0; i < size; i++ )  // Load it with random numbers. {       array[i] = rand; }     for( i = 0; i < size; i++ ) {       cout << array[i] << '\n'; }     delete array;                     // Return array to free store. }

Of course, if you dynamically allocate memory, there is a good chance that your program may run out of free store at some time, and so you need to be able to handle that circumstance. C++ includes a function named "set_new_handler" that allows you to specify a handler that will be invoked when the free store is exhausted:

// newhand.cpp

#include   #include    #include

static void memhandler {    cerr << "Out of memory!\n"; exit(1); }

void main {    set_new_handler( memhandler ); long sum = 0; while (1) {      char *cp = new char[10000]; sum += 10000; cout << "Memory allocated: " << sum << '\n'; }  }

C++ Function Overloading
A particular innovation in C++ relative to C is the use of "function overloading". In standard C, if you defined a function named "cube" that used "int" values, then you would have to define a function with a different name that handled "double" values. C++ allows you to have multiple functions of the same name in the same program by using the "overload" keyword:

// cubes.cpp

#include

long cube( long l ) {    return l * l * l;   }

double cube( double d ) {    return d * d * d;   }

void main {    long n1 = 3; double n2 = 5.0;

cout << cube( n1 ) << "\n" << cube( n2 ) << "\n"; }

This program defines a pair of overloaded functions. The type of parameter will determine which function will be called.

C++ Structures
C++ extends the concepts of data structures defined in C.

The first and simplest difference is that in C++ defining a structure creates a new data type. The only obvious consequence of this (as shown earlier) is that while in C every instance of a defined structure must be declared as a "struct":

struct Date { int month, day, year }; ...  struct Date today;       /* C structure instance declaration. */

-- in C++ the "struct" keyword is not required in the instance declaration. For an example of C++ structure declaration:

// cpstruct.cpp

#include

struct Date {    int month; int day; int year; };

static void display( Date );    // Function proto with "Date" parameter.

void main {    Date bday = { 2, 16, 1953 }; cout << "My birthday is: " << '\n'; display( bday ); }

static void display( Date d ) {    static char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; cout << months[d.month-1] << ' ' << d.day << ", " << d.year; }

You can also declare arrays of structures:

Date days[20];

-- or pointers to them.

The first really significant difference in structure definition under C++ compared to C is that you can specify functions as elements of structures.

This is a big step toward the concept of object-oriented programming. Now, instead of having a data structure that simply stores data items, you can have functions to work with the data "encapsulated" in the structure.

The following example modifies the previous one to illustrate such encapsulation:

// encaps.cpp

#include

struct Date {    int month, day, year; void display;               // Function bound to "Date" struct. };

void Date::display {    static char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; cout << months[month-1] << ' ' << day << ", " << year; }

void main {    Date bday = { 2, 16, 1953 }; cout << "My birthday is: " << '\n'; bday.display; }

There are some interesting things about this program. First, the encapsulated function is defined with:

void Date::display

-- to indicate that "display" is associated with the struct "Date". Note that a parameter of type "Date" is no longer defined, since the function is implicitly associated with a parameter of that form.

Similarly, the data fields are also directly accessible in the function:

cout << months[month-1] << ' ' << day << ", " << year;

It is not necessary to use the notation "d.months", "d.day", "d.year".

However, the function, being an element of that type of structure, is invoked using that notation:

bday.display;

Structures also allow function overloading. Different structures can have a function of the same name. For example:

// stover.cpp

#include   #include <stdio.h>   #include <time.h>

// *********************************************************************

struct Date // Date structure with a function named "display". {    int month, day, year; void display; };

void Date::display {    static char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; cout << months[month] << ' ' << day << ", " << year; }

// *********************************************************************

struct Time // Time structure with a function named "display". {    int hour, minute, second; void display; };

void Time::display {    char t[15]; sprintf( t, "%d:%2d:%2d %s",      ( hour > 12 ? hour - 12 : (hour == 0 ? 12 : hour )),      minute, second, ( hour < 12? "am" : "pm" )); cout << t;  }

// *********************************************************************  void main {    time_t ctime = time(0);             // Get current time. struct tm current = *localtime( &ctime );

Time now;                          // Instances of defined structures. Date today;

now.hour = current.tm_hour;        // Initialize Time structure. now.minute = current.tm_min; now.second = current.tm_sec;

today.month = current.tm_mon;      // Initialize Date structure. today.day = current.tm_mday; today.year = current.tm_year + 1900;

cout << "At the tone it will be "; // Display time and date. now.display; cout << " on "; today.display; cout << ".\n"; }

When invoked, this program produces an output of the form:

At the tone it will be 6:20:33 on March 17, 1995.

BACK_TO_TOP

[5.6] C++ REFERENCES

 * Along with the traditional means of passing parameters to functions as values:

int testfunc( int x );

-- or as pointers:

\Bint testfunc( int *x );

-- C++ provides an additional calling scheme, using "reference variables". This scheme is equivalent to using pointers, in that the function can change the value in the variable and return it to the calling program without having the overhead of passing all the data to the function. However, it doesn't require the use of pointer dereferencing operations in the target function, making it easier to pass structures and arrays to functions.

Reference variables are a slightly fuzzy concept, so please bear with the discussion. It will become clearer as elements are introduced.

A reference variable is defined as an "alias", or synonym, for a variable. It is defined using the "&" operator:

int some_int; int& ref_to_int = some_int;

This use of "&" is distinct from its use as the "address of" operator:

&some_int

-- which gives the address of a variable. The reference is initialized when it is declared -- naturally, since it doesn't have any independent existence.

The following example illustrates the behavior of reference variables:

// reftest.cpp

#include <iostream.h>

void main {    int some_int = 42; int& ref_to_int = some_int;

cout << some_int << ' ' << ref_to_int << '\n';  // Print values. ref_to_int++;                                   // Increment reference. cout << some_int << ' ' << ref_to_int << '\n';  // Print values. some_int++;                                     // Increment variable. cout << some_int << ' ' << ref_to_int << '\n';  // Print values. cout << &some_int << ' ' << &ref_to_int << '\n'; // Print addresses. }

This prints:

42 42  43 43   44 44   0x6555fffc 0x6555fffc

A reference, as this example shows, is not a copy of nor a pointer to the variable it aliases. It is simply another name for it.

 * References are generally used in conjunction with arrays, structures, and class objects, to be discussed in the next chapter. There's not really much reason to define references for simple "int" or "float" variables.

The reason for having references is to simplify parameter passing to functions, as noted earlier in this section. They eliminate the overhead of passing large data structures to functions, eliminate the need for pointer dereferencing operations, and allow a function to modify the data from the source program.

For example:

// ptrdemo.cpp

#include <iostream.h>

struct big    // A big structure that doesn't do much of anything. {    int sn; char text[1024]; } b = { 42, "Life, the Universe, and Everything!" };

void fslow( big b1 );  // Function to call the big structure by value. void ffast( big& b2 ); // Function to call the big structure by reference.

void main {    fslow( b );           // Slow, because data must be put on stack. ffast( b );          // Fast, because data is directly accessed. }

void fslow( big b1 ) {    cout << b1.sn << '\n' << b1.text << '\n'; }

void ffast( big& b2 ) {    cout << b2.sn << '\n' << b2.text << '\n'; }

A second example illustrates how references accomplish the same thing as pointers but don't require the clumsy pointer dereferencing syntax:

// refdemo.cpp

#include <iostream.h>

struct big    // Same big struct as before. {    int sn; char text[1024]; } b = { 42, "Life, the Universe, and Everything!" };

void fptr( big *b1 );   // Function to use pointers. void fref( big& b2 );   // Function to use references.

void main {    fptr( &b ); fref( b ); }

void fptr( big *b1 ) {     cout << b1->sn << '\n' << b1->text << '\n';  // Pointer deference. }

void fref( big& b2 ) {    cout << b2.sn << '\n' << b2.text << '\n';    // As before. }

A function can, as noted, change the value of the referenced variable in the calling program. If this is not desired, in the case where you simply want fast and economical parameter passing, you can declare a reference as a constant:

void func( const somestr& d ); // Parameter "d" can't be changed.

References can also be returned by functions to calling programs:

&getref( int i );         // Prototype for function to return reference. ...  somestr& r = getref( 3 );  // Return reference value to calling routine.

Remember that a reference is an alias. You cannot really perform any operation on a reference but initialize it, since any other operation you perform on the reference is simply performed on the variable referenced. You also cannot define arrays of references.

v2.0.7 / 6 of 7 / 01 feb 02 / greg goebel / public domain

title: User:Jimregan/C Primer chapter 5


text:
User:Jimregan/C Primer chapter 6

Programming In C++: Classes
The central core concept of C++ is the class, and this chapter describes its essential features in an introductory fashion. The ramifications of classes are highly complicated, and this chapter does not, could not, explain them in detail. It simply provides a basis for further study.

C++ Classes
In C, you define variables of various types and create functions to manipulate them. In C++, you define variables and functions and bind them together as a new data type, or "class".

We've already seen how in C++ structures can encapsulate both data and functions. A C++ class is an extension of the definition of C++ structures that adds several important features.

To start off the discussion, let's define a class to define cubes. This example has a few new features which will be explained in following text:

// clscube.cpp

#include

class Cube                        // Cube class. {    private: int height, width, depth;     // Private data members. public: Cube( int, int, int );        // Constructor function prototype. ~Cube;                      // Destructor function prototype. int volume;                 // Member function prototype. };

Cube::Cube( int h, int w, int d ) // Constructor function definition. {    height = h;     width = w;     depth = d;   };

Cube::~Cube                     // Destructor function definition. {    // Does nothing. };

int Cube::volume                // A member function (computes volume). {    return height * width * depth; };

void main                       // This program demonstrates the class. {    Cube somecube( 3, 3, 3 );        // Allocate a cube. cout << somecube.volume << '\n'; }

This example has a few interesting new features. The most important feature is that the class definition is divided into two sections: a "public" section (which, in this case, contains the class's function definitions) and a remaining "private" section (containing variables in this case) which is hidden from view from outside the class.

You could define either functions or variables as either "public" or "private", but in practice the idea is to hide the variables and only allow access to them through functions, so the division in this example is typical and is the recommended usage.

This is one of the essentials of the class concept: to hide data details from the program, allowing it to manipulate data elements through member functions without any knowledge of the actual data structure. This allows a considerable degree of data independence.

The default is "private". If you don't specify if class element is "public" or "private", it is automatically defined as "private".

You can also use "public" and "private" in structure definitions, but once you do so, you might as well declare a class and be done with it. There are some other keywords related to "public" and "private", but we'll put off discussion of them to later.

Note the definition of the function "Cube":

Cube::Cube( int h, int w, int d )

This is a special member function, called a "constructor", that is used to initialize an instance of a class when it is created. The declaration of an instance of a class automatically and transparently invokes the constructor.

In this example, an instance of the class is declared and allocated as follows:

Cube somecube( 3, 3, 3 );

This declaration invokes the constructor function to initialize the instance.

You can also specify default values if desired in the constructor definition:

Cube::Cube( int h = 1, int w = 1, int d = 1 )

In this case, if you define an instance of the class without parameters:

Cube defcube;

-- then its three private variables will all default to a value of 1.

A constructor function doesn't return a value and so it is not declared as a type, not even of type "void".

There is another curious definition here, for the function "~Cube". This is a "destructor" function, and it is automatically and transparently called when the program exits the context in which the class instance was created.

In this case, the destructor doesn't really do anything, it's just there to illustrate the thing exists. A destructor is useful when the constructor allocates memory that must be returned to the free pool after the class has outlived its usefulness. A destructor is also automatically and transparently invoked when the program context in which the class is defined is exited.

Neither constructors nor destructors are required for class definitions.

 * Member functions, which actually do the work the class was defined to do, are declared as they are in C++ structures:

int Cube::volume

The member function, as with C++ structures, of course has direct access to the structure's variables and so they don't need to be specified as parameters.

The class can contain functions defined either as conventional functions or as inline functions, discussed in the previous chapter. C++ notation allows the inline functions to be incorporated directly into the class definition.

For example, the class definition in the example above could be made much more compact by eliminating the unneeded destructor function and writing the remaining constructor and member function in inline form:

class Cube {      int height, width, depth;   // Implied "private" variables. public: Cube( int h, int w, int d ); { height = h; width = w; depth = d; } int volume; { return height * width * depth; } };

This gives the complete class definition. Notice that the inline functions are coded on a single line, which is a common convention that emphasizes their nature as inline functions. It is a good rule of thumb that if an inline function can't be coded on a single line, it shouldn't be an inline function.

It is also possible to have overloaded constructor functions that perform different actions when given different parameters:

class Cube {      int height, width, depth; public: Cube; Cube( int h, int w, int d ); { height = h; width = w; depth = d; } int volume; { return height * width * depth; } };

In this class definition, there are two constructor functions, one which has no parameters and doesn't initialize the private variables, and one that had parameters and does.

As a class is a C++ data type, it can imply the use of type conversions. If you assign an "int" value to a "float" variable, C or C++ will automatically perform the appropriate conversion. Of course, this requires a certain amount of smarts on the part of the compiler to recognize the need for the conversion, since the number formats are very different and the bits from the "int" variable need to be rearranged.

Since the C++ compiler doesn't have any more knowledge of a class than you define for it, it can't automatically perform type conversions, so you have to provide functions yourself for your class to do the job. This is a somewhat advanced topic and a detailed discussion of it is beyond the scope of this document, but the following example demonstrates:

// julie.cpp

#include

class Julian  // Julian (date by number of day in year) date class. {      int day, year; public: Julian {} Julian( int d, int y ) { day = d; year = y; } void display { cout << year << '-' << day << "\n"; } int& getday { return day; } };

class Date    // Month-day-year class. {      int month, day, year; public: Date( int m, int d, int y ) { month = m; day = d; year = y; } operator Julian; // Conversion function. };

class Tester  // A class that is initialized to a Julian date. {      Julian jd; public: Tester( Julian j ) { jd = j; } void display { jd.display; } };

static int ndays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

Date::operator Julian  // Julian <- Date conversion member function. {    Julian jd( 0, year ); for( int i = 0; i < ( month - 1 ); i++ ) {      jd.getday += ndays[i]; };    jd.getday += day; return jd; };

void dispdate( Julian jd )  // A function that expects a Julian date. {    jd.display; };

void main  // Illustrate the different ways to perform the conversion. {    Date dt( 03, 25, 95 ); Julian jd; jd = dt;               // Convert Date to Julian by assigment. cout << "assignment: "; jd.display; jd = (Julian) dt;      // Convert Date to Julian by cast. cout << "cast: "; jd.display; jd = Julian( dt );     // Convert by calling conversion function. cout << "function: "; jd.display; cout << "parameter: "; dispdate( dt );        // Convert by using as function parameter. Tester ts( dt );       // Convert by initialization. cout << "init: "; ts.display; }

This example creates an "operator" function associated with the "Date" class:

Date::operator Julian

-- that takes an instance of the "Date" class and converts it to the "Julian" class. The C++ compiler is smart enough to figure out how to use this function in the appropriate circumstances.

One interesting point about this example is that it illustrates the properties of references. In accordance with the good principles of data hiding, the only access to the "day" member function of class "Julian" is through the "getday" member function:

int& getday { return day; }

This function returns a reference to the "day" member variable. This allows the function to be used on both sides of an equation, a concept quite alien to C:

jd.getday += ndays[i];

This is possible because "jd.getday", as a reference, is seen by the formula simply as the "day" member variable, so as far as the equation is concerned this is exactly comparable to:

jd.day += ndays[i];

The example above converts from one class to another. The conversion could be from a to a simpler data type, such as a "long", if desired.

While date hiding is an essential component of C++'s object-oriented philosophy, like all rules sometimes it is wiser to break it, and C++ actually provides a provision for breaking it in a controlled fashion.

One class can allow another class to access their private member functions by declaring the class as "friend":

// cpfriend.cpp

#include

class Date;   // "Prototype" for Date class definition.

class Julian  // Julian (date by number of day in year) date class. {      int day, year; public: Julian {} Julian( int d, int y ) { day = d; year = y; } void display { cout << '\n' << year << '-' << day; } friend Date;  // Date members have access to Julian private members. };

class Date    // Month-day-year class. {      int month, day, year; public: Date( int m, int d, int y ) { month = m; day = d; year = y; } operator Julian; // Conversion function. };

static int ndays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

Date::operator Julian  // Julian <- Date conversion member function. {    Julian jd( 0, year ); for( int i = 0; i < ( month - 1 ); i++ ) {      jd.day += ndays[i];   // This Date member function has access to     }                       // Julian private variables. jd.day += day; return jd; }

void main {    Date dt( 11, 17, 89 ); Julian jd; jd = dt; jd.display; }

Since the "Julian" class definition refers to the "Date" class definition before it is defined in the program listing, the "Date" class is "prototyped" to keep the compiler from getting confused:

class Date;

The "Julian" class defines "Date" as a "friend" function with:

friend Date;

-- and so the "Date" conversion function can have access to a "Julian" private variable:

jd.day += ndays[i];

Actually allowing an entire class access to another class is not recommended procedure, however, and it is just as easy to only allow access by one member function. In the example above, the "Julian" definition could be modified by adding the declaration:

friend Date::Date( Julian );

You can declare an element of a class as "static", in which case all instances of the class access one and the same element. For example, a static class variable is a "global" variable, if just for that particular class. You can also have "static" member functions, which are simply member functions that only access static member variables.

Another related C++ concept is the "this" pointer, which is just a pointer to the instance of an object that a member function is executing in. This may seem a little absurd. After all, if the member function is executing in one instance of a particular object, it obviously has access to that instance's member functions:

void Date::dispmonth {    cout << month;                      // Display the month. cout << this->month;               // Display the month. }

-- but the trick is that the member function can return the pointer to let some other function know what object it is executing in:

return *this;        // Return object pointed to by "this".

C++ Operator Overloading
Along with the ability to overload functions, C++ provides the ability to overload operators. C itself actually has overloaded operators; "+", for instance, can be used to add a variety of data types even though the addition operation is performed differently for each. C++ simply extends this concept to allow the user to define his or her own overloaded operators.

The following example overloads the "+" operator to allow an "integer" to be added to an instance of the "Date" class, returning an instance of the "Date" class:

// overops.cpp

#include

class Date    // Month-day-year class. {      int month, day, year; public: Date( int m, int d, int y ) { month = m; day = d; year = y; } void display { cout << month << '/' << day << '/' << year; } Date operator+(int)      // Overloaded "+" operator. };

static int ndays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

Date Date::operator+(int n)        // Overloaded "+" operator. {    Date dt = *this;                  // Connect to current object instance. n += dt.day while( n > ndays[dt.month - 1]   // Add integer number to date.     {       n -= ndays[dt.month - 1];       {         if( ++dt.month == 13 )	 {	   dt.month = 1;	   dt.year++;	 }       }       dt.day = n;       return dt;                      // Return date object.     }

void main {    Date olddate( 5, 3, 95 ); Date newdate; newdate = olddate + 21;          // Add integer to date. newdate.display; }

Notice the use of the "this" pointer to return the object so it can be assigned to "newdate". This is an extremely important use of the "this" pointer.

Operator overloading can be performed by similar means for other binary arithmetic operations, for relational operations, increment and decrement operators, array subscripting, and so on. Be warned that operator overloading is tricky, can cause a lot of trouble, and must be done wisely. One C++ guru once noted that C++ programmers first learn to overload operators, and then they learn not to.

C++ Class Inheritance
One of the important features of classes is that, once you define a class, you can build, or "derive", classes from it that are a superset of the original, or "base", class's capabilities. This feature is known as "class inheritance". This scheme allows you to define a general base class -- say, as an arbitrary silly example, a class to describe a bird -- and then derive new classes from it to define more specific types -- say, derived classes to describe hawks, owls, ducks, hummingbirds, and so on.

Let's consider a base class definition for a class named "Time" along with a derived class named "Timezone":

// derive.cpp

#include

// *** Time class definition. ****************************************

class Time {    protected: int hours, minutes, seconds; public: Time( int hr, int min, int sec ); void display; };

Time::Time( int hr, int min, int sec ) {    hours = hr; minutes = min; seconds = sec; }

void Time::display {    cout << hours << ':' << minutes << ':' << seconds; }

enum timezone { gmt, est, cst, mst, pst };

// *** TimeZone class definition. ************************************

class TimeZone : public Time {      timezone zone; protected: const char *Zone; public: TimeZone( int h, int min, int sec, timezone zn ); void display; };

static const char *TZ[] = { "GMT", "EST", "CST", "MST", "PST" };

TimeZone::TimeZone( int hr, int min, int sec, timezone zn ) : Time( hr, min, sec ) {    zone = zn; }

void TimeZone::display {    Time::display; cout << ' ' << Zone; }

const char *TimeZone::Zone {    return TZ[zone]; }

// *** Main program. **************************************************

void main {    Time tm( 10, 13, 30 ); tm.display; cout << '\n'; TimeZone tz( 11, 14, 35, est ); tz.display; }

There are several interesting features in this program. First, the "protected" keyword is used in the "Time" class definition. This is almost the same as the "private" keyword, but it allows classes derived from this base class to have access to that keyword, a privilege they don't get if it is are declared "private".

The "TimeZone" class is derived from the "Time" class with the statement:

class TimeZone : public Time { ... }

The derived class can declare the base class as "private", "public", or "protected".

Calling a constructor function for a derived class implies calling the constructor function for the base class. You have to specify the relationship of the constructor's parameters between the two classes as follows:

TimeZone::TimeZone( int hr, int min, int sec, timezone zn ) : Time( hr, min, sec )

C++ class construction also allows a curious reversal of this relationship. A base class can have a "virtual" function, declared, say, as:

virtual void display;

-- that, when invoked through a derived class, passes execution back to the overloaded function in the derived class.

Both the base and derived class have a function named "display". This implies function overloading on the part of the derived class, meaning its version of "display" will be called rather than that of the base class.

It is possible of course to then derive further classes from the derived class, or derive a class from multiple classes ("multiple inheritance").

C++ Input/Output Streams
Previous examples in this discussion have used the "iostream" capabilities of C++ for console I/O:

cout << "What's your name? "; cin >> name;

The "iostream" capabilities are actually defined by classes that permit general-purpose I/O. These classes are derived by a (mostly hidden) base class named "ios".

These classes have much more functionality than has been used so for. For starters, C++ output is "buffered", meaning that you can output from a program for some time before an output buffer is filled and the buffer is dumped to standard output. You can force the buffer to be dumped using the "flush" operator:

cout << "Danger, Will Robinson!\n"" << flush;

Other useful new functions allow you to set fixed or format numeric output formats (the default is scientific), the output width, and the padding character used to fill out the field:

// strsci.cpp

#include

void main {    pi = 3.141; cout.setf( ios::fixed, ios::scientific ); // Set fixed, clear scientific. cout.width( 10 );                        // 10 character output width. cout.fill("*");                          // Set "*" as pad character. cout << pi << '\n'; }

This prints:

*****3.141

The "iostream" class also contains a number of member functions that duplicate the functionality of C console-I/O routines:

// strcons.cpp

#include

void main {    char c, l[100], s[] = "Banzai!";

// Output a character.

cout.put( 'X' ); cout.put( '\n' );

// Get a character.

cout << "Input a character, then press Enter: "; cin.get( c ); cout << "You input: " << c << '\n'; cin.get( c ); // Get a line of text terminated by a newline.

cout << "Type a line of text, then press Enter: " << "\n\n"; cin.getline( l, 100 ); cout << '\n' << "You entered: " << l << "\n\n";

}

Finally, you can use more or less the same operations for reading and writing files. This requires use of the "fstream" class (which is a superset of the "iostream" class and so supports its functionality). For example:

// strfile.cpp

#include

void main {     int n;

ofstream outfile( "data.txt" );     // Open output file. for( n = 1; n <= 10; ++n )          // Dump text to it. {       outfile << n << '\n'; }     outfile.close;                     // Close it.

ifstream infile( "data.txt" );      // Open it again. while( 1 )                          // Read to EOF. {       infile >> n;                       // Get number. if( infile.eof) {    	  break; }    	cout << n << '\n';                 // Output it. }       infile.close; }

The "get" and "getline" functions work as well.

v2.0.7 / 6 of 7 / 01 feb 02 / greg goebel / public domain

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

title: User:Jimregan/C Primer chapter 6


text:
User:Jimregan/C Primer chapter 7

C Quick Reference
This section contains a sample program to give syntax examples for fundamental C statements, followed by a list of library routines. This list is very terse and assumes that you are simply looking for reminders. If you need more details, please refer to the previous chapters.

/* sample.c: a silly program to give syntax examples. */

#include           /* Include header file for console I/O. */

int f1( int p );            /* Function prototypes. */  long f2( void ); long g;                     /* Global variable. */

int main( int argc, char *argv[] ) {    float f;                   /* Declare variables. */    int ctr; extern long g;

printf( "Arguments:\n\n" ); for( ctr = 0; ctr < argc; ctr++ ) {      puts( argv[ctr] ); }

printf( "\nFunction 1:\n\n" ); ctr = 0; while( ctr < 5 ) {       printf( "%d\n", f1( ctr++ ) ); }

printf( "\nFunction 2:\n\n" ); ctr = 0; do     { g = ctr++; printf( "%d\n", f2 ); }    while( ctr < 5 );

exit( 0 ); }

int f1( int p ) {     return( ( p < 3 ) ? p : p * p ); }

long f2( void ) {    extern long g;     return( g * g ); }

 * Console I/O: #include

int printf( char *s, ) > 0;    Print formatted string to stdout. int scanf( char *s, * ) != EOF: Read formatted data from stdin. int putchar( int ch ):                   Print a character to stdout. int getchar != EOF:                    Read a character from stdin. int puts( char *s ):                     Print string to stdout, add \n. char *gets != NULL:                    Read line from stdin (no \n).

 * PC console routines: #include

int getch != 0:         Get a character from the keyboard (no Enter). int getche != 0:        Get a character from the keyboard and echo it. int kbhit != 0:         Check to see if a key has been pressed.

 * Format codes:

%h:     short int (scanf only) %d:     decimal integer %ld:    long decimal integer %c:     character %s:     string %e:     exponential floating-point %f:     decimal floating-point %g:     use %e or %f, whichever is shorter (printf only) %u:     unsigned decimal integer %o:     unsigned octal integer %x:     unsigned hex integer

%10d:   10-character field width. %-10d   Left-justified field. %6.3f   6-character field width, three digits of precision.

'\0NN': character code in octal. '\xNN': character code in hex. '\0':   NULL character.

 * File-I/O: #include

FILE *fopen( char *f, char *mode ) != NULL;         Create or open file. int fclose( FILE *f );                              Close a file.

rewind( FILE *f );                                  Rewind. rename( char *old, char *new );                     Rename a file. remove( char *name );                               Delete a file.

fseek( FILE *f, long offset, int origin) == 0;      Seek.

fprintf( FILE *f, char *fmt, ) > 0;       Formatted write. fscanf( FILE *f, char *fmt, & ) != EOF;    Formatted read. fwrite( void *b, size_t s, size_t c, FILE *f ) > 0; Unformatted write. fread( void *b, size_t s, size_t c, FILE *f ) > 0;  Unformatted read.

putc( int c, FILE *f );                             Write character. int getc( FILE *f ) != EOF;                         Read character. fputs( char *s, FILE *f );                          Write a string. fgets( char *s, int max, FILE *f) != NULL;          Read a string.

sprintf( char *b, char *fmt, );           Print into string. sscanf( char *b, char *fmt, & ) > 0;       Scan string.

 * File modes:

r:   Open for reading. w:   Open and wipe (or create) for writing. a:   Append -- open (or create) to write to end of file. r+:  Open a file for reading and writing. w+:  Open and wipe (or create) for reading and writing. a+:  Open a file for reading and appending.

 * Offset values:

SEEK_SET:  Start of file. SEEK_CUR:  Current location. SEEK_END:  End of file.

 * Math library: #include

double sin( double x ):           Sine of x (in radians). double cos( double x ):           Cosine of x.   double tan( double x ):            Tangent of x.   double asin( double x ):           Inverse sine of x.   double acos( double x ):           Inverse cosine of x.   double atan( double x ):           Inverse tangent of x.   double sinh( double x ):           Hyperbolic sine of x.   double cosh( double x ):           Hyperbolic cosine of x.   double tanh( double x ):           Hyperbolic tangent of x.   double exp( double x ):            Exponential function -- e^x. double log( double x ):           Natural log of x.   double log10( double x ):          Base 10 log of x.   double pow( double x, double y ):  Power function -- x^y. double sqrt( double x ):          Square root of x.   double ceil( double x ):           Integer >= x (returned as double). double floor( double x ):         Integer <= x (returned as double). double fabs( x ):                 Absolute value of x.

 * Standard utility library: #include

double atof( char *nvalstr ) != 0; Convert numeric string to double. int atoi( char *nvalstr )   != 0;  Convert numeric string to int. long atol( char *nvlastr )  != 0;  Convert numeric string to long. int rand;                        Generates pseudorandom integer. srand( unsigned seed );            Seed random-number generator. exit( int status );                Exits program. int system( char *syscmd )  == 0;  Execute system program. int abs( int n );                  Absolute value of int. long labs( long n );               Absolute value of long.

 * Time & date library: #include

time_t time( time_t *timeptr );    Current time count as long int. char *ctime( time_t *timeptr );    Current time & date string.

 * String function library: #include

int strlen( char *s );                         Length. strcpy( char *dst, char *src );                Copy. strncpy( char *dst, char *src, size_t n );     Copy n characters max. strcat( char *dst, char *s );                  Concatenate. strncat( char *d, char *s, size_t n );         Concatenate n characters. strcmp( char *s1, char *s2 )            == 0:  Compare. strncmp( char *s1, char *s2, size_t n ) == 0;  Compare n characters. stricmp( char *s1, char *s2 )           == 0;  Compare, no case. strnicmp( char *s1, char *s2, size_t n ) == 0; Compare, no case, n chars. char *strchr( char *s, int ch )      != NULL;  Find first character. char *strrchr( char *s, int ch )     != NULL;  Find last character. char *strstr( char *dst, char *src)  != NULL;  Find string. char *strlwr( char *s );                       Lowercase. char *strupr( char *s );                       Uppercase.

 * Character class test library: #include

int isalnum( int c ) != 0;        Alpha / digit. int isalpha( int c ) != 0;        Alpha. int iscntrl( int c ) != 0;        Control character. int isdigit( int c ) != 0;        Decimal digit. int isgraph( int c ) != 0;        Printing character (except space). int islower( int c ) != 0;        Lower-case. int isprint( int c ) != 0;        Printing character (including space). int ispunct( int c ) != 0;        Printing character but not space/alnum. int isspace( int c ) != 0;        Space, FF, LF, CR, HT, VT. int isupper( int c ) != 0;        Upper-case. int isxdigit( int c ) != 0;       Hex digit.

int tolower( int c );             Convert to lower case. int toupper( int c );             Convert to upper case.

 * Dynamic memory allocation: #include

buf = ( *)malloc( (size_t)sizeof * ) != NULL; free( *buf );

v2.0.7 / 7 of 7 / 01 feb 02 / greg goebel / public domain

title: User:Jimregan/C Primer chapter 7


text:
User:IntMan

I am now a senior in high school. I have been working on the Calculus wikibook every so often, and plan on resuming so in late August 2004.

title: User:IntMan


text:
Calculus/Introduction

What is calculus?
Calculus is the broad area of mathematics dealing with such topics as instantaneous rates of change, areas under curves, and sequences and series. Underlying all of these topics is the concept of a limit, which consists of analyzing the behavior of a function at points ever closer to a particular point, but without ever actually reaching that point. As a typical application of the methods of calculus, consider a moving car. It is possible to create a function describing the displacement of the car (where it is located in relation to a reference point) at any point in time as well as a function describing the velocity (speed and direction of movement) of the car at any point in time. If the car were traveling at a constant velocity, then algebra would be sufficient to determine the position of the car at any time; if the velocity is unknown but still constant, the position of the car could be used (along with the time) to find the velocity.

However, the velocity of a car cannot jump from zero to 35 miles per hour at the beginning of a trip, stay constant throughout, and then jump back to zero at the end. As the accelerator is pressed down, the velocity rises gradually, and usually not at a constant rate (i.e., the driver may push on the gas pedal harder at the beginning, in order to speed up). Describing such motion and finding velocities and distances at particular times cannot be done using methods taught in pre-calculus, whereas it is not only possible but straightforward with calculus.

Calculus has two basic applications: differential calculus and integral calculus. The simplest introduction to differential calculus involves an explicit series of numbers. Given the series (42, 43, 3, 18, 34), the differential of this series would be (1, -40, 15, 16). The new series is derived from the difference of successive numbers which gives rise to its name "differential". Rarely, if ever, are differentials used on an explicit series of numbers as done here. Instead, they are derived from a continuous function in a manner which is described later.

Integral calculus, like differential calculus, can also be introduced via series of numbers. Notice that in the previous example, the original series can almost be derived solely from its differential. Instead of taking the difference, however, integration involves taking the sum. Given the first number of the original series, 42 in this case, the rest of the original series can be derived by adding each successive number in its differential (42+1, 43-40, 3+15, 18+16). Note that knowledge of the first number in the original series is crucial in deriving the integral. As with differentials, integration is performed on continuous functions rather than explicit series of numbers, but the concept is still the same. Integral calculus allows us to calculate the area under a curve of almost any shape; in the car example, this enables you to find the displacement of the car based on the velocity curve. This is because the area under the curve is the total distance moved, as we will soon see.

Why learn calculus?
Calculus is essential for many areas of science and engineering. Both make heavy use of mathematical functions to describe and predict physical phenomena that are subject to continuous change, and this requires the use of calculus. Take our car example: if you want to design cars, you need to know how to calculate forces, velocities, accelerations, and positions. All require calculus. Calculus is also necessary to study the motion of gases and particles, the interaction of forces, and the transfer of energy. It is also useful in business whenever rates are involved. For example, equations involving interest or supply and demand curves are grounded in the language of calculus.

Calculus also provides important tools in understanding functions and has led to the development of new areas of mathematics including real and complex analysis, topology, and non-euclidean geometry. Notwithstanding calculus' functional utility (pun intended), many non-scientists and non-engineers have chosen to study calculus just for the challenge of doing so. A smaller number of persons undertake such a challenge and then discover that calculus is beautiful in and of itself.

What is involved in learning calculus?
Learning calculus, like much of mathematics, involves two parts:

 * Understanding the concepts: You must be able to explain what it means when you take a derivative rather than merely apply the formulas for finding a derivative.  Otherwise, you will have no idea whether or not your solution is correct.  Drawing diagrams, for example, can help clarify abstract concepts.

 * Symbolic manipulation: Like other branches of mathematics, calculus is written in symbols that represent concepts.  You will learn what these symbols mean and how to use them.  A good working knowledge of trigonometry and algebra is a must, especially in integral calculus.  Sometimes you will need to manipulate expressions into a usable form before it is possible to perform operations in calculus.

What you should know before using this text
There are some basic skills that you need before you can use this text. Continuing with our example of a moving car:

 * You will need to describe the motion of the car in symbols. This involves understanding functions.
 * You need to manipulate these functions. This involves algebra.
 * You need to translate symbols into graphs and vice versa. This involves understanding the graphing of functions.
 * It also helps (although it isn't necessarily essential) if you understand the functions used in trigonometry since these functions appear frequently in science.

Scope
The first four chapters of this textbook cover the topics taught in a typical high school or first year college course. The first chapter, ../Precalculus/, reviews those aspects of functions most essential to the mastery of calculus. The second, ../Limits/, introduces the concept of the limit process. It also discusses some applications of limits and proposes using limits to examine slope and area of functions. The next two chapters, ../Differentiation/ and ../Integration/, apply limits to calculate derivatives and integrals. The Fundamental Theorem of Calculus is used, as are the essential formulas for computation of derivatives and integrals without resorting to the limit process. The third and fourth chapters include articles that apply the concepts previously learned to calculating volumes, and as other important formulas.

The remainder of the central calculus chapters cover topics taught in higher-level calculus topics: parametric and polar equations, sequences and series, multivariable calculus, and differential equations.

The final chapters cover the same material, using formal notation. They introduce the material at a much faster pace, and cover many more theorems than the other two sections. They assume knowledge of some set theory and set notation.

title: Calculus/Introduction


text:
User talk:IntMan

Welcome to the open content textbook project, I am very excited to have you interested in contributing. Any work you do will be the basis for the future's most used textbooks. Are you thinking about submitting the physics stuff you did ? My next pet project will be based on the physics class I just took, and I feel great about the material I have, but maybe you can do even better. Best of luck and see ya 'round, -- Karl Wick

title: User talk:IntMan