If you're coming from C, you can use printf() in C++ too. But the preferred way is cout:
cout << "hello world!" << endl;
Reading to string variables:
Use getline. The basic format is:
getline(cin,[name of string variable to read to]);
Example:
string name;
getline(cin,name);
Reading to any other variable:
Use cin.getline(). The basic format is:
cin.getline( [name of variable to read to] , [# of chars to read] );
Example:
char user[32];
cin.getline(user,32);
cout << "You entered: " << user << endl;
For our purposes, 1 byte = 8 bits.
Integer Types
short: at least 16 bits wide (-32,768 to +32,767)
int: at least as big as a short. Usually 32 bits on most modern computers (Windows 98 and above, Mac OSX)
long: at least 32 bits wide or at least as big as an int, whichever is bigger (-2147483648 to +2147483647)
Floating-Point Types
float: at least 32 bits.
double: at least 48 bits or at least as big as a float, whichever is bigger. Usually 64 bits.
long double: at least as big as a double. Usually 80, 96 or 128 bits.
Look at the cfloat header file for the exact values on your system.
Finding out the sizes for your system:
Use sizeof():
cout << "int is " << sizeof(int) << " bytes" << endl;
The climits file also defines some useful constants:
#include
cout << "int max value " << INT_MAX << endl;
cout << "int min value " << INT_MIN << endl;
cout << "Bits per byte " << CHAR_BIT << endl;
Also available:
UINT_MAX: Max unsigned int value
SHRT_MAX: Max short value
SHRT_MIN: Min short value
USHRT_MAX: Max unsigned short value
LONG_MAX: Max long value
LONG_MIN: Min long value
ULONG_MAX: Max unsigned long value
CHAR_MAX: Max char value
CHAR_MIN: Min char value
SCHAR_MAX: Max signed char value
SCHAR_MIN: Min signed char value
UCHAR_MAX: Max unsigned char value
Use the const keyword:
const int FOOT = 12;
aka type casting. There are two ways to do it:
int num = 65;
cout << char(num); # prints "A"
cout << (char)num; # another way to do it.
C-style string (i.e. char arrays) work in C++ too, but the string class is more convenient:
string name;
name = "Jason Fox";
cout << name << endl;
name = "this is something much longer";
cout << "THe fourth letter is:" << name[3] << endl;
As you can see, C++ style strings can be used just like C-style strings. The key difference is you don't have to give it a fixed character length. Much more convenient. You also don't need to use strcpy or strcat. These are all legal operations:
string one = "one";
string two = "two";
one = two; # copying one string to another
one += two; # concatenation is easy
str1.size(); // string created with 'string'
strlen(str2); // string created with a char array
You can still use malloc() with C++, but there's a better way: the 'new' keyword. Example:
int *myInt = new int; // memory allocated for int.
Of course, you only do this for getting memory dynamically at runtime. The way you get memory for compile time is still the same:
int myInt;
If you allocated memory with 'new', use the 'delete' keyword to delete it:
int *ps = new int;
// do something with new memory
delete ps;
This doesn't delete the pointer (obviously) but just the memory it points to.
An example with arrays:
int *ps = new int[10];
// do something with new memory
delete [] ps;
cout is an ostream object that you use to write to standard out. Similarly you can create your own ofstream object to write to a file:
ofstream file;
file.open("somefile.txt");
file << "write something" << endl;
file.close();
So after an ofstream object is associated with a file, you use it exactly like you use cout. You also need to include the fstream header file:
#include
cin is an istream object that you use to read from standard in. Similarly you can create your own ifstream object to read from a file:
ifstream file;
file.open("test.txt");
string line;
getline(file,line);
cout << line << endl;
file.close();
So after an ifstream object is associated with a file, you use it exactly like you use cin. You also need to include the fstream header file:
#include
Use the & operator:
int a = 10;
int & b = a;
a = 20;
cout << b << endl; // prints 20
You have to assign a value to a reference when you declare it. i.e. you can't do this:
int a = 10;
in & b;
b = a; // Nope
In functions:
Most often, references are used in parameters in functions. This allows you to pass by reference instead of passing by value:
int main(int argc, char * argv[])
{
int a = 4;
sq(a);
cout << a << endl; # prints 16
}
void sq(int &x)
{
x = x*x;
}
Default args in C++ work similarly to default args in Python (Maybe it would be more appropriate to say it the other way around).
You set the default arguments in the prototype of a function. For example, here's a function that squares a number. The default argument is a 2:
int sq(int x=2);
int main(int argc, char * argv[])
{
int b = sq();
cout << b << endl; // prints 4
}
int sq(int x)
{
return x * x;
}
Just create multiple functions with the same name but with different arguments. C++ will automatically choose the correct version of the function based on the arguments passed in. Example:
// two functions with the same name
int add(int a, int b);
int add(int a, int b, int c);
int main(int argc, char * argv[])
{
int b = add(4,4,4); // choose the second function
cout << b << endl;
}
int add(int a, int b)
{
return a + b;
}
int add(int a, int b, int c)
{
return a + b + c;
}
Function templates allow you to write more general code. For example, here's a function that swaps two values:
template
void Swap(Any &a, Any &b)
{
Any temp;
temp = a;
a = b;
b = temp;
}
C++ will automatically generate a function for any type you put in. For example:
int a = 10;
int b = 20;
Swap(a,b); // C++ automatically generates a Swap function of type Swap(int &a, int &b)
double a = 10;
double b = 20;
Swap(a,b); // C++ automatically generates a Swap function of type Swap(double &a, double &b)
So Swap will automatically generate a function for any type. Suppose you want it to behave differently for certain types. You can specify a explicit specialization. For example, suppose that along with the previous function I have this one as well:
template < > void Swap(double &a, double &b)
{
cout << "swappin' doubles!" << endl;
double temp;
temp = a;
a = b;
b = temp;
}
This one only applies to doubles, and when I try to swap two doubles, this is the function that will be used instead of the template function.
And of course I can specify a normal function too:
void Swap(int &a, int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
So if we put in ints, this is the function that will be used. The way C++ chooses functions is:
normal function > explicit specialized function > template function
#ifndef SOME_VAR
#define SOME_VAR
#include "someheader.h"
#endif
Automatic variables are those variables for which spaces is automatically allocated / deallocated as needed. The variables you use in a function are automatic variables — when the function is called, space is allocated for them on the stack. When the function returns, that space is freed again.
In contrast, global variables in your program are static variables; they are there for the entire duration of your program and space is allocated for them when space is allocated for your program. These don't come from the stack.
You can mark a variable as static by using the static keyword:
static int a;
You can mark a variable as automatic with the auto keyword:
auto int a;
Because you can use the 'auto' keyword only with variables who are already automatic by default, using it makes no difference. The only reason you would use it is to make it really clear that some variable is an automatic variable.
You can declare a namespace like so:
namespace Jack{
int a;
int b = 0;
string c;
}
Now here's how you would access a, b or c:
Jack::a = 30;
Jack::c = "hello there";
//etc
This means you can have multiple variables with the same name — just put them in different namespaces and there's no conflict. You could have this namespace in the same file:
namespace Jack{
int a = 10;
int b = 30;
string c = "hello";
}
And you can use the variables like so:
// two different variables
Jack::a = 1;
Jill::b = 2;
If you don't want to type the full name of a variable every time, you can use a using directive:
using Jack::a;
a = 20; //refers to Jack::a
Jack::b = 10; // this still needs the 'Jack::' in front
Or to make all names in a namespace available:
using namespace Jack;
a = 10; // Jack::a
b = 10; // Jack::b
Nested Namespaces
You can do the following:
namespace one
{
namespace two{
int fire;
}
}
// here's how you access it:
one::two::fire = 20;
In C++, inline functions are used instead of defines. Here's an example of an inline function:
inline int sq(int x) { return x * x; }
The rand() function generates a number between 0 and RAND_MAX. RAND_MAX can be as low as 2^15 - 1 on some computers. Here's how we would generate a random number between 0-9:
#include <cstdlib>
cout << rand() % 10 << endl;
#include
sqrt(100);
If one template parameter has a default argument, then all template parameters following it must also have default arguments.
// default parameter of int:
template<class T = int> class A;
To see how long you spend in each function, how many times each function gets called, etc, use the gprof tool. First, make sure you have it on your system by using:
which gprof
Then, compile your code using the -pg flag (This is not the same as the -p and -g flags together):
g++ test.cpp -pg -o test
Now run your code. You'll see a file in the same directory called gmon.out. Now you can use gprof to read the file by using:
gprof [application name] # for the full story
gprof -b [app name] # brief summary
gprof -A [app name] display annotated source code
It is particularly interesting to do this with the various g++ optimization flags and see how your code is being optimized. For example, writing a function fib and calling fib(10) produced:
176 calls to fib at the default level (which means some optimization was already happening).
88 calls to fib using -O.
60 calls to fib using -O3.
Use Boost::lexical_cast:
mystring = boost::lexical_cast(anIntVal);
Use fabs:
#include <cmath>
fabs(14.99-16.99);
Unfortunately, you can't use == because due to floating point errors, they might actually be 13.999999 instead of 14 or something. You need to do this instead:
#include <cmath>
const double EPSILON = .00001;
return fabs(a - b) < EPSILON;