#include <stdlib>
#include <iostream>
int main()
{ int x, y;
std::cout << "Please enter two numbers: ";
std::cin >> x >> y; // input stream
int sum = x + y;
std::cout << "Their sum is " << sum << std::endl;
return EXIT_SUCCESS;
}
bool char short int long float double enum |
true, false character - 'A' short integer integer long integer single-precision floating-point number double-precision floating-point number enumeration - a set of discrete values |
cout << 'a' << int('a') << static_cast<int>('a');
enum Color { RED, GREEN, BLUE }; // default values are 0, 1, 2
enum Mood { HAPPY = 3, SAD = 1, ANXIOUS = 4, SLEEPY = 2 };
Color skyColor = BLUE;
Mood myMood = SLEEPY;
char ch = 'Q';
char* p = &ch; // p holds the address of ch
cout << *p; // outputs the character 'Q'
ch = 'Z'; // ch now holds 'Z'
cout << *p; // outputs the character 'Z'
C++ provides no build-in runtime checking for array subscripting out of bounds [common programming error]!double f[3]; // array of 3 doubles f[0], f[1], f[2]
double* p[10]; // array of 10 double pointers p[0]..p[9]
f[2] = 2.5;
p[4] = &f[2]; // p[4] points to f[2]
cout << *p[4]; // outputs 2.5
int a[] = { 10, 11, 12, 13 }; // initialization
int b[20] = { 0 }; // initialize all elements with value 0
Given two arrays c and d, the comparison c == d does not test whether the contents of the two arrays are equal.char ch[] = {'c', 'a', 't'};
char* p = c; // p points to c[0]
char* q = &c[0]; // q also points to c[0]
cout << c[2] << p[2] << q[2]; // outputs "ttt"
#include<string>;
using std::string;
//...
string s = "to be";
string t = "not " + s; // t = "not to be"
string u = s + " or " + t; // u = "to be or not to be"
if (s > t) cout u;
//...
s = "John";
int i = s.size(); // i = 4
char c = s[3]; // c = 'n'
s += " Smith"; // s = "John Smith"
char *p = s.c_str(); // p is a C-style string
This defines a new type called Passenger. The individual member of the structure variable (object) are accepted using the member selection operator, which has the form struct_variable.member.enum MealType { NO_PREF, REGULAR, LOW_FAT, VEGETARIAN };
struct Passenger {
string name; // "John Smith"
MealType mealPref; // LOW_FAT
bool isFreqFlyer; // true
string freqFlyerNo; // "293145"
};
This is C-style structure. In general, structures and classes in C++ provide a much wider range of capabilities than what is possible in C-style structures (member functions, access control, etc).Passenger pass = { "John Smith", LOW_FAT, true, "293145" };
pass.name = "Pocahontas"; // change name
pass.mealPref = VEGETARIAN; // change meal preference
This new passenger object continuous to exist in the free store until it is explicitly deleted.Passenger *p;
//...
p = new Passenger; // p points the new Passenger
p->name = "Pocahontas";
p->mealPref = VEGETARIAN; // change meal preference
p->isFreqFlyer = false;
p->freqFlyerNo = "NONE";
//...
delete p;
Having inaccessible objects in dynamic memory is called memory leak.char* buffer = new char[500];
//...
delete buffer; // ERROR: delete only the fist element buffer[0]
char* buffer = new char[500];
//...
delete [] buffer; // delete all elements
It is often useful to associate a name with a type:const double PI = 3.14159265;
const int CUT_OFF[] = {90, 80, 70, 60};
const int N_DAYS = 7;
const int N_HOURS = 24*N_DAYS;
int counter[N_HOURS];
typedef char* BufferPtr; // type BufferPtr is a pointer to char
typedef double Coordinate; // type Coordinate is a double
//...
BufferPtr p; // p is a pointer to a char
Coordinate x, y; // x and y are of type double
const int cat = 1; // global cat
int main()
{ const int cat = 2; // local cat (to main)
cout << cat; // outputs 2
return 0;
}
int dog = cat; // dog = 1 (from global cat)
We can access an object x in namespace group, using the notation group::x, which is called fully qualified name.namespace myglobals {
int cat;
string dog = "bow wow";
}
int d = myglobals::cat;
using std::cout;or
using myglobals::cat;
using namespace std;
using namespace myglobals;
class_name.member | class/structure member selection |
dot operator |
pointer->member |
class/structure member selection | arrow operator |
array[exp] |
array subscripting |
index operator |
exp + exp |
addition |
exp - exp | subtraction |
exp * exp | multiplication |
exp / exp | division |
exp % exp | modulo (remainder) |
var ++ |
post increment |
var -- |
post decrement |
++ var | pre increment |
-- var | pre decrement |
int a[] = { 0, 1, 2, 3 };
int i = 2;
int j = i++; // j = 2 and then i = 3
int k = --i; // i = 2 and k = 2
cout << a[k++]; // a[2] (=2) is output; now k = 3
exp < exp |
less than |
exp > exp | greater than |
exp <= exp | less than or equal to |
exp >= exp | greater than or equal to |
exp == exp | equal to |
exp != exp | not equal to |
! exp |
logical not |
exp && exp | logical and |
exp || exp | logical or |
exp != exp | not equal to |
~ exp |
bitwise complement |
exp & exp | bitwise and |
exp ^ exp | bitwise exclusive-or |
exp | exp | bitwise or |
exp << exp | shift left |
exp >> exp | shift right |
int i = 10;
int j = 5;
int k = 1;
i -= 4; // i = i - 4; result 6
j *= -2; // j = j * (-2); result -10
k <<= 1; // k = k << 1; result 2
class_name :: member |
class scope resolution |
namespace_name :: member | namespace scope resolution |
exp ? exp : exp |
conditional expression |
stream >> var |
input stream |
stream << exp |
output stream |
Operator | Description | Associativity |
:: | scope | Left |
() [ ] -> . sizeof | Left | |
++ -- | increment, decrement | Right |
~ | bitwise complement |
|
! (not) |
unary NOT | |
& * | reference and dereference |
|
..._cast, (type) |
type casting | |
+ - | unary + and - |
|
* / % | arithmetic operators | Left |
+ - | addition, subtraction | Left |
<< >> | bitwise shifts |
Left |
< <= > >= | relational operators | Left |
== != | relational operators | Left |
& |
bitwise and |
Left |
^ | bitwise exclusive-or | Left |
| | bitwise or |
Left |
&& (and) |
logical operator and |
Left |
|| (or) |
logical operator or |
Left |
?: | conditional operator |
Left |
= += -= *= /= %= >>= <<= &= ^= |= |
assignment operators |
Right |
, | comma, separator | Left |
int a = 10, b, c, d;
// right associativity
d = c = b = a; // is equivalent to d = (c = (b = a));
// left associativity
d - c + b - a; // is equivalent to ((d - c) + b) - a;
d > c && -b <= a // is equivalent to (d>c) && ((-b)<=a)
int cat = 14;
double dog = (double)cat;
double pig = double(cat);
int cat = 14;
double dog = static_cast<double>(cat); // dog = 14.0
double lion = 155.99;
int pig = static_cast<int>(lion); // pig = 155
Operator Overloadingvoid print(int x)
{ cout << x; }
void print(const Passenger &pass)
{ cout << pass.name << " " << pass.mealPref;
if (pass.isFreqFlyer) cout << pass.freqFlyerNo;
}
bool operator==(const Passenger &x, const Passenger &y)
{ return x.name == y.name &&
x.mealPref == y.mealPref &&
x.isFreqFlyer == y.isFreqFlyer &&
x.freqFlyerNo == y.freqFlyerNo;
}
ostream& operator<<(ostream &out, const Passenger &pass)
{ out << pass.name << " " << pass.mealPref;
if (pass.isFreqFlyer) out << pass.freqFlyerNo;
return out;
}
//...
Passenger pass1 = // details omitted
Passenger pass2 = // details omitted
cout << pass1 << pass2 << endl;
enum MealType { NO_PREF, REGULAR, LOW_FAT, VEGETARIAN };
class Passenger {
private:
string name; // "John Smith"
MealType mealPref; // LOW_FAT
bool isFreqFlyer; // true
string freqFlyerNo; // "293145"
public:
Passenger(); // default constructor
bool isFreqFlyer() const; // accessor function
void makeFreqFlyer(const string &newFreqFlyerNo);
// update (mutator) function
};
// ...
bool Passenger::isFreqFlyer() const
{ return isFreqFlyer; }
void Passenger::makeFreqFlyer(const string &newFreqFlyerNo)
{ isFreqFlyer = true;
freqFlyerNo = newFreqFlyerNo;
}
//...
Passenger pass;
//...
if (!pass.isFreqFlyer()) // OK
pass.makeFreqFlyer("999999"); // OK
pass.name = "Joe Blow"; // ERROR: private member
enum MealType { NO_PREF, REGULAR, LOW_FAT, VEGETARIAN };
class Passenger {
private:
string name; // "John Smith"
MealType mealPref; // LOW_FAT
bool isFreqFlyer; // true
string freqFlyerNo; // "293145"
public:
Passenger();
bool isFreqFlyer() const
{ return isFreqFlyer; }
void makeFreqFlyer(const string &newFreqFlyerNo)
{ isFreqFlyer = true;
freqFlyerNo = newFreqFlyerNo;
}
};
class Matrix; // Matrix definition comes later
class Vector { // a 3-element vector
private:
double coord[3];
public:
// ...
friend class Matrix; // allow Matrix access to coord
};
class Matrix { // a 3x3 array
private:
double a[3][3];
public:
// ...
Vector multiplyBy(const Vector& v) { // multiply (a * v)
Vector w(0, 0, 0);
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
w.coord[i] += a[i][j] * v.coord[j]; // access private data
return w;
}
};
class Complex {
private:
class Node {
// ...
};
//...
};
stack |
Container with last-in,
first-out access |
queue |
Container with first-in, first-out access |
deque |
Double-ended queue |
vector |
Resizeable array |
list |
Doubly linked list |
priority_queue |
Queue ordered by value |
set,
multiset |
Set |
map,
multimap |
Associative array (dictionary) |
vector.cppvector<int> scores(100);
vector<char> buffer(500);
vector<Passenger> passList(20);
vector<int> newScores = scores;
Member Functionsclass Person { // base class
private:
string name; // name
string ssn; // social security number
public:
//...
void print(); // print data
string getName(); // retrieve name
};
class Student : public Person { // derived class
private:
string major; // major subject
int gradYear; // graduate year
public:
//...
void print(); // print data
void changeMajor(string newMajor); // change major
};
Person person(...); // define a person
Student student(...); // define a student
cout << student.getName();// invokes Person::getName()
person.print(); // invokes Person::print();
student.print(); // invokes Student::print();
person.changeMajor("Math"); // ERROR!
student.changeMajor("Math"); // OK
void Person::print() // definition of Person print
{ cout << name << " " << ssn; }
void Student::print() // definition of Student print
{ Person::print(); // first print Person data
cout << major << gradYear;
}
class Base {
private:
int priv;
protected:
int prot;
public:
int publ;
};
class Derived: public Base {
void someMemberFunction()
{ cout << priv; // ERROR: private member
cout << prot; // OK
cout << publ; // OK
}
};
class Unrelated {
Base X;
void anotherMemberFunction()
{ cout << X.priv; // ERROR: private member
cout << X.prot; // ERROR: protected member
cout << X.publ // OK
}
};
Static BindingPerson::Person(const string &nm, const string &ss)
: name(nm), ssn(ss) {} // initializer list
Student::Student(const string &nm, const string &ss,
const string &maj, int year)
: Person(nm, ss), // initialize Person data members
major(maj), // initialize member
gradYear(year) {} // initialize gradYear
Person::~Person() // Person destructor
{ ... }
Student::~Student() // Student destructor
{ ... }
Student* s = new Student(...);
//...
delete s; // calls ~Student() then ~Person()
Person* pp[100];
pp[0] = new Person(...);
pp[1] = new Student(...);
cout << pp[1]->getName(); // OK
pp[0]->print(); // calls Person::print()
pp[1]->print(); // calls Person::print()
pp[1]->changeMajor(...); // ERROR!
class Person { // base class
virtual void print(); // print data
//...
};
class Student : public Person { // derived class
virtual void print(); // print data
//...
};
Person* pp[100];
pp[0] = new Person(...);
pp[1] = new Student(...);
pp[0]->print(); // calls Person::print()
pp[1]->print(); // calls Student::print()
pp[1]->changeMajor(...); // OK
delete [] pp;
Minimum of doubles:int min(int a, int b)
{ return (a < b ? a : b); }
Generic function for an arbitrary type T, called function template:double min(double a, double b)
{ return (a < b ? a : b); }
We can invoke our templated function to compute the minimum of objects of many different types. We could use any type, provided that the less than operator (<) is defined for this type. The compiler looks at the argument types, and determine which form of the function to instantiate:template<typename T> // parameter list
T min(T a, T b) // returns the minimum of a and b
{ return (a < b ? a : b); }
cout << min(3, 4); // invokes min<int>(3,4)
cout << min(6.9, 3.5); // invokes min<double>(6.9, 3.5)
cout << min('t', 'g'); // invokes min<char>('t', 'g')
template <typename Object>
class BasicVector {
Object* a; // array storing an element
int capacity; // length of array a
public:
BasicVector(int cap = 10) // constructor
{ capacity = cap;
a = new Object[capacity];// allocate array storage
}
Object& elemAtRank(int r) // access element at index r
{ return a[r]; }
// ...
};
BasicVector<int> iv(5); // vector of 5 integers
BasicVector<double> dv(20); // vector of 20 doubles
BasicVector<string> sv(10); // vector of 10 strings
//...
iv.elemAtRank(3) = 8; // iv[3] = 8;
dv.elemAtRank(14) = 2.5; // dv[14] = 2.5
sv.elemAtRank(7) = "hello"; // sv[7] = "hello"
class MathException { // generic math exception
private:
string errMsg; // error message
public:
MathException(const string& err) { errMsg = err; }
};
class ZeroDivisionException : public MathException {
public:
ZeroDivisionException(const string& err)
: MathException(err) {}
};
class NegativeRootException : public MathException {
public:
NegativeRootException(const string& err)
: MathException(err) {}
};
try {
// ...
if (divisor == 0) throw ZeroDivisionException("Division by zero");
//...
}
catch (ZeroDivisionException& zde)
{ // handle division by zero
}
catch (MathException& me)
{ // handle any math exception other than division by zero
}
void calculator() throw(ZeroDivisionException, NegativeRootException)
{
//...
}
void funct1(); // can throw any exception
void funct2() throw(); // can throw no exception
class RuntimeException { // generic run-time exception
private:
string errorMsg;
public:
RuntimeException(const string& err) { errorMsg = err; }
string getMessage() const { return errorMsg; }
};
inline std::ostream& operator<<(std::ostream& out, const RuntimeException& e)
{ return out << e.getMessage(); }