Part 0: Setting up C++
Part 1: Hello world! Your first steps with C++
Part 2: Arrays, files and functions
Part 3: Pointers and classes
OS: Linux / Mac OS
We are going to have two windows open at the same time:
A text editor (vi, emacs, vscode etc).
The command line or terminal, where a C++ compiler has already been installed and is working.
Create a new directory (folder) in your working directory called cpp
by typing mkdir cpp
.
Change directory to your new cpp
directory by typing cd cpp
.
For cin
cout
endl
stuff, we need the <iostream>
library. Libraries are like toolboxes.
xxxxxxxxxx
//**
using namespace std; //**
int main()
{
cout << "Hello world!" << endl;
return 0;
}
return 0
in the main function means the program executed successfully, while return any non-zero value
in the main function means the program does not execute successfully.
Save as helloworld.cpp
.
Compile by going to the command line and typing.
xxxxxxxxxx
g++ helloworld.cpp -o hello
Then run the program.
xxxxxxxxxx
./hello
xxxxxxxxxx
using namespace std;
int main()
{
double x;
double y;
x = 3.141;
y = 1.618;
cout << "The value of x is " << x << " and the value of y is " << y << endl;
return 0;
}
auto
declaration type since C++ 2011, the type is deduced from the initializer.
xxxxxxxxxx
auto j = 16; //j is integer
auto j = 2.3; //j is double
auto j = true; //j is bool
Compile and run.
New file! height.cpp
. Note that we're going to use strings here, which need the <string>
library.
xxxxxxxxxx
using namespace std;
int main()
{
string name;
double height;
cout << "What is your name?" << endl;
cin >> name;
cout << "What is your height?" << endl;
cin >> height;
cout << name << " is " << height << " metres tall." << endl;
return 0;
}
Compile and run.
New file! calculator.cpp
xxxxxxxxxx
using namespace std;
int main()
{
double x;
cout << "Enter a number" << endl;
cin >> x;
cout << "That number squared is " << pow(x, 2) << endl;
cout << "The square root of that number is " << sqrt(x) << endl;
return 0;
}
Compile and run.
New file! bartender.cpp
xxxxxxxxxx
using namespace std;
int main()
{
int age;
cout << "Welcome to the pub." << endl;
cout << "What is your age?" << endl;
cin >> age;
if(age > 18){
cout << "Have a pint!" << endl;
} else if(age == 18){
cout << "Show me your ID and then have a pint!" << endl;
} else {
cout << "I'm calling the police." << endl;
}
return 0;
}
Compile and run.
New file! square_numbers.cpp
xxxxxxxxxx
using namespace std;
int main()
{
int n = 10;
for(int i = 0; i < n; i++){
cout << pow(i, 2) << endl;
}
return 0;
}
Compile and run.
Change the file: let's comment out the for loop above and instead write it as a while loop.
xxxxxxxxxx
int i=3; // We can define and initialise a variable at the same time.
while(i < n){
cout << pow(i, 3) << endl;
i++;
}
To save and read files, we need to include the <fstream>
library.
New file! save_to_file.cpp
xxxxxxxxxx
using namespace std;
int main()
{
ofstream myfile; //for output
myfile.open("greeting.txt");
myfile << "header line 1" << endl;
myfile << "header line 2" << endl;
myfile << "header line 3" << endl;
int datapoint = 95;
myfile << datapoint << endl;
for (int i = 0; i < datapoint; ++i) {
myfile << i << " " << 0.01+0.2*i+0.03*i*i << endl;
}
myfile.close();
return 0;
}
Your turn:
Create a new file, save_to_file2.cpp
, where you print the first 10 squares to a text file called square_numbers.txt
.
Run your program again. What can you say about how it writes to the text file?
Replace myfile.open ("square_numbers.txt");
with myfile.open ("square_numbers.txt", ios_base::app);
to make C++ append to the end of a text file, rather than overwrite.
New file! read_from_file.cpp
xxxxxxxxxx
using namespace std;
int main()
{
string line;
ifstream myfile; //for input
myfile.open("greeting.txt");
for(int i=0; i<3; i++) {
getline(myfile, line);
cout << line << endl;
}
int datapoint;
myfile >> datapoint;
cout << "point: " << datapoint << endl;
int x[1000];
double y[1000];
int count = 0;
while(!myfile.eof()) {
myfile >> x[count] >> y[count];
if(myfile.eof()) break;//避免最后一个重复读取
cout << count << " " << x[count] << " " << y[count] << endl;
count++;
}
if(datapoint != count)
cout << "data miss" << endl;
else
cout << "read all data." << endl;
myfile.close();
return 0;
}
Edit square_numbers.cpp
xxxxxxxxxx
using namespace std;
int main()
{
int n = 10;
int square_numbers[10];
for(int i = 0; i < n; i++){
square_numbers[i] = pow(i, 2);
}
for(int i = 0; i < n; i++){
cout << square_numbers[i] << endl;
}
return 0;
}
Note you can't cout
an array
We can also define arrays like this:
xxxxxxxxxx
int main()
{
int n = 10;
int square_numbers[10];
int favourite_numbers[10] = {3, 1, -4, 1}; // Note we haven't defined them all.;
for(int i = 0; i < n; i++){
square_numbers[i] = pow(i, 2);
}
for(int i = 0; i < n; i++){
cout << square_numbers[i] << endl;
}
for(int i = 0; i < n; i++){
cout << favourite_numbers[i] << endl;
}
return 0;
}
You can only use curly brackets like this at initialisation time.
We can also declare:
xxxxxxxxxx
int favourite_numbers[] = {3, 1, -4, 1};
Multidimensional arrays work too
xxxxxxxxxx
int magic_square[3][3] = {{4, 9, 2},{3, 5, 7},{8, 1, 6}};
Writing functions allows us to do more complicated things.
New file! learning_functions.cpp
xxxxxxxxxx
using namespace std;
int sign_function(int n)
{
int sign;
if(n > 0){
sign = 1;
} else if(n == 0){
sign = 0;
} else {
sign = -1;
}
return sign;
}
int main()
{
int n;
n = 3;
cout << sign_function(n) << endl;
return 0;
}
Global and local variables.
Note: order is important. What happens if you define sign_function
after main
?
There is a way to define functions with main
first: it's called 'forward declaration'.
In general, this is better because it allows more flexible code.
xxxxxxxxxx
using namespace std;
int sign_function(int n);
int main()
{
int n;
n = 3;
cout << sign_function(n) << endl;
return 0;
}
int sign_function(int n)
{
int sign;
if(n > 0){
sign = 1;
} else if(n == 0){
sign = 0;
} else {
sign = -1;
}
return sign;
}
Compile and run.
New file! pointers.cpp
:
xxxxxxxxxx
using namespace std;
int main()
{
int x = 10;
cout << "Value of x is " << x << endl;
cout << "Address of x is " << &x << endl;
return 0;
}
The &
sign indicates an address in memory.
A pointer is a variable whose value is the address of another variable, and is notated with a *
xxxxxxxxxx
using namespace std;
int main()
{
int x = 10;
int *p; // allocate p of type ‘pointer to integer’
p = &x; // assign ‘memory address of x’ to pointer px
cout << "Value of x is " << x << endl;
cout << "Address stored in p is " << p << endl;
cout << "Value of *p variable is " << *p << endl;
return 0;
}
See what happens to the value of *p
if we change the value of x
.
Historically pointers were used instead of arrays.
New file! pointer_array.cpp
xxxxxxxxxx
using namespace std;
int main ()
{
int primes[3] = {2, 3, 5};
int *p;
p = primes; // Set the pointer to point at the start of the array
for (int i = 0; i < 3; i++) {
cout << "Address of primes[" << i << "] is " << p << endl;
cout << "Value of primes[" << i << "] is " << *p << endl;
p++;
}
return 0;
}
See what *(primes + 2)
outputs.
If you want to access command line arguments you can declare main() as follows
New file! main_arg.cpp
xxxxxxxxxx
using namespace std;
int main(int argc, char *argv[])
{
cout << "argc == " << argc << '\n';
for(int i = 0; i < argc; i++) {
cout << "argv[" << i << "] == " << argv[i] << '\n';
}
return 0;
}
compile and run
`g++ main_arg.cpp -o main_arg``
`./main_arg table_in.dat table_out.dat
outputs:
xxxxxxxxxx
argc == 3
argv[0] == ./main_arg
argv[1] == table_in.dat
argv[2] == table_out.dat
Classes are one of the main things that separate C++ from C. Classes are ways for us to set up objects that have properties and functions which are particular to that type of object. A class is something like a userdefined data type.
New file rectangles.cpp
xxxxxxxxxx
using namespace std;
class Rectangle
{
public:
double width; // Width of rectangle
double height; // Height of rectangle
};
int main()
{
Rectangle Rec1; // Declare Rec1 of type Rectangle
// Rec1 specification
Rec1.height = 5.0;
Rec1.width = 6.0;
double area;
// area of Rec1
area = Rec1.height * Rec1.width;
cout << "Area of Rec1: " << area << endl;
return 0;
}
Add another rectangle, Rec2
You should get something like:
xxxxxxxxxx
using namespace std;
class Rectangle
{
public:
double width; // Width of rectangle
double height; // Height of rectangle
};
int main()
{
Rectangle Rec1; // Declare Rec1 of type Rectangle
Rectangle Rec2; // Declare Rec2 of type Rectangle
// Rec1 specification
Rec1.height = 5.0;
Rec1.width = 6.0;
// Rec2 specification
Rec2.height = 10.0;
Rec2.width = 12.0;
double area;
// area of Rec1
area = Rec1.height * Rec1.width;
cout << "Area of Rec1: " << area << endl;
// area of Rec2
area = Rec2.height * Rec2.width;
cout << "Area of Rec2: " << area << endl;
return 0;
}
Let's make area a 'member function' of the class (so we can call Rec1.area()
, for example)
xxxxxxxxxx
class Rectangle
{
public:
double width; // Length of rectangle
double height; // Height of rectangle
double area() {return width * height;} //member function.
};
Replace area = Rec1.height * Rec1.width;
with area = Rec1.area();
and see that it works.
Add a member function perimeter
which returns the length of the perimeter.
We're going to look at another way of creating a member function. This is entirely equivalent.
Just like how we forward declared functions earlier, we can forward declare them here.
xxxxxxxxxx
class Rectangle
{
public:
double width; // Length of rectangle
double height; // Height of rectangle
double area() {return width * height;}
void set_dimensions (double x, double y);
};
void Rectangle::set_dimensions (double x, double y)
{
width = x;
height = y;
}
Replace Rec1.height = 5.0;
and Rec1.width = 6.0;
with a call to Rec1.set_dimensions
If you want to use Rectangle
in lots of files, it's annoying to define it every time.
In actual usage, the definition of class rectangle
would typically go in the file rectangle.h
and the definitions of the member functions, like rectangle::set_dimensions
, would go in the file rectangle.cc
.
Put the class declaration and set_dimensions
definition in a header file, rectangle.h
, and call it from rectangles.cpp
rectangle.h
xxxxxxxxxx
class Rectangle
{
public:
double width; // Length of rectangle
double height; // Height of rectangle
double area() {return width*height;}
void set_dimensions (double x, double y);
};
rectangle.cc
xxxxxxxxxx
void Rectangle::set_dimensions (double x, double y)
{
width = x;
height = y;
}
rectangles.cpp
x
using namespace std;
int main()
{
Rectangle Rec1,Rec2; // Declare Rec1 of type Rectangle
// Rec1 specification
Rec1.width = 5.0;
Rec1.height = 6.0;
// Rec2
Rec2.set_dimensions(10.0, 12.0);
// area of Rec1
cout << "Area of Rec1: " << Rec1.area() << endl;
// area of Rec2
cout << "Area of Rec2: " << Rec2.area() << endl;
return 0;
}
Compile and run
g++ rectangles.cpp rectangle.cc -o rectangles
./rectangles
Modified from https://github.com/Pecnut/course-intro-to-cpp