Nuts and Bolts of C++ [1]
Nuts and Bolts of C++
Compiler -> Linker + Library -> Executable Machine Language Program
Library belongs to the operation system.
High-level Languages (HLL)
Recent Examples
-
Pascal
-
C
Current Examples
-
C++
-
Java
C++ program is portable to different machines.
Visual Studio
A Solution must contain at least one project.
A Project must contain at least one file.
In Visual Studio, each user task is referred to as a solution to a problem.
In Visual Studio, every project mainly contains:
- Executable code and debug information
- C++ source code
- Classes and objects
Command Prompt
Command Prompt – a traditional interface between the user and computer
some basic command:
cd – change directory
dir – directory
cin and cout
cin is the keyboard. cout is the display.
cin.get() only gets the first character.
enter also count as a character.
Preprocessor
#include <iostream>
- Instruct the compiler on how to complie the program
- Will not generate machine codes
- Start with a pound (#) symbol
Header Files
- Definitions of some terms in the program codes are recorded in some header files
- Can be shipped with the compiler or other resources
#include
tells the compiler where to find the header file and insert this file to that location of the program#include <iostream>
tells the compiler it should get the file iostream through the default path#include "myfile"
tells the comiler it should get the file myfile in the current path
Actual program (main function)
- Every C++ program must have the main() function
- It is the beginning point of every C++ program
Program codes
- The basic element of a program is a function
1 |
|
Namespaces
- std::cout and std::endl means that we are referring to the cout and endl of the std namespace
- Design to help programmers develop new software components without generating naming conflicts
Naming Conflict
- cout and endl are NOT C++ keywords, people can use these two names for any purpose.
- not necessarily referring to the standard output and newline character.
1 |
|
Common useful things
Character | What it means |
---|---|
\n |
new line |
\t |
Tab |
\b |
Backspace |
\" |
double quote |
\' |
Single quote |
\\ |
Backslash |
Comments
-
Improve readability
-
Will not affect the program
1
2//This is a comment.
/*This is a multline comment. */
Functions
it is a bad habit to do everything by a single function.
- When the function returns, the program goes back to where it left before.
- The function main() can call other functions to help completing a task.
Note: If you want to write a function and put it under main, you need function prototype.
Example1
1 |
|
Example2
1 |
|
Variables and Memory
- A variable is associated with a place (Location in the memory) to store information in a computer
- The name of a variable can be considered as a label of that piece of memory
- Computer change the content of memory when the program modify the value of variable
- Every data is reflected with type and value.
- One adress for one byte, i.e. 8 bits of memory.
Types of Variables
Type | Size | Values |
---|---|---|
bool | 1 byte | 1 or 0 |
unsigned short int | 2 bytes | 0 to 65,535 |
short int | 2 bytes | -32,768 to 32,767 |
unsigned long int | 4 bytes | 0 to 2^32-1 |
long int | 4 bytes | -2147483648 to 2147483647 |
unsigned int | 4 bytes | 0 to 2^32-1 |
int | 4 bytes | -2147483648 to 2147483647 |
char | 1 byte | 256 character values |
float | 4 bytes | (+/-) 1.2e-38 to (+/-)3.4e38 |
double | 8 bytes | (+/-) 2.2e-308 to (+/-) 1.8e308 |
What so special about 2147483648?
Declaring Variable
-
When we use a variable, we need to declare its type so that the computer can reserve suitable memory space for it.
-
Programmer do not need to know the adress.
-
The name of the variable is case sensitive. (int myVariable is not the same as int myvariable)
-
Declared uninitialized variable have a default value.
Maximum and Minimum
When the value goes beyond those limits, unexpected behavior may result.
1 |
|
Signed integers do NOT behave in the same way.
1 |
|
Characters
-
Char
1
2
3
4
5char c = 53, d = '5'; //They are the same
// c = 5, d = 5
char character = a;
character = a + 1; // a now become 'b' (refer to ascii table!!)- only consider the variable as an 8-bit ASCII character. ascii table
- ‘’ is for single character
Constants
The value of a constant will be fixed until the end of the program.
- Literal Constants - come with the language
- Symbolic Constants - we define a special name as a label to it
Defining Symbolic Constants (2 ways)
- Old way (#define is the command from preprocessor)
1 |
|
- Better way (keyword - const)
1 | const unsigned short int student = 87; |
Usage of Constants
- Help debugging the program - compiler automatically check if a constant is modified by the program
- Improve readability - give the value a meaningful name
- Easy modification - only need to change single line in the source program
If Statement
1 | if(condition) //remember the () follow the if |
sometimes you dont need {}. Only the statement follows the if statement will check the condition.
1 | if(condition) |
Enumerated Constants
Allow one to create a new type that contains a number of constants
If the following item is not declared a value, it will be the previous value + 1.
The first value will be 0.
1 | enum COLOR {RED, BLUE, GREEN, WHITE, BLACK}; |
1 | enum COLOR2 {RED = 100, BLUE, GREEN = 500, WHITE, BLACK = 700}; |
When to use it?
Look at this example:
1 |
|
After using enumerated constants:
1 |
|
A Typical Program
Statements
1 | x = a + b; //an simple statement |
-
A C++ program comprises a number of functions
-
A function comprises a number of statements
A statement must end with a semicolon ;
spaces in statement nearly carry no information.
Expressions
1 | 3.2; //returns the value 3.2 |
- An expression reutrns a value.
Operators
-
An expression often comprises one of more operators
-
Assignment operator ‘=’ assigns a value to a variable
Operators Meaning + Add - Subtract * Multiply / Divide % Modulus
1 | int a = 3, b = 4, x; |
Integer and Floating Point Divisons
1 |
|
Short Hand of Expressions
1 | //Add |
++ variable vs variable ++
1 | int c = 5; |
1 | int c = 5; |
Precedence and Parentheses
- Performed from left to right
- first multi/div then add/subtract
- Parentheses can be nested as in normal arithmetic
Relational Operators
Operators | Meaning |
---|---|
== | Equals |
!= | Not Equals |
> | Greater than |
>= | Greater than or equals |
< | Less than |
<= | Less than or equals |
Logical Operators
-
Logical operators evaluate expressions of bool values
-
Each logical operation returns a bool result (true or false)
Operators | Meaning | Examples |
---|---|---|
&& | AND | condition1 && condition2 |
|| | OR | condition1 || condition2 |
! | NOT | !condition1 |
Program Flow Control
Control of Program Flow
- if… else
- switch… case … break
An example of if statement
1 |
|
An example of Switch statement
1 |
|
Switch statement can be implemented by the If statement but with more complicated structure. However, Switch can only be applied to data value tests.
Looping
-
Many programming problems are solved by repeatedly acting on the same variables
-
The method for achieving repeated execution is by looping
C++ offers many approaches to realise looping
- if … goto <-- Old way, abandoned by the public
- while loop <-- Use when testing parameters are complicated
- do-while loop <-- Use when the repeated part is expected to be executed at least once
- for loop <-- Use when the testing parameters are simple
While loop
1 |
|
while loops do the looping until the testing condition fails.
Do … While loop
1 |
|
while loops do the test first and then the loop.
Sometimes we would like to have the loop to be done at least once. In this case, do … while can be used
For loop
1 |
|
It can be done in a single line by a for loop. Tricky but convenient to use.
For loop also support Multiple/Null initialization and increments, or even empty for loop.
Multiple initialization and increments
1 |
|
Null initialization and increments
1 |
|
Empty For Loop
1 |
|
Continue and break
The keywords continue and break change the program flow during looping
Use with caution as it makes the program hard to understand owing to the sudden change of direction
1 |
|
Rewrite Looping program into other looping program
Look at this example. This is a nested for loops. Take time to get familiarise with it.
1 |
|
Now I change it into nested do while loop. Do…while program also do the same but it is more complicated.
1 |
|
Functions
Why do we need functions?
- Functions help us shorten our program by re-using the program codes.
- The same program will be much longer without calling functions
- Can be even longer if the same operation is done in other parts of the program.
- Functions make our program much easier to read
Declaring Functions
Function Prototype
unsigned short int FindArea(int, int);
Return type – function name – type of input parameters
1 |
|
Function Prototypes in Header file
Advantage: if a particular set of function prototypes is often used in different programs, we need not declare them line by line every time they are needed.
1 | //sourceFile.cpp |
Add a header.
1 | //myHeader.h |
Variables of Functions
there are 3 types of variables that a function may make use of:
Passed parameters and return parameter
- The links between the called function and the calling function
Local variable
- Visible only within a function, For temporary local storage
- A function can define local variables for temporary use.
- Local variables are only visible within the function defining them
- If both main() used the same name of global variable and local variable, Local variable has a higher priority.
Global variable
Global variable
- Visible to ALL functions in the program, An old and dangerous way to communicate between functions
- Must be carefully used
- Make your program difficult to debug
Variable Stored in Data Memory.
Paramater Passing - Passed by Value
- only a copy of the parameter value is passed to the called function
- what the called function does to the passed parameters has nothing to do with the original one, since they are just two variables (and occupying different memory, even when their names are the same)
Scope of Variables
Variables declared within a pair of braces are visible only to the statements in that braces after the variable is declared.
1 |
|
Default Parameters
- Calling function should pass the same number of parameter values as those defined in the prototype of the called function
1 | long myFunction(int); //function prototype |
- One exception is if the function prototype’s parameter has a default value
1 | long myFunction(int x = 50); //default value |
If the calling function does not provide a parameter value, 50 will be automatically used.
Look at this example.
Once a default value is given, the parameters that follow must have default values.
1 |
|
Overloading Functions
C++ allows overloading of function, i.e. create more than one function with the same name
1 | int myFunction (int, int); |
When a function calls myFunction(), the compiler checks the number and type of the passed parameters to determine which function should be called.
Look at this example:
1 |
|
Overloading example:
1 |
|
Writing a Good Program
Debugging a big program is exponentially more difficult than a small program.
- If a big program is to be developed, always try to break it down to many small programs (functions) and debug them independently. Divide and Conquer.
- Usually main() is only used to indicate the program flow. The actual task is done by the functions called by main(). By looking at the sequence of functions called by main(), people basically understand what is going on in a program.
- main() gives the skeleton of a program.
Improve the Readability of Programs
In practice, the time a programmer spends in documentation is more than writing the program.
- A program is seldom developed by a single person, cooperations are needed between programmers or even teams of programmers
- Besides, a program developed by a team of programmers often needs to be maintained by another team
It is essential that a program is properly documented to help team work.
Documenting a Program - readme (for user)
I Personally recommend markdown file (readme.md).
Not only it is often used it github, it is also very convinent to use.
I recommend using Typora to edit markdown files.
After developing a program, a readme file is often prepared in practice to indicate the following:
- Background information of the program (e.g. objectives, version no., development date, developer name)
- How to use the program (e.g. command line options)
- Additional resource required (e.g. hardware, driver, etc.)
- Bugs fixed as compared to previous version(s)
- Possible conflict with other programs
Within a program - comments (for developer)
- Commenting a program is the responsibility of every programmer
- Need meaningful comments (explain something people will have difficulty to understand)
Developing a program step-by-step
Step 0 – Prepare a flowchart
- To better visualize the problem, we may develop a flowchart for it
Step 1 – construct the skeleton
- What will be in the main function?
Step 2 – Add stubs (i.e. just for testing)
- stubs is a function that assure the program can successfully build
- We need to ensure the skeleton is correct before we proceed to implement the functions – add stubs
Step 3 – Implement functions
- If the skeleton has been proved to be correct, start to implement functions
- It is desirable to further break a big function into smaller functions
Step 4 – Implement the sub-functions
- It is desirable to have each function contained at most 20 lines of codes.
Debugging a Program
It is often NOT the case that a program can run correctly once it is developed.
Therefore, Debugging is often a necessary procedure.
Debugging can be divided into the following two stages:
Compile-time debugging (relatively easy)
- Compile-time errors can often be spotted out by the compiler
- The compiler can detect the approximate error location, but cannot be exact
- Also, the error messages generated are sometimes irrelevant
- Correct the errors owing to incorrect use of language syntax or unresolved references
- When a series of error messages are found, always try to debug them starting from the first one
- Once the first one is corrected, the rest may be solved as well.
Run-time debugging (often far more difficult)
- Comparing with compile-time errors, runtime errors are more difficult to locate and correct
- Run-time errors are often caused by wrong programming logic or improper use of resources
- Run-time errors may sometimes lead to incorrect results or even system failure
- Even worst, some run-time errors give no observable problem but gradually damage the system or the database.
- Correct the errors owing to incorrect program logic or resource usage
How to Avoid Run-time Errors?
C++ has many standard features to allow possible run-time errors be detected during compile-time
Try your very best to enable the compiler to detect the errors for you (that is, to convert run-time errors to compile-time errors whenever possible).
A structured way in program development can help avoid run-time errors.
Never develop your program in one step. Always ensure the skeleton is correct before going forward.
How to Debug Run-time Errors?
The problem of run-time errors can be observed only at run-time. One has to run the program in order to debug run-time errors
To debug run-time errors, the first thing that has to be done is to locate the errors
Achieved by the divide and conquer approach: The simplest way is to set some check-points in the program and to see how many checkpoints the program can correctly get through.
Run-time Debugger of Visual Studio
In some IDEs, there is a debug mode that allows you to set a breakpoint and check the variables.
To help in debugging more complicated run-time errors, Visual Studio has provided a run-time debugger:
- Allow line-by-line tracing of program code
- Allow arbitrary breakpoint in a program
- Allow examination of the status of all resources at the breakpoints, such as what data present in memory, data value of variables
- Allow monitoring of a particular resource of interest
Button | Usage |
---|---|
Breakpoint | A line number of interest in your program. When the debugger is running it halts execution of the program at this line. |
Call stack | A list of functions in the debugger that explains how the program got to where it currently is. Think of this as a live stack trace, without the exception. |
Continue | An action to take in the debugger that will continue execution until the next breakpoint is reached or the program exits. |
Step over | An action to take in the debugger that will step over a given line. If the line contains a function the function will be executed and the result returned without debugging each line. |
Step into | An action to take in the debugger. If the line does not contain a function it behaves the same as “step over” but if it does the debugger will enter the called function and continue line-by-line debugging there. |
Step out | An action to take in the debugger that returns to the line where the current function was called. |
Basically:
- Click on the lines of code where you would like to set
Right-click → Breakpoint → Insert Breakpoint
- Build it successfully. Start the debugger by clicking Debug → Start Debugging
Look at the Status window: Give the value of all related variables. Can also particularly watch the result of an expression by typing it in.
-
Step Into: Like Step Over, but if the current statement is a function calling, go into the called function to debug
-
Step Out: Return to the calling function
-
Step Over: Execute just the current line
Check View → Toolbars → Debug if you cannot see the debug toolbar.
- Step over the code
On stepping over each line of code, the current values of the variables are shown
- Find the error and stop Debugging. Go back to the source and fix the error.
Basic Object Oriented Programming
What is an Object?
An Object has it own states and behaviors.
When come to software, Software designers use the same idea to ease programmers to develop their software.
Each Software object also has its own states and behaviors.
methods (behavior) and attributes (states)
Encapsulation (Data Hiding)
- Hiding Information
- Provide a public interface for interacting with it
Advantages to software developers
- Modularity: An object can be easily passed around in the system. (Library, Reusability)
- Information hiding: Users need not go into details of the object before using the object.
- Safety: Users of the object may not directly access the internal state of the object. Reduce Errors.
What is a Class?
A Class is a blueprint of prototype that defines the variables and methods (functions) common to all objects of a certain kind. Every object of a class is an instance of that class.
Benefit - Reusability. Save effort in developing a number of objects of the same kind.
Declaring Classes in C++
To declare a class, use the class keyword.
1 | class Cat |
- Declaring the class does not allocate any memory for a Cat
- Only tell the compiler what a Cat is, the attributes and functions of the cat.
- Declaration of classes should be placed in the header file and included into your program.
#include
Declaring an Object of a Class
When a class is defined, we can further declare the objects of that class:
1 | Cat Frisky; // declare 1 Cat object called Frisky |
Obviously, one can declare two cats as follows:
1 | Cat Frisky, Felix; // declare 2 Cat objects |
Accessing Class Members
When an object is defined, we can access the members of that object based on its class definition.
The operator ‘.’ allows us to access the members of the object.
1 | unsigned int weight = Frisky.itsWeight; |
Never access directly to class.
1 | //Cat.itsAge = 5; // Don’t do that! Cat is class |
Private vs Public
Members can be divided into public members or private members.
- Private members of a class are those members that can only be accessed by member functions of that class. By default, all members are private.
- Public members of a class are those members that can be accessed by other functions and class objects.
This mechanism provides the privacy or security to the information of a class that requires protection.Typically, access private members by public methods.
1 |
|
How Private Variables Are Used?
Use Getters and Setters.
Set is for writing while Get is for reading.
1 |
|
Note: People can only read your class info while only you knows whats inside the function.
Private vs Public vs Protected
Constructors and Destructors
We can initialize an object using constructors.
- Every class should have a constructor
- User can define its own constructor for the class
- Otherwise, the compiler will make one for the user although it does nothing
Constructor is a function of which the program will call if an object of this class is constructed (created) and stored in memory. Besides constructor, every class has also a destructor that will be called when the object of that class is destructed (removed).Data memory released
Note: No return type needed for constuctors and destructors.
Look at this example:
1 | class Cat |
const Member Functions
It is possible that some functions will never change the value of any member variable.
- It is desirable to declare them as const member function
- Then, the compiler will automatically check if there is any inconsistency in the program
- It helps to debug the program
1 | int GetAge() const; // add the keyword const when |