\documentclass[11pt]{article}

\usepackage{upquote}
\usepackage{pygmentex}

\title{\LaTeX\ Cheatsheet}
\author{Ashfaqur Rahman}
\date{May 12, 2018}

\begin{document}

\maketitle
\tableofcontents
\newpage

A latex cheatsheet.

\section{Characters and Commands}

\subsection{Latex special characters}

$ % & # _ { } \verb=\ ~ ^= are special characters and has special meaning to latex.
You can use a leading \textbackslash\ to use them. To print $, write \textbackslash$

\subsection{Latex commands}

Each latex command starts with a \textbackslash and contains only letters.
Example: \verb=\maketitle=, \verb=\tableofcontents= etc.\ Parameters to
a command are specified inside {} and optional parameters are specified
inside [ ]. For example \verb=\documentclass[10pt]{article}=.

\section{Writing}

\subsection{Modes in \LaTeX}

\begin{description}
\item[Paragraph mode] Normal mode
\item[Math Mode] For mathematical equation. Text inside \verb=(…)= or \verb=$…$= or \verb=$$…$$= or \verb=\begin{equation}…\end{equation}= or \verb=\begin{displaymath}…\end{displaymath}=
\item[Left to right mode] Text are displayed from left to right without line breaks. text inside \verb=\mbox{}=
\end{description}

\subsection{Creating a New Paragraph}

A blank line creates a new paragraph.

\subsection{Spaces}

\subsubsection{Inserting Spaces}

\verb=,= is used for inserting a space.

\subsubsection{Space after a period}

Latex assumes end of sentence if it found period after small case later. In that case it puts extra space after period. But for the cases like ``etc.’’ a space followed by \verb== should be used after period like \verb=etc.\ =. A space followed by \verb== means inter word space.

If ending of a sentence contains a uppercase letter to end the sentence use \verb=@= before period.

\subsubsection{Space after a latex command}

All spaces are ignored after a latext command like \verb=\LaTeX= command. To make a space after \LaTeX\ a space followed by \verb== should be used like \verb=\LaTeX\ =. Another way to do this is
to use empty {} after a command like \verb=\LaTeX{}=.

\subsection{Dashes}

\begin{itemize}
\item\verb=-= A intra-word dash or hyphene. Example: X-ray.
\item\verb=–= A number range dash. Example: 1–10
\item\verb=—= A punctuation dash. Example: —
\end{itemize}

\subsection{Quotations}

\verb== is used for single quotation start ().\
\verb=’= is used for single quotation end (‘).\
\verb== is used for double quotation start ().\
\verb=”= is used for double quotation end (“).

\subsubsection{Putting Quotation in a Quotation}

\verb=\,`Ah!`\, She said= produces ``,,`Ah!’,,‘’ She said

\subsection{Commenting}

\verb=%= is used for commenting. Latex ignore all character after \verb=%= to the end of the line. Also ignores space in the beginig of the next line.

\section{\LaTeX Commands List}

\begin{itemize}
\item\verb=\documentclass[]{}= — To specify document type. Arguments can be book, article, report etc. Options\footnote{Options are specified inside the square brackets} are:

    \begin{enumerate}
        \item 11pt --- 10\% larger than 10pt.
        \item 12pt --- 20\% larger than 10pt.
        \item twoside --- to print in both sides.
        \item twocolumn --- two column in a single page.
    \end{enumerate}

    \item\verb=\usepackage{}= --- To use external packages.
    \item\verb=\title{}= --- To specify document title.
    \item\verb=\author{}= --- To specify documnet author. Multiple authors cab be specified using \verb=\and= command.
    \item\verb=\begin{}= --- To begin any block. like \verb=\begin{document}= to begin any document, \verb=\begin{quote}= begins a long quotation, \verb=\begin{math}=begins a math block etc.
    \item\verb=\end{}= --- ends any block that begins with \verb=\begin{}=
            \item Argument of \verb=\begin= and \verb=\end= are called environments. They create different display environments. Every declaration or command can be environment like \verb=\emph= can also be written as environment like \verb=\begin{emph}= ... \verb=\end{emph}= Here is a list of different environments:

        \begin{description}
            \item[document] Document environment.
            \item[quote] Shor quotation environment.
            \item[quotation] Long quotation environment.
            \item[itemize] Unordered list environment.
            \item[enumerate] Ordered list environment.
            \item[description] Description list environment like this one.
            \item[displaymath] Display math equations in separate line but without equation number.
            \item[equation] Displayequation in separate line with equation number for further referance.
        \end{description}

    \item\verb=\maketitle= --- To create title. It must be inside \verb=\begin{document}=.
    \item\verb=\part= --- Create parts of a document. Doesn't effect documnet numbering.
    \item\verb=\chapter= ---- Create chapters. No applicable for article document class.
    \item\verb=\section= --- Specify a section.
    \item\verb=\subsection= --- Specify a sub-section of a section.
    \item\verb=\subsubsection= --- Specify a sub-section of a sub-section.
    \item\verb=\appendix= --- Specify an appendix.
    \item\verb={}= --- Curly braces can be used for defining scope. Example --- Input: \verb=Hello, {\em aagontuk}= Output: Hello, {\em aagontuk}
    \item\verb=\today= --- Current date \today
    \item\verb=\TeX= --- Shows \TeX
    \item\verb=\LaTeX= --- Shows \LaTeX
    \item\verb=\ldots= --- Produces  \ldots
    \item\verb=\emph{}= --- To emphasize text. Example: I will \emph{emphasize} it.
    \item\verb=\mbox{TEXT}= --- Never breaks TEXT.\ 
    \item\verb=\footnote{footnote}= --- To create a footnote. Example: Footnote\footnote{Please find the foornote here}
    \item\verb=\\= --- New line.
    \item\verb=\\*= --- New line but prevents a new page.
    \item\verb=\newline= --- New line.
    \item\verb=\hfill \break= --- New line.
    \item\verb=\newpage= --- New Page.
    \item\verb=\hspace{xmm}= --- x mm horizontal space.
    \item\verb=\vspace{xmm}= --- x mm vertical space.

\end{itemize}

\section{Useful Tricks}

\subsection{Centered section header without number}

In latex usually section are left aligned and numbered.
If a starred version of the section command is used
it doesn’t generate number. To make the section header
center aligned `sectsty’ package can be used.

\begin{pygmented}[lang=tex]
\documentclass[11pt]{article}
\usepackage{sectsty}
\sectionfont{\centering}

\begin{document}
\section*{Statement of Purpose}
\end{document}
\end{pygmented}

\end{document}

Index

Basic

How to output

  1. console.log() - Output in the developer console.
1
2
var a = 50;
console.log(a);
  1. alert() - Output in the browser.
1
2
var a = 50;
alert(a);

How to take Input

prompt() function is used to take input.

1
2
3
var lastQuestion;
lastQuestion = prompt("How long the universe will last?: ");
console.log(lastQuestion);

Variables

Converting Between Values
  1. From String To Number:

    1
    2
    3
    4
    var strNum = "3.14";
    var num = Number(strNum);
    console.log(strNum);
    console.log(num);
  2. From Number to String:

    1
    2
    3
    4
    var num = 2.72;
    var strNum = String(num);
    console.log(num);
    console.log(strNum);
Working with Numbers

TODO

Conditional Statement

INDEX

  1. <html>
  2. <head>
  3. <meta>
  4. <body>
  5. <h1> - <h6> for heading
  6. <hr> for horizontal line
  7. <p> for paragraph
  8. <pre> to preserve line breaks
  9. Formatting Tags
  10. Quotations
    1. Quoting using quotation mark
    2. Quoting using <blockquote>
    3. <abbr> for Abbreviation
    4. <address> for Contact Information
    5. Citation
  11. HTML color
  12. HTML & CSS
    1. Inline CSS
    2. Internal CSS
      1. Internal CSS using id
      2. Internal CSS using class
    3. External CSS
  13. <a> For links
  14. <img> For images
  15. <table> For tables
  16. HTML Lists
  17. HTML Forms
    1. <input> for various input area
    2. Example of an HTML form with all the tags and attributes

<html>


Attributes:

  • lang="language" - Specifies language used in the document. Example lang=”en-US”.

<head>


Contains title, style, script, meta informations of a page.

<meta>


This tag can only go inside <head> tag. It contains meta data of an HTML page.
<meta> tag has no ending tag.

Attributes:

  • charset="charset" - Describe the character encoding used in the document. Eg. UTF-8.
  • name="type" - Describe different information about the document. types for name can be
    • application-name
    • author
    • description
    • keyword - Keywords about the page. Useful for search engines.
    • viewport - Describe how the page will be shown in different devices. Very useful for portability.
  • http-equiv="type" - Provieds an HTTP header for the information of the content attribute. type can be:
    • refresh - To set refresh time of a page.
  • content="value" - Hold values for different types specified in name / http-equiv attribute.

Examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- Define keywords for search engines -->
<meta name="keyword" content="HTML, Cheetsheet, Tags, Attributes">

<!-- Define description of a web page -->
<meta name="description" content="This page is about html cheatsheet">

<!--To state author of the page>
<meta name="author" content="Aagontuk">

<!-- To set character encoding -->
<meta charset="UTF-8">

<!-- To refresh page in every 15 sec -->
<meta http-equiv="refresh" content="15">

<!-- To make the page look good in every device -->
<meta name="viewport" content="width=device-width, initial-scale="1.0"">

<body>


Attributes:

  • alink="color" - color of a link when it is clicked.
  • link="color" - color of unvisited link.
  • vlink="color" - color of visited link.
  • background="image.png" - background image of a page if bgcolor not set.
  • bgcolor="color" - background color of a page if background image not set.
  • text="color" - color of the texts in the page.

<h1> to <h6>


Creates headlines in html document.

<hr>


Creates a horizontal line. Used for styling the document.

Attributes:

  • align - Specifies alignment.
  • size="pixel" - Specifies height in pixel. Eg. size=”10”
  • width="x%" - Specifies width in %. Eg. width=”50%”
  • noshed - Line will be of a solid color.

<p>


Creates a paragraph. Omit any line breaks(extra space, tab etc).

<pre>


Use fixed width font. Preserve line breaks.

Formatting Tags


  • <b> - Bold Text.
  • <i> - Italic Text.
  • <u> - Underline.
  • <strong> - Strong Text.
  • <em> - Emphasized Text.
  • <small> - Samll Text.
  • <sup> - Superscript.
  • <sub> - Subscript.
  • <mark> - Marked Text. Text with some background color.
  • <del> - Deleted Text. Striked.
  • <ins> - Inserted Text. Underlined.

Quotations


Quoting with quotation mark

Texts under <q> tag are placed under quotation mark.

Quoting using <blockquote>

<blockquote> is used to quote text from another source.
Text under <blockquote> are indented.

1
2
3
4
5
6
7
<p>Here is some information about Themis:</p>
<blockquote cite="https://en.wikipedia.org/wiki/Themis">
Themis is an ancient Greek Titaness. She is described as
"[the Lady] of good counsel", and is the personification of
divine order, fairness, law, natural law and custom.
Her symbols are the Scales of Justice, tools used to remain balanced and pragmatic.
</blockquote>

<abbr> for Abbreviation

<abbr> is used for abbreviation. Show full form under cursor.

1
2
3
<p>
Richard M. Stallman is the creator of the <abbr title="GNU is not Unix">GNU</abbr> system.
</p>

<address> for Contact Information

1
2
3
4
<address>
Luke Skywalker</br>
Naboo System</br>
</address>

<cite>

<cite> is used for mentioning the title of someone’s work.

1
<p><cite>Star Wars</cite> directed by George Lucas</p>

HTML Color


Color can be specified in three way.

  1. Using color name. List of standard color names
    1
    <p style="color: red">This is a red text</p>
  2. Using RGB value.
    1
    <p style="color: rgb(0, 255, 0)">This is a green text</p>
  3. Using hexadecimal value.
    1
    <p style="color: #808080">This text is Ass</p>

CSS And HTML


CSS is used for decoration. Three ways to use CSS in HTML.

Inline CSS

Inline CSS is used to decorate each tag individualy using the style attribute.

1
<p style="font-family: garamond; color: red;">We want freedom in the web</p>

Internal CSS

Internal CSS is used to decorate the whole HTML document. <style> tag in used
inside <head> to decribe CSS properties.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>

<html>
<head>
<title>HTML Document</title>

<style>
h3 {
font-size: 50px;
text-align: center;
}

p {
font-family: garamond;
color: blue;
}
</style>
</head>

<body>
<h3> Internal CSS Example </h3>
<p> Internal CSS is decribed using <q>style<q> tag </p>
</body>
</html>

To identify each tag separately id and class can be used.

HTML id Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>

<html>
<head>
<title>Internal CSS</title>

<style>
h3 {
font-size: 30px;
font-family: garamond;
}

#p01 {
color: red;
font-size: 14px;
}

#p02 {
color: green;
font-size: 20px;
}
</style>
</head>

<body>
<h3> Internal CSS Example using id </h3>
<p id="p01"> This is first paragraph </p>
<p id="p02"> This is second paragraph </p>
</body>
</html>
HTML class Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>

<html>
<head>
<title>Internal CSS</title>

<style>
h3 {
font-size: 30px;
font-family: garamond;
}

p.redText {
color: red;
font-size: 14px;
}

p.greenText {
color: green;
font-size: 20px;
}
</style>
</head>

<body>
<h3> Internal CSS Example using class </h3>
<p class="redText"> This text should be red </p>
<p class="greenText"> This text should be green </p>
</body>
</html>

Extarnal CSS

Separate CSS file is used. <link> tag is used to use the file in the document.

1
2
3
<head>
<link rel="stylesheet" href="style.css">
</head>

See W3Schools.

<img> for Images

See W3Schools. Some interesting features:

  • Floating property
  • <map> tag.

<table> for Tables

See W3Schools. Example:

1
2
3
4
5
6
7
8
9
<table style="width:100%">
<tr>
<th>Title 1</th>
<th>Title 2</th>
</tr>
<tr>
<td> Cell 1</td>
<td> Cell 2</td>
</table>

HTML Lists

See W3Schools. Interesting:

  • Description List.
  • Creating a Menu using list and CSS.

HTML Form

For creating HTML forms for getting data from user.
Froms are created using <form></form> tag. Forms normaly contains:

  • <input> - Creating various types of inputs. Text, button, radio button, checbox etc.
  • <select> - For creating a drop down list.
  • <textarea> - For creating a large text field.
  • <label> - For creating label for various inputes.
  • <fieldset> - For specifying different input group. <legend> tag is used for labeling <fieldset>.

Important Attributes:

  • action="process_file_address" - Specifies the sever side sript which will process the submitted data.
  • method="get/post" - get for plain text submit. post for encrypted submit.
  • name="form_name" - Specifies the name of the form.
  • id="" - ID of the form.
  • autocomplete="on/off" - Turn on/off browser autocomplete feature.
  • enctype="" - Specifies how the data will be encrypted when send to the server.
  • accept="file_type" - Specifies comma separated file types that will be allowed for upload.
  • target="" - Specifies where submit response will be shown(New tab, own page etc).

<input> for various types of input area

In type attribute input types are specified.
It can be:

  • type="text" - For simple text area.
  • type="password" - For taking passwords.
  • type="radio" - For radio buttons.
  • type="checkbox" - For checkbox.
  • type="file" - For uploading file.
  • type="button" - Creating a button. When the button is clicked it works based on onclick="scrpit_to_execute" attribute.
  • type="submit" - Creates a submit button for the form. When the submit button is clicked action is taken based on the action attribute of the form.
  • type="reset" - Creates a button for resetting the form.
  • type="image" - Defines an image as a submit button.
  • type="range" - Creates a range slider.
  • type="number" - Creates a number picker.
  • type="color" - Creates a color picker.
  • type="date" - Creates a date picker.
  • type="tel" - Telephone number form.

Important Attributes:

  • name="" - Specifies the name of an <input/> element.
  • value="" - Specifies the value of an <input> element. This can be used for setting default value.
  • placeholder="" - This text is shown faded in the text fields.
  • size="" - Maximum character input size for an input field.
  • max="" - Maximum accepted value for number, range, date type.
  • min="" - Minimum accepted value for number, range, date type.
  • step="" - Step size for slider or number picker.
  • pattern="" - Specifies a regular expression against which input is validated.
  • title="" - Text that is show when input dont pass regex validation.
  • autocomplete="on/off" - on/off browser autocomplete feature.
  • autofocus="on/off" - Will autofocus to this input field when the page loads.
  • checked - Make a checkbox / radio button as checked.
  • disabled - To disable an input field.
  • multiple - User can enter multiple values in an input element.
  • readonly - Specifies a input field as readonly. It can’t be changed.
  • required - Specifies a field as required.
  • accept="file_type1, file_type2" - Accepted file types. Comma separated for multiple file type acceptence.
  • formaction="" - Specifies the script that will process this input field when the form submitted.
  • formmethod="get/post" - Which method to follow for form submission.
  • formenctype="" - Submitted data encryption type.
  • formtarget="" - Specifies where the response will be placed for this input(New tab, own page etc).

Example of an HTML form with all the tags and attributes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h2 class="header"> Create an Account in Hell NOW! </h2>

<form action="process.php" method="post" autocomplete="on">
<fieldset>
<legend>Basic Information</legend>
Your Name:&nbsp;
<input type="text" name="name" value="name" placeholder="Name" size="40" autofocus="on"/><br/>
Your Gender:<br/>
<input type="radio" name="gender" value="male"/>Male<br/>
<input type="radio" name="gender" value="female"/>Female<br/>
<input type="radio" name="gender" value="other" checked="checked"/>Other<br/>
Married?<br/>
<input type="checkbox" name="married" value="no" checked="checked"/>No<br/>
<input type="checkbox" name="married" value="yes"/>Yes</br>
</fieldset>

<fieldset>
<legend>Insanity Check</legend>
Pick <span class="color">Red</span> color:&nbsp;
<input type="color" name="color" value="blue"><br/>
What is the value of &Pi;:&nbsp;
<input type="number" name="pi" value="3" min="1" max="9" step="2"/><br/>
Can you slide for no reason?&nbsp;
<input type="range" name="slide" value="50" min="0" max="100" step="2"/>
</fieldset>

<fieldset>
<legend>Create Username</legend>
Username:&nbsp;
<input type="text" name="uname" placeholder="username" pattern="[A-Za-z]{6}" label="Only letters and upto six characters" required/><br/>
Password:&nbsp;
<input type="password" name="pass" pattern="[A-Za-z0-9]{6}" label="Only letters and numbers upto 6 characters" required/><br/>
Upload Image:<br/>
<input type="file" name="image"/>
</fieldset>

Want to meet god?<br/>
<label name="meetYes">Yes</label>
<input type="radio" name="god" value="yes" id="meetYes" disabled="disabled"/><br/>
<label name="meetNo">No</label>
<input type="radio" name="god" value="no" id="meetNo" disabled="disabled"/><br/>
<input type="submit" value="Register!"/>
<input type="reset"/>
</form>
</body>
</html>

Hello world

1
2
3
4
5
6
7
package main

import "fmt"

func main() {
fmt.Println("hello, world")
}
  • Every program is made up of packages
  • program starts running in package main

Functions

  • Types come after the variable name
  • Bellow function takes two integer and returns one integer
1
2
3
func add(x int, y int) int {
return x + y
}
  • Type can be crammed together if same type
1
2
3
func add(x, y int) int {
return x + y
}
  • Multiple values can be returned from functions
1
2
3
4
5
6
7
8
func swap(x, y string) (string, string) {
retrun y, x
}

func main() {
a, b := swap("hello", "world")
fmt.Println(a, b)
}
1
$ world hello
  • Values can be returned by name. If a variable name is specified
    with the return type. Those variable will be return by the function.
1
2
3
4
5
6
7
8
9
func plus_five(x, y int) (a, b int) {
a = x + 5
b = y + 5
return
}

func main() {
fmt.Println(plus_five(10, 20))
}
1
$ 15 25
  • Function can be passed to a function

  • A function can be closures

Variables

  • var declares a list of variables
1
2
3
4
5
6
7
8
9
10
11
12
var i, j int = 10, 20

var isGo bool
isGo = true

// Can't mix types in var
//var k int, isC bool

// implicit type declaration can be mixed
var k, isC = 25, false

fmt.Println(i, j, isGo, k, isC)
  • := can be used for short
1
k, isC = 25, false

Basic Types

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bool

string

int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr

byte // alias for uint8

rune // alias for int32
// represents a Unicode code point

float32 float64

complex64 complex128
  • Uninitialized variables are given default zero values. 0 for int, “” for strings
    and false for bools

  • If type isn’t specified explicitly type is inferenced from the context

    1
    2
    i := 10 // i is int
    hello := "hello, world" // hello is string
  • Type conversion is done with T(v)

    1
    2
    i := 10
    d := float64(i)
  • constants are declared with const keyword. Constants can be declared with
    :=.

    1
    const PI = 3.14

Conditional statements

if/else if/else

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import (
"fmt"
"bufio"
"strconv"
"strings"
"os"
)

func main() {
reader := bufio.NewReader(os.Stdin)
strInp, _ := reader.ReadString('\n')
strInp = strings.TrimSpace(strInp)

intInp, _ := strconv.Atoi(strInp)

if intInp < 0 {
fmt.Println("negative")
} else if intInp > 0 {
fmt.Println("positive")
} else {
fmt.Println("zero")
}
}
  • If condition with statement. Variable scope declared in the statement
    is inside if
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package main

    import (
    "fmt"
    "math"
    )

    func main() {
    x := -20
    if v := math.Abs(float64(x)); v >= 10 {
    fmt.Println("Too large to process: ", v)
    }
    }

Switch

  • No fall through cases
  • Evaluates from top to bottom, stops when a case succeed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package main

import (
"fmt"
"math/rand"
"time"
)

func cast_spell() string {
spells := []string{
"Oculus Reparo",
"Alohomora",
"Wingardium Leviosa",
}

max := len(spells) - 1

rand.Seed(time.Now().UnixNano())

index := rand.Intn(max + 1)

return spells[index]
}

func main() {
switch spell := cast_spell(); spell {
case "Oculus Reparo":
fix_glass()
case "Alohomora":
unlock()
case "Wingardium Leviosa":
float_object()
default:
break_wand()
}
}
  • Switch without argument can be used instead of an if/else if/else chain:
1
2
3
4
5
6
7
8
9
10
11
12
switch {
case input == "left":
go_left()
case input == "right":
go_right()
case input == "up":
go_up()
case input == "down":
go_down()
default:
open_portal()
}

Pointers

  • There is no pointer arithmetical
1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func main() {
var p *int

i := 10
p = &i
fmt.Printf("%v\n", *p)
}

Structs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import "fmt"

type Pixel struct {
R int
G int
B int
}

func main() {
p := Pixel{5, 10, 0}
fmt.Println(p.R, p.G, p.B)
}
  • Pointers to struct can be used as (*ptr).field. Shortcut ptr.field:
1
2
3
4
5
p := Pixel{5, 10, 0}
var q *Pixel
q = &p

r := &p // implicit type
  • Struct initialization:
1
2
3
4
a = Pixel{1, 2, 3}
b = Pixel{R: 2, B: 3} // G = 0
c = Pixel{} // R = 0, G = 0, B = 0
d = &Pixel{} // type &Pixel

Array

1
2
3
4
5
6
7
8
9
10
var arr [2]string
arr[0] = "hello"
arr[1] = "world"

list := [5]int{1, 2, 3, 4, 5}

var screen [1024]Pixel

screen := []Pixel{Pixel{1, 2, 3}, Pixel{1, 2, 3}} // implicit size
screen := []Pixel{{1, 2, 3}, {1, 2, 3},} // same as above

Slice

  • Slice are reference to an array
1
2
3
4
5
6
var a [10]int

s := a[1:3] // from index 1 until 3. Includes a[1],a[2]
s := [:3] // from 0 until 3
s := [3:] // from 3 to end
s := [:] // full array
  • Slices have length and capacity. Length is the number of elements and capacity
    is the undelying size.

  • make function can be used to create zero initialized arrays

1
2
arr := make([]int, 5) // 5 length, 5 capacity
arr := make([]int, 0, 5) // 0 length, 5 capacity
  • append function can be used to dynamically grow an array
1
2
3
var arr []int // len 0, cap 0

arr = append(arr, 1, 2) // append with element 1 and 2, now len 2, cap 2
  • Iterate array with for range
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
arr := []string{"hello", "world", "good", "bye"}

// use both index and value
for index, value := range arr {
fmt.Println(index, value)
}

// use only value
for _, value := range arr {
fmt.Println(value)
}

// use only index
for index, _ := range arr {
fmt.Println(index)
}

Maps

Loop

For loop

For with range

INDEX

  1. Frequently used git commands

    1. Configuring git
    2. Initializing a project
    3. Cloning a repository from remote
    4. Showing status of the project
    5. Adding files to staging area
    6. Inspect changes of a file
    7. Creating and applying patch file
    8. Commiting
    9. Removing files
    10. Moving/Renaming files
    11. Viewing logs
    12. Modifying last commit
    13. Removing from staging area
    14. Unmodifying a modified file
    15. Managing remote
    16. Tagging
    17. Aliasing
  2. Branching and Merging

    1. Creating a new branch
    2. Switching to a branch
    3. Deleting a branch
    4. Renaming a branch
    5. Merging a branch to another branch
    6. Merging a specific file from another branch
  3. Remote Branches

    1. Fetching commits from remote repository
    2. Pushing/fetching a new branch to/from remote repository
    3. Tracking Branch
    4. Pulling
    5. Deleting a remote branch
  4. Rewriting history

    1. Removing commits

Frequently Used Git Commands

Configuring Git

git config is used to create and modify system/user/repo git configuration file.

Options:

  • –system - will set the config system wide. for all user’s
    all repos in the system. System wide git config file is
    stored generally in /etc/gitconfig

  • –global - will set the config user wide. For a specific user’s
    all git repos. stored in ~/.config/git/config or user’s home directory.

  • –local - will set the config for a specific repo. Stored in .git/config

  • –list - Show all the list of current config variables and their values.

Examples:

1
2
3
4
git config --global user.name 'aagontuk'
git config --global user.email 'aagontuk@mail.com'
git config --global core.editor vim
git config user.name # will show value of user.name

Initializing a project

git init is used to initialize a project as git repository.

1
git init

Cloning a repository from remote

git clone is used for cloning a remote repository into local system.

1
git clone https://github.com/aagontuk/cheatsheets mycheatsheets

Showing status of the project

git status is used to see status of the project files. Untracked/tracked/modified/staged.

1
2
git status	# Show details status
git status -s # Show brief status

Adding files to staging area

git add is used to add untracked/modified files to staging area and prepare for commit.
If a directory is added, its contents will be added recursively.

  • Adding whole file:
1
git add README.md
  • Adding portion of a file:
1
git add -p README.md    # This will bring an interactive prompt

Inspect changes of a file

git diff is used to show changes of a file

1
2
3
git diff		# Shows changes between last staged and unstaged
git diff --staged # Shows changes between the last commit and staged
git diff COMMIT_HASH~ COMMIT_HASH # Show diff between last commit and its ancestor

Creating and applying patch file

For creating patch file use git diff:

1
git diff > mypatch.patch

If you want add untracked files too first stage them
using git add then create the patch file:

1
git diff --cached > mypatch.patch

Now you can
remove those untracked files from staging area
if you don’t want to commit them.

If you want to add binary files in the patch:

1
git diff --binary > mypatch.patch

To apply a patch:

1
git apply mypatch.patch

Commiting

git commit is used for commiting changes that are staged

1
2
3
4
git commit			        # To commit changes that are staged.
git commit -m "COMMIT_MSG" # Commit with inline commit message.
git commit -a # stage all tracked modified files and commit.
git commit -v # will add diff of changes in the commit message.

Removing files

git rm is used to remove files.

Following command will remove a file from tracking and also remove from system(HDD).

1
git rm project_file

If the file is already modified or staged, then to remove -f have to be used.

1
git rm -f project_file

To remove only from git but not from the system(HDD). So that git no longer track
the file.

1
git rm --cached project_file

Moving/Renaming files

git mv is used to rename files/folders

1
git mv project_file my_project_file

View logs

git log is used to view commit logs/history

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
git log					# Show entire commit log of the repo
git log -n # Show last n commit logs
git log -p -n # Show last n commit log including change/patch/diff in those commits
git log --stat # Commit log witch list of modified files and stat of the changes in those files
git log --pretty=oneline # show each commit log in one line with only full SHA and subject
git log --pretty=short # Log with SHA, author and subject
git log --pretty=full # Log with SHA, author, commiter, subject, message body
git log --pretty=fuller # Log with SHA, author, commiter, subject, message body, write and commit dates
git log --oneline # Show first 7 characters of SHA value, Heading
git log --format="%h - %an, %ad: %s" # Custom log output format
git log --graph # Will show a ascii graph of commit history
git log --relative-date # Will show relative date(days, weeks etc) rather than exact date
git log --since=2.weeks # Show all commits since a specific date or relative date
git log --until=2.weeks # Show all commit before a specific date or relative date
git log --author=AUTHOR # Show the logs of a specific author
git log --follow -- FILE # Show all the commits to a specific file
git log testing # Show the logs of testing branch
git log --all # Show logs of all branches. By default shows only the logs of checked out branch

Modifying last commit

After a commit, to redo that commit for additional changes
git commit --amend can be used. This is useful when accidentally
forgot to add files to a commit.

1
2
3
git commit -m "Serious bugfix"		# Accidentally commited without forgotten_files
git add forgotten_files # forgotten_files is added
git commit --amend # Previous commit will be modified by adding forgotten_files

If this command is used just after a commit, editor will show up to edit
the commit message. So this can be used to modify minor changes in the latest
commit message.

1
2
git commit -m "Serious busfix"
git commit --amend # Edit busfix -> bugfix

If you want to remove files that were added in a commit
mistakenly:

1
git reset --soft HEAD~N

N is the commit number relative to HEAD. Which is 1 for
the latest commit.

You will see last commit was deleted and all the files
in staging area again. Now you can
remove unwanted files from there.

Removing files from staging area

After files are staged in the staging are using git add command, to
remove the file from the staging area:

1
git reset HEAD file_name

Unmodifying a modified file

When a file is modified which is tracked by git, git show the modified
flag in git status. Following command can be used to discard the modification.
If this is used, git will no longer show it as modified, also modifications
to that file will be gone.

1
git checkout -- file_name

Managing Remote

  • Adding a remote repository to local
1
2
git remote add <shortname> <url>
git remote add origin git@github.com:aagontuk/cheatsheets.git
  • View the list of remote
1
git remote show
  • View details of a remote
1
2
git remote show <shortname>
git remote show origin
  • Fetching data from remote. Fetching will only download data
    from remote but will not merge automatically. After fetching
    you have to manually merge.
1
2
git fetch <remote>
git fetch origin
  • Pulling will fetch data and merge automatically
1
git pull
  • Pushing local to remote
1
2
git push <remote> <branch>
git push origin master
  • Renaming a remote
1
git remote rename back backports
  • Changing URL of a remote
1
2
git remote set-url <remote_name> <new_url>
git remote set-url origin https://github.com/aagontuk/cheatsheets.git
  • Removing a remote
1
git remote remove paul
  • Dry run merge
1
git merge --no-commit --no-ff $BRANCH_NAME

This will stage the changes but won’t commit them.
To see the staged changes:

1
git diff --cached

To undo the merge:

1
git merge --abort

Tagging

  • View tags
1
git tag
  • Search for tags
1
git tag -l "v1.1.*"
  • Creating a annotated tag
1
git tag -a v1.2 -m "Version 1.2"
  • Creating a lightweight tag
1
git tag v1.2-rc4

In annotated tag when shown with git show tag information and commit will be shown.
But in lightweight tag only commit information will be shown.

  • Tagging later in a specific commit
1
2
git tag <tag> <sha>
git tag v1.2 a02fed6
  • Viewing tag information
1
2
git show <tag>
git show v1.2
  • Tags have to be pushed separately in the remote.
    To push tags:
1
2
git push origin v1.2	# will push tag v1.2
git push origin --tags # will push all tags
  • To delete a tag from local:
1
git tag -d v1.2-rc4

This will only delete from local. To also delete from remote:

1
git push origin :refs/tags/v1.2-rc4
  • To checkout in a tag following command have to be used.
1
git checkout v1.1

Checkout in a tag will leave the repo in detached HEAD state.
After checking out to make further commits to this a new
branch have to be created.

1
git checkout -b version1.1 v1.1

Aliasing

Creating command aliases:

1
git config --global alias.unstage 'reset HEAD --'

Now you can use git unstage file1 instead of git reset HEAD -- file1 to unstage file1.

Aliasing a external tool:

1
git config --global alias.mergetool '!meld'

Branching and Meging

Creating a new branch

Create a new branch named testing:

1
git branch testing

Switching to a branch

Switch to a branch named testing:

1
git checkout testing

This shortcut can be used to create and checkout to a new branch in one command:

1
git checkout -b testing

This will create branch testing and switch to it.

Show all the branches

1
git branch --all

Deleting a branch

1
git branch -d testing

Renaming a branch

For example you want to change your branch name from bad_branch_name to good_branch_name.

1
git branch --move bad_branch_name good_branch_name

This will only change the local branch name. To change the remote branch name too
you have do first push the renamed branch to remote:

1
git push --set-upstream origin good_branch_name

Now there will be two branch in remote remotes/origin/bad_branch_name and
remotes/origin/good_branch_name. Remove remote/origin/bad_branch_name

1
git push origin --delete bad_branch_name

Merging a branch to another branch

Let’s say your are now in testing branch. You have added some changes and now
want to merge the commits of testing branch into master branch:

1
2
git checkout master
git merge testing

Remote Branches

Remote branches are named like <remote_name>/<remote_branch_name>.
For example origin/master. This points to the latest commit of your
remote repository at the time of your last synchronization.

Fetching commits from remote repository

1
git fetch <remote_name>/<remote_branch_name>

This will synchronize the remote branch with the local repository.
For example if your remote branch name is origin/master this will
synchronize orgin/master with the local repository. Note that this
will not merge commits from remote branch(origin/master) into
your local branch(master). You have to do it manually.

Pushing/fetching a new branch to/from remote repository

For example you have created a new branch named testing and
added some commits to it. Now you want to upload it to your
remote repository:

1
git push origin testing

This will create a new branch named testing in your remote repository.
If you want to name the remote branch name different from the local
branch name:

1
git push origin testing:experimental

For the next example lets say you didn’t name the differently.
Now if someone who is also forked that remote repository do fetch, a new
remote branch named origin/testing will be created in their local
repository. Not this will not create any new local branch to work on for them.
They will have to do it manually:

1
git checkout -b testing origin/testing

You can also use this shortcut if you keep the local branch name
and remote branch name same:

1
git checkout testing

If you want to give a different name to the local branch:

1
git checkout -b experimental origin/testing

Tracking Branch

Checking out a local branch from a remote branch creates
a tracking branch. Tracking branch means that local branch
and the remote branch has a direct relationship with each other. If you
are in that local branch when you do a push git will automatically
push the commits to the remote branch and when you do pull
git will automatically merge all the commits from the remote branch
to that local branch.

For example in above example if your are in testing branch, when you do a
pull git will merge all the commits from origin/testing to testing automatically.
And after working on testing when you do push git will automatically push
all the commits to origin/testing.

If you have a local branch which don’t have a tracking branch or you want to
change the remote tracking branch. For example if you currently on testing
branch and want to set origin/testing as you remote tracking branch:

1
git branch -u origin/testing

Pulling

For automatically fetching commits from remote branch and merging with
local tracking branch use:

1
git pull

It is equivalent to:

1
2
git fetch
git merge

Deleting a remote branch

1
git push origin --delete testing

This will delete branch testing from remote repository.

Cherry Picking

For merging a specific commit or set of commits from a brach
to another branch.

In below example COMMIT_HASH is the hash of the commit you want
to cherry pick from another branch:

1
2
git checkout stable-branch
git cherry-pick COMMIT_HASH

For cherry picking a set of commits(A, B are commit hash):

1
2
git checkout stable-branch
git cherry-pick A^..D

This assumes A is older commit than D and will include commit
hash A, B, C, D:

1
2
git checkout stable-branch
git cherry-pick A..D

If you want to exclude A:

Rewriting history

Removing commits

Lets say your commit history looks like this:

Number (newest-oldest) Commit Hash Commit Message
1 4d884d0 Important fix
2 5540e24 server fix
3 4c5199f client fix
4 7879940 My awesome fix
5 2c27f34 minor fix

If you want to remove consecutive commits you can use git rebase. For example
if you want to remove commit 3 and 4 you can do following:

1
git rebase --onto <branch_name>~<number of the oldest commit you want to remove> <branch_name>~<number of the oldest commit you want to keep> <branch_name>

So if you want to remove 3 and 4 in master branch:

1
git rebase --onto master~4 master~2 master

Now if you want to remove non-consecutive commits, you can use git cherry-pick. For example if you want to
remove commit 2 and 4 you have to do following procedure:

  • Go to oldest usable commit(In this case 5)
  • Create a new branch
  • cherry pick the commits you want to keep(In this case 3 and 1) after that commit(In this case 5).
  • Checkout to the previous branch you were in.
  • Do a hard reset to the last usable commit(In this case 5)
  • Merge the new branch in this branch

So lets say in our case you were in master branch and want to remove commit 2 and 4:

1
2
3
4
5
6
7
git checkout 2c27f34
git checkout -b new_branch
git cherry-pick 4c5199f
git cherry-pick 4d884d0
git checkout master
git reset --hard 2c27f34
git merge new_branch

After deleting the commit(s) you have to force push in the remote repository:

1
git push --force origin master

Note that deleting commits can introduce merge conflicts.

Introduction

Version Control System: Version control is a system that records changes to a file or set of files over time. Each change of those files can be tracked easily. So its is possible to revert back to a previous version etc.

Git: Git is a command line program for distributed version controlling

GitHub: GitHub is a web-based Git repository hosting service. It offers all the distributed version control and software management functionality of Git. It makes it easy to save project remotely, version controlling, collaborate with multiple developers on a project etc.

Configuring Git

Configure Name & Email: First we have to add name and email. If no name or email is added pc’s username will be used as username and host name will be used as email. This username and email is for your local repository and have no relation with remote repository’s(like github) username and email.

1
2
me@my-pc:~$ git config --global user.name 'name'
me@my-pc:~$ git config --global user.email 'me@example.com'

Configure color: Configure git so that terminal output becomes color coded.

git config --global color.ui 'auto'

Creating & Publishing Repository

Creating Local Repository


Creating repository: To make a local repository first create a folder where all other files & folder of this project will be saved. I am creating a project called cheatsheets where I will store all my cheatsheets. So first I will create a directory named cheatsheets.

me@my-pc:~$ mkdir cheatsheets

initializing: Now I have to go to in my newly created directory & do git init command to initialize git. This will create a hidden folder .git, where git will store all its information about this project for tracking.

1
2
me@my-pc:~$ cd cheatsheets
me@my-pc:~/cheatsheets$ git init

Now I will add files of my project to this directory. Lets say I have created a file called git_and_github.md which is my cheatsheet about git & github.

me@my-pc:~/cheatsheets$ ls
git_and_github.md

Checking status: git status command gives the current status of the local repository.

me@my-pc:~/cheatsheets$ git status

1
2
3
4
5
6
7
8
9
10
On branch master

Initial commit

Untracked files:
(use "git add <file>..." to include in what will be committed)

git_and_github.md

nothing added to commit but untracked files present (use "git add" to track)

Add to staging area: So its saying there is an untracked file. After adding contents to my files I have to add the files to staging area using git add command, So that git can track those files & their contents. Now I am adding git_and_github.md file to staging area.

me@my-pc:~/cheatsheets$ git add git_and_github.md

Now git status gives:

me@my-pc:~/cheatsheets$ git status

1
2
3
4
5
6
7
8
On branch master

Initial commit

Changes to be committed:
(use "git rm --cached <file>..." to unstage)

new file: git_and_github.md

Commiting: To add the files into main repository we have to use git commit command. A commit message with -m option will have to add with this. Now each time we change project’s files we have to use this command to add those changes into main repository. Commit message can be anything you want. Usually it is used for specifying what has been added or changed in a specific version of a file. It will also your github commit message when we will upload our local repository to remote github repository.

me@my-pc:~/cheatsheets$ git commit git_and_github.md -m "Commit Message"

1
2
3
[master (root-commit) f779fa4] Commit Message
1 file changed, 63 insertions(+)
create mode 100644 git_and_github.md

Updating changes: After modifying a file, changes will have to send into staging area issuing git add again. And commit changes to repository using git commit. Adding & commiting can be done in a single command issuing git commit -a.

me@my-pc:~/cheatsheets$ git commit -a -m "updated content"

1
2
[master 318a1c2] updated content
1 file changed, 53 insertions(+), 5 deletions(-)

Summary:

Command Description
git init initialize a local git repository
git status See current status of a git repository
git add Adding files to staging area
git commit Commit changes to repository

Publishing Local Repository


Now I will publish my local repository to a remote repository like GitHub.

Setup GitHub: Create GitHub accout. Set up ssh (optional) etc.

Creating a remote repository: Now I have to create a repository in GitHub which will be the remote repository for my local repository. My local repository will be synced in this remote repository. Repositories can be public or private.

I am creating a repository named cheatsheets in GitHub. The repository URL of github are in this form github.com/USERNAME/REPOSITORYNAME.git. So my newly created repository’s URL will be: https://github.com/rashfaqur/cheatsheets.git. For SSH it will be git@github:USERNAME/REPOSITORYNAME.git. In my case it is git@github.com:rashfaqur/cheatsheets.git

Note: If you want to use SSH you have to use SSH type URL for SSH to work.

Adding remote repository into local repository: Now I have to add my remote repository URL / address using git remote add URL_ALIAS URL command, so that my local repository can know my remote repository. Were URL is my remote repository’s URL and URL_ALIAS is a sudo name for remote repository URL so that I don’t have to type URL in future. URL_ALIAS can be any name. Commonly origin is used. I am using origin & SSH URL.

me@my-pc:~/cheatsheets$ git remote add origin git@github.com:rashfaqur/cheatsheets.git

This will have to do only once.

Pushing local repository: git push -u URL_ALIAS BRANCH_NAME command is used to push / publish local repository into remote Repositorie. Where BRANCH_NAME is the branch name. Main branch is called master. There can be several branch. I will add my porject into master branch.

me@my-pc:~/cheatsheets$ git push -u origin master

1
2
3
4
5
6
7
8
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 1.24 KiB | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@github.com:rashfaqur/cheatsheets.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.

Next time after commiting changes I can only issue git push to push all the changes into remote repository.

Branches


Creating a new branch

  • Show current branches

    1
    me@mypc:~/cheatsheets$ git branch
  • Create a new branch with name feature

    1
    me@mypc:~/cheatsheets$ git branch feature
  • Active / Checkout new branch

    1
    me@mypc:~/cheatsheets$ git checkout feature

PCB , Wering, Connecting Components

  1. Powering Up a project - SparkFun
  2. Working With Wires - SpurkFun
  3. Connectors
  4. PCB Basics - SparkFun

Pull Up and Pull Down Registors

  1. Pull up registors - SparkFun

Motors

DC Motors
  1. L293D Motor Driver - Robot Platform

Transistors

  1. BJT as Amplifier - Youtube
  2. BJT as Switch - Youtube

Logic Level

  1. Logic Level - SparkFun

Analog to Digital Conversion

  1. ADC - Arduino Playground
  2. ADC - SpurkFun

Pulse Width Modulation

  1. PWM - SparkFun

Shift Registers

  1. Shift Registers - SparkFun

Serial Communication

  1. Serial Communication: Asynchronous - SparkFun
  2. Conversion from RS-232 to TTL - SparkFun
Serial Peripheral Interface (SPI)
  1. SPI - SparkFun
Inter Integrated Circuit (I2C)
  1. I2C - SparkFun

Sensors

MPU6050 Motion Sensor
  1. MPU6050 - Dummy’s Code

Controlling

PID Controll
  1. PID Control Using Arduino
  2. PID Control - Book Chapter

  • See available images
1
docker images
  • Running a continer
1
docker run IMAGE_NAME
  • Running a container with tty
1
docker run -it IMAGE_NAME
  • See all the containers and their status.
    Without -a only shows the running container.
1
docker ps -a
  • Stoping a container
1
docker stop CONTAINER_ID
  • Restarting a container
1
docker restart CONTAINER_ID
  • Attaching a tty with stopped container
1
2
docker restart CONTAINER_ID
docker attach CONTAINER_ID
  • Removing a container instance
1
docker rm CONTAINER_ID
  • Create a new image from a container change
1
docker commit CONTAINER_ID IMAGE_NAME

INDEX

Variable and fundamental data types

Initializing a variable

  • Copy initialization:

    1
    int numRings = 20;
  • Direct initialization:

    1
    int numRings(20);
  • Uniform initialization:

    1
    int numRings{20}

If uniform initialization is used with no value. Default is 0.

1
int numRings{}

Integers

Fixed width integers

Will give fixed sized integer in all architecture.

1
2
3
4
5
6
7
8
9
10
11
12
#include <cstdint> // for fixed width integers

/*
* 8 bit singed integer. Many systems consider them as chars. So it is better
* to not use them if using integers is the purpose
*/
int8_t var;

uint8_t var; // 8 bit unsigned integer

intN_t var; // N = 16, 32, 64 bits signed integer
uintN_t var; // N = 16, 32, 64 bits unsigned integer

Fixed width integers performance is machine dependent. To get the fastest
integer type on a specific machine use int_fastN_t. It will give the fastest
integer which is at least N bits long. N = 8, 16, 32, 64.

1
int_fast32_t var;

To get the smallest integer which is at least N bits long use int_leastN_t
where N = 8, 16, 32, 64.

1
int_least64_t var;

Floating point numbers

Setting precision of a floating point number:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <iomanip> // for std::setprecision()

int main(){
double d{12.34567890};

std::cout << "Without precision: " << d << std::endl;
std::cout << std::setprecision(4);
std::cout << "With precision: " << d << std::endl;

return 0;
}

Special floating numbers: positive infinity, negative infinity, not a number.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

int main(){
float zero(0.0);
float posinf = 5.0 / zero;
float neginf = -5.0 / zero;
float nan = zero / zero;

std::cout << posinf << std::endl;
std::cout << neginf << std::endl;
std::cout << nan << std::endl;

return 0;
}

Boolean Numbers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

int main(){
bool universeCameFromNothing(true);

std::cout << "Universe came from nothing: " << universeCameFromNothing
<< std::endl;

std::cout << std::boolalpha;

std::cout << "Universe came from nothing: " << universeCameFromNothing
<< std::endl;

return 0;
}

Type Casting

1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main(){
char ch(65);

std::cout << ch << std::endl;
std::cout << static_cast<int>(ch) << std::endl;

return 0;
}

To get the variable or expression type.

1
2
3
4
5
6
7
8
9
#include <typeinfo>

int main(){
int numerator(50);
double denominator(5.0);

std::cout << typeid(numerator).name() << std::endl;
std::cout << typeid(numerator / denominator).name() << std::endl;
}

Literal

1
2
3
4
5
6
7
8
int integer(50);	// integer
float f(0.05f); // used f suffix as default literal is double type
double d(0.31416); // double floating literal
int hex(0xa0); // hexadecimal literal
int oct(012); // Octal literal
int bin(0b1010); // Binary literal

int longNumber(1'23'570) // c++14 only

Constants

1
2
3
4
5
6
7
8
9
const double avg(6.023e23);
const double massEarth; // This is not allowed

int x(50);
const int y(x) // This is allowed

constexpr double adg(9.8); // Compile time constant. Value of the constant
// must be resolved in compile time otherwise
// will generate an error. This is c++11 feature

Variable Scopes and duration

shadowing:

1
2
3
4
5
6
7
8
9
10
11
12
int number(5);

if(number == 5){
int number; // local variable

number = 10; // will effect only local variable
// this is shadowing

std::cout << number << std::endl; // will print local
}

std::cout << number << std::endl; // will print outer block number

Global scope operator

:: is the global scope operator.

1
2
3
4
5
6
7
8
int x(50);	// global variable

int main(){
int x(40);

std::cout << x << std::endl; // will print local x
std::cout << ::x << std::endl; // will print global x
}

Internal Variable: Can be used anywhere in the file they are defined but not
out of the file.

External Variable: Cab be used across multiple files. Global variables are
by default external. static keyword can be used to make them internal.

Console Input/Output

Console I/O Methods

  • std::cin is used for console input. std::cin takes inputs untill first
    whitespace.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <iostream>

    int main(){
    int selection;

    std::cin >> selection;
    std::cout << "You have selected: " << selection << std::endl;

    return 0;
    }
  • std::getline() is used to take whole line as input.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <iostream>
    #include <string>

    int main(){
    std::string name;

    std::cout << "Enter Name: ";
    std::getline(std::cin, name);
    std::cout << "Your name is: " << name;

    return 0;
    }

Error Handling in Console Input

std::cin takes upto newline from the input stream. So it will be a problem if any other input function is used after taking numeric input from std::cin.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>

int main(){
std::string name;
int select;

std::cout << "Select: ";
std::cin >> select;

std::cout << "Enter name: ";
std::getline(std::cin, name); // will not work

std::cout << "Your name is: " << name << "! You have selected: "
<< select;

return 0;
}

To solve this problem std::cin.ignore(n, ch) can be used where n is the
number of character to ignore from the input stream before ch character is
found.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>

int main(){
int select;
std::string name;

std::cout << "Select: ";
std::cin >> select;

std::cin.ignore(32767, '\n');

std::cout << "Enter name: ";
std::getline(std::cin, name);

std::cout << "Hi " << name << "! You have selected " << select << std::endl;

return 0;
}

A Program Handling All the Error Case in Input

Expand to see code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>

double getDouble(){
double d;

while(true){
std::cout << "Enter: ";
std::cin >> d;
std::cin.ignore(32767, '\n'); /* clear '\n' from input stream */

/*
* Input will fail if a valid number isn't typed.
* if input fails, cin will set fail flag and stop extracting
* characters from input stream.
*/
if(std::cin.fail()){
std::cout << "Please enter a floating number" << std::endl;
std::cin.clear(); /* Clear fail flag */
std::cin.ignore(32767, '\n'); /* Clear input stream */
}
else{
return d;
}
}
}

char getOperator(){
char op;

while(true){
std::cout << "Enter (+, -, * or /): ";
std::cin >> op;
std::cin.ignore(32767, '\n');

if(op == '+' || op == '-' || op == '*' || op == '/'){
return op;
}
else{
std::cout << "Bad operator. Input again." << std::endl;
}
}
}

void printResult(double d1, char op, double d2){
if(op == '+'){
std::cout << d1 << " + " << d2 << " = " << d1 + d2 << std::endl;
}
else if(op == '-'){
std::cout << d1 << " - " << d2 << " = " << d1 - d2 << std::endl;
}
else if(op == '*'){
std::cout << d1 << " * " << d2 << " = " << d1 * d2 << std::endl;
}
else{
if(d2 != 0){
std::cout << d1 << " / " << d2 << " = " << d1 / d2 << std::endl;
}
else{
std::cout << "Can't devide by zero!";
}
}
}

int main(){
double d1 = getDouble();
char op = getOperator();
double d2 = getDouble();

printResult(d1, op, d2);

return 0;
}

Generating Random Numbers

Generating Random Numbers

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <ctime>
#include <cstdlib>

int main(){
/* For generating different seed each time the program runs */
srand(static_cast<unsigned int>(time(0)));
std::cout << rand();

return 0;
}

Function for generating Random Numbers Between A Range

Using modulus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <ctime>
#include <cstdlib>

int getRandom(int min, int max){
return min + (rand() % (max - min + 1));
}

int main(){
/* For generating different seed each time the program runs */
srand(static_cast<unsigned int>(time(0)));
std::cout << getRandom(1, 6);

return 0;
}

But this method is biased to low numbers. Following method has less bias to
low numbers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <ctime>
#include <cstdlib>

int getRandom(int min, int max){
static const double fraction = 1.0 / RAND_MAX;

return min + ((max - min + 1) * (rand() * fraction));
}

int main(){
/* For generating different seed each time the program runs */
srand(static_cast<unsigned int>(time(0)));
std::cout << getRandom(1, 6);

return 0;
}

For details: http://www.learncpp.com/cpp-tutorial/59-random-number-generation/

Advanced Data Types

Array

Array Indexes

Array index must be a compile time constant.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

int main(){
int array[5]; // ok

#define ARR_SIZE 5
int array[ARR_SIZE]; // ok

int const arr_size = 5;
int array[arr_size]; // ok

int arr_size = 5;
}

Representing Array Indexes with Enumerators

Array index can be represented with enumerators. In this way it makes
arrays well documented:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

namespace Store{
enum Store{
LM7805,
MAX485,
LM311,
ATMEGA64,
LED,
MAX_ELEMENT
};
}

int main(){
int inStore[Store::MAX_ELEMENT];

inStore[Store::LM7805] = 50;

std::cout << "There are " << inStore[Store::LM7805] \
<< " LM7805 in store" << std::endl;

return 0;
}

Relation Between Array and Pointer

Arrays are actually pointers. It points to the first element of the array.

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

int main(){
int arr[2] = {1, 2};

/* Following two address will be same*/
std::cout << arr << std::endl;
std::cout << &arr[0] << std::endl;

return 0;
}

Difference Between Array and Pointer to Array

The type of the array is int (*)[n] if it is an integer array
but the type of the pointer to that array is int *. Array type contains
the size information of the array. When array is dereferenced or assigned
to a pointer it implicitly converts itself into type * from
type (*)[n] so size information is lost. Here is an example of this
behaviour:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

int main(){
int arr[5] = {1, 2, 3, 4, 5};
int *arrPtr = arr; // arr is converted from int (*)[2] to int *

/* Will print the size of the array which is 5 * 8 bytes */
std::cout << sizeof(arr) << std::endl;

/* Will print the size of the pointer which is 8 bytes */
std::cout << sizeof(arrPtr) << std::endl;

return 0;
}

String Constants Using Fixed Sized Array and Pointer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

int main(){
/*
* keep the string constant in memory with r/w access
* and return the pointer to it.
* So string constant can be changed any time later
*/
char arr[] = "hello, world";

/*
* Keep the string constant in read-only section of memory
* so it can't be changed
*/
char *text = "GNU is not Unix";

/* As it is a constant so its better to initialize following way */
const char *text = "GNU is not Unix";

arr[0] = 'g'; // This OK

/*
* In this case as string constant is kept in read-only
* memory, doing this will generate segmentation
* fault
*/
*(text + 2) = 'O';

std::cout << arr << std::endl;
std::cout << text << std::endl;

return 0;
}

Pointers

Definig NULL Pointer C++ Way

From C++11 nullptr keyword can be used to define a NULL pointer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

int main(){
int *ptr = nullptr;

if(ptr){
std::cout << "Not null" << std::endl;
}
else{
std::cout << "Null" << std::endl;
}

return 0;
}

Void Pointers

  • Can point to any data type
  • Have to cast manually to a data type before dereferencing.
  • Pointer arithmetic can’t be done using void pointers as size of the
    obect isn’t known
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

int main(){
int x(5);
void *ptr = &x; // pointing to an integer

std::cout << *static_cast<int*>(ptr) << std::endl;

char ch = 'P'; // pointing to a char
ptr = &ch;

std::cout << static_cast<char*>(ptr) << std::endl;

return 0;
}

Converting A Pointer Address to Integer

Using reinterpret_cast<>:

1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main(){
int x = 17;
unsigned int addressX = reinterpret_cast<int>(&x);

std::cout << addressX << std::endl;

return 0;
}

Dynamic Memory Allocation

There are three basic type of memory allocation:

  • Static memory allocation: Static and global variables. Allocated
    when program runs. Persist throught the program life. Memory is taken from the stack.

  • Atomatic memory allocation: Function parameter and local variables. Allocated when enter into relevent block and deallocated when exited the block. Memory is taken from the stack.

  • Dynamic memory allocation: Memory allocated and deallocated dynamically. Memory is taken from the heap.

Allocating Memory dynamically

Dynamically memory is allocated using the new keyword.

1
2
3
4
5
6
7
8
9
#include <iostream>

int main(){
int *ptr = new int; // dynamically an integer is allocated.

*ptr = 5;

return 0;
}

Deallocating memory

Memory is deallocated using the delete keyword.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

int main(){
int *ptr = new int(5); // memory is allocated to the pointer

/* memory is deallocated.
* memory is realesed by os.
*/

delete ptr;

/* still the pointer is holding the memory address
* so its better to make it null
*/
ptr = 0;
ptr = nullptr; // c++11

return 0;
}

Memory leak

memory leak happens when allocated memory can’t be deallocated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

void doSomthing(){

/* Memory is allocated but not deallocated
* so memory leak happens when the variable
* goes out of scope as there is no way
* to deallocate in that case
*/

int *ptr = new int;
}

int main(){
doSomthing();
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

int main(){
int *ptr = int new;

int val;

// assigning to a address with out deallocating
ptr = &val; // memory leak

return 0;
}
1
2
3
4
5
6
7
8
9
10
#include <iostream>

int main(){
int *ptr = new int(5);

// allocating new memory without deallocating previous one
int *ptr = new int(10);

return 0;
}

Reference Variables

Create alias for a variable. Basically share same memory address. Must be
initialized with an addressable object. Can be used in function to pass
parameter by reference.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

int main(){
int x(10);
int &y = x; // reference variable

/*
* will output:
* 10
* 10
*/
std::cout << x << std::endl
std::cout << y << std::endl

return 0;
}

For Each Loop

  • Only works from c++11 above
  • Can’t be used in case of decayed arrays and dynamically allocated arrays.
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

int main(){
int fibseq[] = {1, 1, 2, 3, 5, 8, 13, 21};

std::cout << "Fibonacci Sequence: ";
for(const auto &elem: fibseq){
std::cout << elem << " ";
}
std::cout << std::endl;

return 0;
}

Functions

Function Pointers

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

int foo(int x){
return x*x;
}

int main(){
int (*square)(int) = foo;

std::cout << square(10) << std::endl;

return 0;
}
  • Can’t be used for function’s with default arguments

Function Ellipsis

Ellipsis can be used to pass variable length argument in a function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <cstdarg> // to use ellipsis

void printNum(int count, ...){
va_list list;
va_start(list, count);

for(int arg = 0; arg < count; arg++){
std::cout << va_arg(list, int) << std::endl;
}

va_end(list);
}

int main(){
printNum(5, 1, 2, 3, 4, 5);

return 0;
}

Lambda Functions

To create anonymous functions. Simple example:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <algorithm>
#include <vector>

int main(int argc, char *argv[]) {
std::vector<bool> bitvect{1, 0, 0, 1};

/* lambda function example: used to make ~bitvect */
std::transform(bitvect.begin(), bitvect.end(), bitvect.begin(),
[](bool b){ return b == 1 ? 0 : 1; });

return 0;
}

Syntaxt:

[&](){}: Capture all outside variable by reference.
[=](){}: Capture all outside variable by value.
[&x](){}: Capture only outside variable x by reference.
[x](){}: Capture only outside variable x by value.
[&, x](){}: Capture all outside variable by reference but x by value.
[]() -> Type {}: To specify return type.

Object Oriented Programming

Basic Class Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>

class Point{

private:
double m_x;
double m_y;

public:
double getX(){
return m_x;
}

void setX(double x){
m_x = x;
}

double getY(){
return m_y;
}

void setY(double y){
m_y = y;
}
};

int main(){
Point p;

p.setX(-2.5);
p.setY(2.5);

std::cout << "(" << p.getX() << ", " << p.getY() << ")" << std::endl;

return 0;
}

Constructors

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>

class Point{

private:
double m_x;
double m_y;

public:
Point(double x = 0, double y = 0): m_x(x), m_y(y){
// empty
}

double getX(){
return m_x;
}

void setX(double x){
m_x = x;
}

double getY(){
return m_y;
}

void setY(double y){
m_y = y;
}

void printPoint(){
std::cout << "(" << m_x << ", " << m_y << ")" << std::endl;
}
};

int main(){
Point p(0.5, 0.5);

p.printPoint();

return 0;
}

In c++11 its possible to give default value in class memeber variable
declaration.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>

class Point{

private:
double m_x = 0; // default value of x
double m_y = 0; // default value of y

public:
// member variable will be initialized with default value
// if called
Point(){
//empty
}

double getX(){
return m_x;
}

void setX(double x){
m_x = x;
}

double getY(){
return m_y;
}

void setY(double y){
m_y = y;
}

void printPoint(){
std::cout << "(" << m_x << ", " << m_y << ")" << std::endl;
}
};

int main(){
Point p; // will call default constructor

p.printPoint();

return 0;
}

Destructors

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <cassert>

class Point{

private:
double m_x;
double m_y;

public:
Point(double x = 0, double y = 0): m_x(x), m_y(y){
//empty
}

double getX(){
return m_x;
}

void setX(double x){
m_x = x;
}

double getY(){
return m_y;
}

void setY(double y){
m_y = y;
}

void printPoint(){
std::cout << "(" << m_x << ", " << m_y << ")" << std::endl;
}
};

class PointArray{

private:
Point *m_points;
int m_length;

public:
PointArray(int length){
m_points = new Point[length];
m_length = length;
}

// Destructor
~PointArray(){
delete[] m_points;
}

void insert(Point &p, int index){
assert(index >= 0 && index < m_length);

m_points[index] = p;
}

Point& get(int index){
assert(index >= 0 && index < m_length);

return m_points[index];
}
};

int main(){
PointArray parr(5);

Point p(2, 3);
Point q;

parr.insert(p, 0);

q = parr.get(0);
q.printPoint();

return 0;
}

Static Member Variables

  • Will shared by all object.
  • Not bound to any object. Bound to the whole class. So it is possible
    to use this variable without any object.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>

class Static{
public:
static int id;
};

/* Have to initialize first otherwise linker error will generate */
int Static::id = 1;

int main(){
Static s;
Static t;

/* Shared by both object */
s.id = 5;
std::cout << s.id << "\t" << t.id << std::endl;

/* Bound to whole class */
Static::id = 10;
std::cout << s.id << "\t" << t.id << std::endl;

return 0;
}

Static Member Functions

  • Not bound to any object.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

class ID{
private:
static int m_id;

public:
static int getID(){
return m_id;
}
};

/* Have to initialize first otherwise linker error will generate */
int ID::m_id = 1;

int main(){
std::cout << ID::getID << std::endl;

return 0;
}

Member Types

In C++ classes can have memeber types or nested types. They make the class
easy to maintain. For example in the following example it will be easy
to change the type from int to double. It need to change in only one line.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

class Point{
public:
using point_t = int; // Member type

Point(point_t x, point_t y): m_x(x), m_y(y){}

void print(void){
std::cout << "(" << m_x << ", " << m_y << ")";
}

private:
point_t m_x;
point_t m_y;
};

int main(int argc, char *argv[]){
Point p(10, 20);
p.print();
return 0;
}

Access Specifiers

public:
private:
protected:

Chaining member functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>

class Point{
public:
using point_t = int;

Point(point_t x, point_t y): m_x(x), m_y(y){}

Point& add(point_t x, point_t y){
this->m_x += x;
this->m_y += y;
return *this;
}

Point& mul(point_t x, point_t y){
this->m_x *= x;
this->m_y *= y;
return *this;
}

void print(void){
std::cout << "(" << m_x << ", " << m_y << ")";
}

private:
point_t m_x;
point_t m_y;
};

int main(int argc, char *argv[]){
Point p(10, 20);
p.add(3, 5).mul(7, 8).add(2, 3);
p.print();
return 0;
}

Difference between structs and classes in C++

C++ structs and classes are same. Only difference is that all members in structs are public.

Friend function and friend class

Friend functions and classes can access the private members of a class. In the following example printWeather() is friend of both Humidity and Temperature class. So it can access
private members of both classes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>

class Humidity;

class Temperature
{
private:
int m_temp;
public:
Temperature(int temp=0) { m_temp = temp; }

friend void printWeather(const Temperature &temperature, const Humidity &humidity);
};

class Humidity
{
private:
int m_humidity;
public:
Humidity(int humidity=0) { m_humidity = humidity; }

friend void printWeather(const Temperature &temperature, const Humidity &humidity);
};

void printWeather(const Temperature &temperature, const Humidity &humidity)
{
std::cout << "The temperature is " << temperature.m_temp <<
" and the humidity is " << humidity.m_humidity << '\n';
}

int main()
{
Humidity hum(10);
Temperature temp(12);

printWeather(temp, hum);

return 0;
}

Classes can also be friend of another class. In following example Display class if a friend
of Storage class so it can access the private members.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>

class Storage
{
private:
int m_nValue;
double m_dValue;
public:
Storage(int nValue, double dValue)
{
m_nValue = nValue;
m_dValue = dValue;
}

// Make the Display class a friend of Storage
friend class Display;
};

class Display
{
private:
bool m_displayIntFirst;

public:
Display(bool displayIntFirst) { m_displayIntFirst = displayIntFirst; }

void displayItem(const Storage &storage)
{
if (m_displayIntFirst)
std::cout << storage.m_nValue << " " << storage.m_dValue << '\n';
else // display double first
std::cout << storage.m_dValue << " " << storage.m_nValue << '\n';
}
};

int main()
{
Storage storage(5, 6.7);
Display display(false);

display.displayItem(storage);

return 0;
}

Operator Overloading

In C++ each operator is actually a function. For example the operator + is acturally
operator+() function.

  • At least one of the operand will have to be a custom type

Using Friend Function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>

class Point{
private:
using point_t = int;
point_t m_x;
point_t m_y;

public:
Point(): m_x(0), m_y(0){}
Point(point_t x, point_t y): m_x(x), m_y(y){}

// constant memeber function
void print(void) const {
std::cout << "(" << m_x << ", " << m_y << ")" << "\n";
}

// This is not a member function only a friend function
// This could defined outside of the function too
friend Point operator+(cost Point &p, const int n){
return Point(p.m_x + n, p.m_y + n);
}

friend Point operator+(const int n, const Point &p){
return p + n;
}

friend Point operator+(const Point &p1, const Point &p2){
return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
}
};

int main(int argc, char *argv[]){
Point p1(10, 20);
Point p2(4, 5);
Point p3 = p1 + p2 + 5;

p3.print();

return 0;
}

Using Normal Function

If there is no need to access private class data, operator overloading can be done as normal
function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>

class Point{
private:
using point_t = int;
point_t m_x;
point_t m_y;

public:
Point(): m_x(0), m_y(0){}
Point(point_t x, point_t y): m_x(x), m_y(y){}

point_t getX(void) const {
return m_x;
}

point_t getY(void) const {
return m_y;
}

// constant memeber function
void print(void) const {
std::cout << "(" << m_x << ", " << m_y << ")" << "\n";
}
};

Point operator+(const Point &p, const int n){
return Point(p.getX() + n, p.getY() + n);
}

Point operator+(int n, const Point &p){
return p + n;
}

Point operator+(const Point &p1, const Point &p2){
return Point(p1.getX() + p2.getX(), p1.getY() + p2.getY());
}

int main(int argc, char *argv[]){
Point p1(10, 20);
Point p2(4, 5);
Point p3 = p1 + p2 + 5;

p3.print();

return 0;
}

Using Member Function

The assignment (=), subscript ([]), function call (()), and member selection (->) operators must be overloaded as member functions.
IO operators(<< and >>) can’t be overloaded as memeber functions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

class Point{
private:
using point_t = int;
point_t m_x;
point_t m_y;

public:
Point(): m_x(0), m_y(0){}
Point(point_t x, point_t y): m_x(x), m_y(y){}

// No need to pass the class explicitly as it will be passed as hidden this pointer
Point operator+ (int n){
return Point(m_x + n, m_y +n);
}
};

int main(int argc, char *argv[]){
Point p1(10, 20);
Point p2 = p1 + 5;
return 0;
}

Overloading IO operators

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>

class Point{
private:
using point_t = int;
point_t m_x;
point_t m_y;

public:
Point(): m_x(0), m_y(0){}
Point(point_t x, point_t y): m_x(x), m_y(y){}

point_t getX(void){
return m_x;
}

point_t getY(void){
return m_y;
}

friend std::ostream& operator<< (std::ostream &out, const Point &p);
friend std::istream& operator>> (std::istream &in, Point &p);
};

// Overloading as friend function
// Returning std::ostream so that it can be chained like std::cout << p1 << p2
std::ostream& operator<< (std::ostream &out, const Point &p){
out << "(" << p.m_x << ", " << p.m_y << ")";
return out;
}

std::istream& operator>> (std::istream &in, Point &p){
in >> p.m_x >> p.m_y;
return in;
}

// Overloading as normal function
Point operator+ (Point p, int n){
return Point(p.getX() + n, p.getY() + n);
}

Point operator+ (int n, Point p){
return p + n;
}

Point operator+ (Point p1, Point p2){
return Point(p1.getX() + p2.getX(), p1.getY() + p2.getY());
}

int main(int argc, char *argv[]){
Point p1(10, 20);
Point p2;

std::cout << "Enter a point:\n";
std::cin >> p2;
std::cout << p1 << " + " << p2 << " = " << p1 + p2 << "\n";

return 0;
}

Functors

When classes acts like function calls they are called functors. This can be done by
overloading () operator.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>

class Point{
private:
using point_t = int;
point_t m_x;
point_t m_y;

public:
Point(): m_x(0), m_y(0){}
Point(point_t x, point_t y): m_x(x), m_y(y){}

point_t getX(void){
return m_x;
}

point_t getY(void){
return m_y;
}

// () can only be overloaded as member function
Point operator() (int n){
return Point(m_x + n, m_y + n);
}

friend std::ostream& operator<< (std::ostream &out, const Point &p);
};

// Overloading as friend function
// Returning std::ostream so that it can be chained like std::cout << p1 << p2
std::ostream& operator<< (std::ostream &out, const Point &p){
out << "(" << p.m_x << ", " << p.m_y << ")";
return out;
}

int main(int argc, char *argv[]){
Point pnt(10, 20);

// Will add 5 to pnt.m_x, pnt.m_y and create new Point object.
// Notce class object is called like function.
std::cout << pnt(5) << "\n";

return 0;
}

Overloading Typecast

Typecast overloading can be done to convert between types.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <cmath>

class Polar{
private:
double m_r;
double m_theta;

public:
Polar(double r, double theta): m_r(r), m_theta(theta){}
friend std::ostream& operator<< (std::ostream &out, const Polar &p);
};

// Overloading as friend function
// Returning std::ostream so that it can be chained like std::cout << p1 << p2
std::ostream& operator<< (std::ostream &out, const Polar &p){
out << "(" << p.m_r << ", " << p.m_theta << ")";
return out;
}

class Cartesian{
private:
using point_t = int;
point_t m_x;
point_t m_y;

public:
Cartesian(): m_x(0), m_y(0){}
Cartesian(point_t x, point_t y): m_x(x), m_y(y){}

friend std::ostream& operator<< (std::ostream &out, const Cartesian &c);

// Typecast overloading
operator Polar() const {
double r = sqrt(pow(m_x, 2) + pow(m_y, 2));
double theta = atan(static_cast<double>(m_y) / static_cast<double>(m_x));
theta = (theta * 180) / M_PI;

return Polar(r, theta);
}
};

std::ostream& operator<< (std::ostream &out, const Cartesian &c){
out << "(" << c.m_x << ", " << c.m_y << ")";
return out;
}

int main(int argc, char *argv[]){
Cartesian cart(10, 20);
Polar pol(cart);

std::cout << "Cartesian: " << cart << "\tPolar: " << pol << "\n";

return 0;
}

Copy Constructors

When copy initialization is used a copy constructor is used. By default
compiler uses memberwise initialization if no copy constructor is
provided. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Xyz {
private:
int m_var;
public:
Xyz(int x): m_var(x){}
};

int main(void){
Xyz xy(10); // uses default initialization

Xyz yz(xy); // Copy initialization
// As there is no copy constructor provided, compiler will do a memberwise initialization
}

Member functions of a class can access the private members ot
the same class type. Here is an example with copy constructor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Xyz {
private:
int m_var;
public:
Xyz(int x): m_var(x){}

// Copy constructor
Xyz(const Xyz &xyz): m_var(xyz.m_var){}
};

int main(void){
Xyz xy(10); // uses default initialization

Xyz yz(xy); // uses copy constructor
}

Elision

Copy initialization should be avoided as it can be elided
for optimization.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <string>

class Hello{
private:
std::string m_s;

public:
Hello(std::string s): m_s(s){}

Hello(const Hello &h): m_s(h.m_s){
std::cout << "Copy constructor called\n";
}

std::string get(void){return m_s;}
};

int main(int argc, char *argv[]){
Hello h("hello");
Hello g(h); // Copy constructor will be used
Hello i = Hello("gello"); // Copy constructor won't be used
Hello k(Hello("gello")); // Copy constructor won't be used

std::cout << h.get() << g.get() << i.get() << k.get() << "\n";
}

If a class is passed by value in a function and return by value from a function
copy constructor will be called. For example:

1
2
3
4
Hello changeHello(Hello h){ // Copy constructor will be called 
h.change("new hello");
return h; // Copy constructor will be called
}

Implicit conversion, explicit and delete keyword

  • explicit keyword can be used to prevent implicit conversion.
  • delete keyword can be used to prevent both implicit and explicit conversion.
  • For details

Overloading assignment operator

  • Can only be oveloaded as memeber function.
  • Watch out for self assignment.
  • If no overloaded assignment operator is provided, compiler will do memberwise copy.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <string>

class Hello{
private:
std::string m_s;

public:
Hello(std::string s): m_s(s){}

Hello(const Hello &h): m_s(h.m_s){
std::cout << "Copy constructor called\n";
}

std::string get(void){return m_s;}

Hello& operator= (const Hello &h){
// If self copying
if(this == &h)
return *this; // for chainig

m_s = h.m_s;

return *this; // for chaining
}
};

int main(int argc, char *argv[]){
Hello h("hello");
Hello i("iello");
Hello j("jello");
Hello k(h); // Copy constructor is called

j = i = h; // Overloaded function is called

std::cout << h.get() << i.get() << j.get() << k.get() << "\n";
}

Shallow copy VS Deep copy

  • Shallow copy means memberwise copying by the compiler if no copy constructor or overloaded assingment operator is provided.
  • The default copy constructor and default assignment operators do shallow copies, which is fine for classes that contain no dynamically allocated variables.
  • Classes with dynamically allocated variables need to have a copy constructor and assignment operator that do a deep copy.

Object Relationship

Composition and Aggregation

In both cases relationship between parent and child is ‘has a’.

Composition

  • The part (member) is part of the object (class)

  • The part (member) can only belong to one object (class) at a time

  • The part (member) has its existence managed by the object (class)

  • The part (member) does not know about the existence of the object (class)

  • Typically use normal member variables

  • Can use pointer members if the class handles object allocation/deallocation itself

  • Responsible for creation/destruction of parts

Aggregation

  • The part (member) is part of the object (class)

  • The part (member) can belong to more than one object (class) at a time

  • The part (member) does not have its existence managed by the object (class)

  • The part (member) does not know about the existence of the object (class)

  • Typically use pointer or reference members that point to or reference objects that live outside the scope of the aggregate class

  • Not responsible for creating/destroying parts

Association

  • The associated object (member) is otherwise unrelated to the object (class)
  • The associated object (member) can belong to more than one object (class) at a time
  • The associated object (member) does not have its existence managed by the object (class)
  • The associated object (member) may or may not know about the existence of the object (class)

Dependencies

A dependency occurs when one object invokes another object’s functionality in order to accomplish some specific task.
This is a weaker relationship than an association, but still,
any change to object being depended upon may break functionality in the (dependent) caller.
A dependency is always a unidirectional relationship.

Container Classes

Hold and organize multiple instance of another type(class or fundamental type).

std::initializer_list

Used in container class’s constructor for list initialization.

Inheritance

Order of construction

Most base class constructed first and most derived class constructed last.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

class Parent{
public:
Parent(){
std::cout << "A" << "\n";
}
};

class Child: public Parent{
public:
Child(){
std::cout << "B" << "\n";
}
};

int main(int argc, char *argv[]){
Child c;
return 0;
}

/*
* Will print:
* A
* B
*/

When a derived class is instanciated following things happen in order:

  • Memory for derived is set aside (enough for both the Base and Derived portions)
  • The appropriate Derived constructor is called
  • The Base object is constructed first using the appropriate Base constructor. If no base constructor is specified, the default constructor will be used.
  • The initialization list initializes variables
  • The body of the constructor executes
  • Control is returned to the caller

Constructors and initialization of derived classes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>

class Parent{
public:
int m_x;

Parent(int x=0): m_x(x){
std::cout << "A" << "\n";
}
};

class Child: public Parent{
public:
int m_y;

// Parent will be initialized with defautl vlaue
Child(int y=0): m_y(y){
std::cout << "B" << "\n";
}

// Parent will be initialized with given value
Child(int x, int y): Parent(x), m_y(y){
std::cout << "B" << "\n";
}
};

int main(int argc, char *argv[]){
// Parent's default constructor will be called
Child c(10);

// Parent will be initialized with given value
Child d(20, 10);

// Will print
// Parent 0
// Child 10
std::cout << "Parent " << c.m_x << "\nChild " << c.m_y << "\n";

// Will print
// Parent 20
// Child 10
std::cout << "Parent " << d.m_x << "\nChild " << d.m_y << "\n";

return 0;
}

When Child d(10, 20) is called following things happended:

  • Memory for Child is allocated.
  • The Child(int, int) constructor is called, where x = 10, and y = 20
  • The compiler looks to see if we’ve asked for a particular Base class constructor. We have! So it calls Parent(int) with x = 10.
  • The base class constructor initialization list sets m_x to 10
  • The base class constructor body executes, which prints A
  • The base class constructor returns
  • The derived class constructor initialization list sets m_y to 20
  • The derived class constructor body executes, which prints B
  • The derived class constructor returns

Order of Destruction

Destructors are called in reverse order of construction.

Inheritance and Access Specifiers

  • public: Can be accessed by anybody.
  • protected: Can be accessed by class member functions, friend functions and derived classes.
  • private: Can be accessed by only class member functions and friend functions.

A summary of the behavious when inherited publicly, protectedly or privately:

Access Specifier in Base Class Inherited Publicly Inherited Protectedly Inherited Privately
public public protected private
protected protected protected private
private inaccessible inaccessible inaccessible

Overriding Behavior

Redefining

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>

class Base{
public:
Base(){}

void identify(void){
std::cout << "I am base\n";
}
};

class Derived: public Base{
public:
Derived(){}

void identify(void){
std::cout << "I am derived\n";
}
};

int main(int argc, char *argv[]){
Derived d;

// Will print I am derived
d.identify();

return 0;
}
  • Redefined functions doesn’t inherite access specification from parent.

Expanding Existing Functionality

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

class Base{
public:
Base(){}

void identify(void){
std::cout << "I am base\n";
}
};

class Derived: public Base{
public:
Derived(){}

void identify(void){
// if scope isn't used Derived::identify() will be called
Base::identify();
std::cout << "I am derived\n";
}
};

int main(int argc, char *argv[]){
Derived d;

// Will print
// I am base
// I am derived
d.identify();

return 0;
}

Changing an Inherited Member’s Access Specification

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

class Base{
public:
Base(){}

protected:
// Only membes, friends and derived class can call
void identify(void){
std::cout << "I am base\n";
}
};

class Derived: public Base{
public:
Derived(){}

// Base::identify() is now public
using Base::identify;
};

int main(int argc, char *argv[]){
Base b;
Derived d;

// Error: can't call from here
b.identify();

// OK: as it is public in Derived class
d.identify();

return 0;
}

Functionality can be hidden by making it private in derived class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

class Base{
public:
Base(){}

void identify(void){
std::cout << "I am base\n";
}
};

class Derived: public Base{
public:
Derived(){}

private:
// Base::identify() is now private
using Base::identify;
};

int main(int argc, char *argv[]){
Base b;
Derived d;

// OK: as it is public in Base class.
b.identify();

// OK: as it is public in Derived class
d.identify();

return 0;
}

Multiple Inheritance

  • Ambiguity can arise.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>

class USBDevice
{
private:
long m_id;

public:
USBDevice(long id)
: m_id(id)
{
}

long getID() { return m_id; }
};

class NetworkDevice
{
private:
long m_id;

public:
NetworkDevice(long id)
: m_id(id)
{
}

long getID() { return m_id; }
};

class WirelessAdapter: public USBDevice, public NetworkDevice
{
public:
WirelessAdapter(long usbId, long networkId)
: USBDevice(usbId), NetworkDevice(networkId)
{
}
};

int main()
{
WirelessAdapter c54G(5442, 181742);
std::cout << c54G.getID(); // Which getID() do we call?

// Can be solved using scope
std::cout << c54G.USBDevice::getID();

return 0;
}
  • Diamond problem

Virtual Functions

Pointers to the Base Class of Derived Object

It is possible to create pointers to the base class of derived object.
But the pointers won’t be able to call member functions from the derived
class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

class Base{
public:
Base(){}

void identify(void){
std::cout << "I am base\n";
}
};

class Derived: public Base{
public:
Derived(){}

void identify(void){
std::cout << "I am derived\n";
}
};

int main(int argc, char *argv[]){
Derived *pd = new Derived();
// Pointer to base of derived object
Base *pb{pd};

// Will call Derived::indentify()
pd->identify();

// Will call Base::identify()
pb->identify();

return 0;
}

Use case for this could be in functions which takes derived class as parameter.
For each derived class a different functions have to be created. For example:

1
2
3
4
5
6
7
void report(Derived &d){
d.identify();
}

void report(AnotherDerived &ad){
ad.identify();
}

This problem can be solved using pointer/reference to base:

1
2
3
4
5
6
7
8
9
10
11
void report(Base &b){
b.identify();
}

int main(int argc, char *argv[]){
Derived d;
AnotherDerived ad;

report(d);
report(ad);
}

But the problem is in both cases Base::identify() will be called.
As pointer to base only can see memebers from base. This problem
can be solved using virtual functions.

Polymorphism

A virtual function is a special type of function that, when called,
resolves to the most-derived version of the function that exists between the base and derived class.
This capability is known as polymorphism. A derived function is considered a match if it has the same signature
(name, parameter types, and whether it is const) and return type as the base version of the function.
Such functions are called overrides.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>

class Base{
public:
Base(){}

virtual void identify(void){
std::cout << "I am base\n";
}
};

class Derived: public Base{
public:
Derived(){}

void identify(void){
std::cout << "I am derived\n";
}
};

class AnotherDerived: public Derived{
public:
AnotherDerived(){}

void identify(void){
std::cout << "I am another derived\n";
}
};

int main(int argc, char *argv[]){
AnotherDerived ad;
Base *bp = &ad;

// Both resolve to AnotherDerived::identify()
ad.identify();
bp->identify();

Derived d;
bp = &d;

// Resolve to Derived::identity() as it is the most derived class in this case
bp->identify();

return 0;
}

Another example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <string>

class Base{
public:
Base(){}

virtual std::string getName(void) const {return "Base";}
};

class Derived: public Base{
public:
Derived(){}

virtual std::string getName(void) const {return "Derived";}
};

class AnotherDerived: public Derived{
public:
AnotherDerived(){}

virtual std::string getName(void) const {return "AnotherDerived";}
};

void report(Base &b){
std::cout << "I am " << b.getName() << "\n";
}

int main(int argc, char *argv[]){
Derived d;
AnotherDerived ad;

report(d);
report(ad);

return 0;
}

If you want to call functions from base class in virtual function just use
scope operator:

1
2
3
4
Derived d;
Base *bp = &d;

std::cout << bp->Base::getName() << "\n";
  • Return type have to match between virtual functions.
  • Never use virtual function in constructors and destructors.

override and final Specifiers

A derived virtual function is only considered override if
functino signature and return type matches exactly between
the virtual functions. override specifier enforces virtualization of a function.
If signature and return type doesn’t match the compiler will
generate an error. If override is used, no need to specify
virtual keyword.

Covariant Return Type

Destructors

In case of inheritance destructors should
always make virtual. Specially if there is
dynamically allocated memory involved. If
a derived class is converted to a base class
and then call delete, only base destructor will
be called. If dynamic memory is allocated in
derived class, this will leak memory.

Abstract Class, Pure Virtual Functions and Interface Class

Abstract class is a class wich is only used by the derived class. It can’t be
instantiated anywhere else.

A pure virtual function has no body at all. It is meant to be redefined in derived classes.
A class with pure virtual functions is an abstract class means it can’t be intantiated.
A pure virtual function may or may not have a body.

1
virtual void doSomething() = 0

In interface class has no member variables. All the functions are pure virtual.

Virtual Base Class

  • Single Base class is shared by the derived classes.
  • Solves diamond problem.
  • Most derived class is responsible for constructing the virtual base class.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>

class PoweredDevice
{
public:
PoweredDevice(int power)
{
std::cout << "PoweredDevice: " << power << '\n';
}
};

class Scanner: virtual public PoweredDevice // note: PoweredDevice is now a virtual base class
{
public:
Scanner(int scanner, int power)
: PoweredDevice{ power } // this line is required to create Scanner objects, but ignored in this case
{
std::cout << "Scanner: " << scanner << '\n';
}
};

class Printer: virtual public PoweredDevice // note: PoweredDevice is now a virtual base class
{
public:
Printer(int printer, int power)
: PoweredDevice{ power } // this line is required to create Printer objects, but ignored in this case
{
std::cout << "Printer: " << printer << '\n';
}
};

class Copier: public Scanner, public Printer
{
public:
Copier(int scanner, int printer, int power)
: PoweredDevice{ power }, // PoweredDevice is constructed here
Scanner{ scanner, power }, Printer{ printer, power }
{
}
};

Object Slicing

1
2
3
4
5
6
7
8
9
10
Derived d;
Base b(d); // b will get the Base part from d. It is called object slicing

// Will call Base::doSomething() even if it is a virtual function
b.doSomething()

Base &b(d);

// Will call Derived::doSomething if it is a virtual function as b in reference to d
bp->doSomething()
  • In general avoid slicing

std::reference_wrapper

Dynamic Casting

Dynamic casing is used for downcasting.

Workaround for Friend Functions

Only member functions can be virtualized. So friend functions
can’t be virtualized. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
class Base
{
public:
Base() {}

// Here's our overloaded operator<<
friend std::ostream& operator<<(std::ostream &out, const Base &b)
{
// Delegate printing responsibility for printing to member function print()
return b.print(out);
}

// We'll rely on member function print() to do the actual printing
// Because print is a normal member function, it can be virtualized
virtual std::ostream& print(std::ostream& out) const
{
out << "Base";
return out;
}
};

class Derived : public Base
{
public:
Derived() {}

// Here's our override print function to handle the Derived case
virtual std::ostream& print(std::ostream& out) const override
{
out << "Derived";
return out;
}
};

int main()
{
Base b;
std::cout << b << '\n';

Derived d;
std::cout << d << '\n'; // note that this works even with no operator<< that explicitly handles Derived objects

Base &bref = d;
std::cout << bref << '\n';

return 0;
}

Templates

Function Template

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

template <typename T>
T add(T x, T y){
return x + y;
}

int main(int argc, char *argv[]){
std::cout << add(1, 2) << "\n";
std::cout << add(1.5, 2.1) << "\n";

return 0;
}

For more than one type:

1
2
3
4
template <typename T1, typename T2>
void doSomething(T1 x, T1 y){

}

Class Template

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>

template <class T>
class Value{
private:
T m_x;

public:
Value(T x): m_x(x){}

T get(void){return m_x;}
};

int main(int argc, char *argv[]){
Value<int> ival(10);
Value<double> dval(10.25);
Value<std::string> sval("hello");

std::cout << "ival: " << ival.get() << " dval: " << dval.get() << " sval: " << sval.get()
<< "\n";
return 0;
}

If template class definition and implementation are splitted into seperate files
linker error can be generated. To solve this following can be done:

  • Definition and implementation in one file.
  • Implementation in *.inl file and #include in *.h file.

For more details

Template Non-Type parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>

template <class T, int size> // size is the non-type parameter
class StaticArray
{
private:
// The non-type parameter controls the size of the array
T m_array[size];

public:
T* getArray();

T& operator[](int index)
{
return m_array[index];
}
};

// Showing how a function for a class with a non-type parameter is defined outside of the class
template <class T, int size>
T* StaticArray<T, size>::getArray()
{
return m_array;
}

int main()
{
// declare an integer array with room for 12 integers
StaticArray<int, 12> intArray;

// Fill it up in order, then print it backwards
for (int count=0; count < 12; ++count)
intArray[count] = count;

for (int count=11; count >= 0; --count)
std::cout << intArray[count] << " ";
std::cout << '\n';

// declare a double buffer with room for 4 doubles
StaticArray<double, 4> doubleArray;

for (int count=0; count < 4; ++count)
doubleArray[count] = 4.4 + 0.1*count;

for (int count=0; count < 4; ++count)
std::cout << doubleArray[count] << ' ';

return 0;
}

Template Specialization

If an exception is needed to make for an specific type.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <string>
#include <cstring>

char str[100];

template <class T>
T add(T x, T y){
return x + y;
}

// If it is an const char*
template<>
const char *add(const char *s1, const char *s2){
strcat(str, s1);
strcat(str, s2);
return str;
}

int main(int argc, char *argv[]){
std::cout << add(1, 2) << "\n";
std::cout << add(1.5, 2.2) << "\n";
std::cout << add("hello", "world") << "\n";
return 0;
}

Standard Template Library

Appendix A: Some Usefull Functions

  • decltype(s) - Query the type of s

INDEX

  1. File I/O
    1. High Level Access
    2. Error Handling
    3. Low Level Access
  2. User Defined Types
    1. Structure
    2. Union
    3. Enumerated Types
    4. Bit Fields
    5. Typedefs

FILE I/O

High Level Access

1
#include <stdio.h>	/* Header files for the bellow functions */
1
FILE* fopen(char *fileName, char *mode);

Returns a FILE pointer associated with the file name or NULL if error occurs. Modes are r(read), w(write), a(append).
There are three special file pointer; stdin(standard input), stdout(standard output), stderr(standard error).

1
int getc(FILE *filePointer);

Returns next character from the file stream referred to by filePointer. It returns EOF if end of file or error occurs.

1
int putc(int c, FILE *filePointer);

Writes character c to the file referred to by filePointer. Retuens the character written or EOF if error occurs.

1
2
int fprintf(FILE *filePointer, char *format, ...);
int fscanf(FILE *filePointer, char *format, ...);

For formatted input / output of files

1
char *fgets(char *line, int MAX_CHAR, FILE *filePointer);

Reads the next line from the file referred to by filepointer into char array line. MAX_CHAR - 1 characters will be read.
Returns pointer to the line or NULL if EOF or error occurs.

1
int fputs(char *line, FILE *filePointer);

Writes a string to a file. Returns EOF if error occurs, zero otherwise.

1
int remove(const char *fileName);

Removes fileName from file system. Returns non zero if attempt fails

1
int rename(const char *oldFileName, const char *newFileName);

Rename oldFileName to newFileName. Returns non zero if attempt fails.

1
FILE* tmpfile(void);

Creates a temporary file of mode wb+. It will be removed automatically when the file is closed.

1
int fclose(FILE *filePointer);

Closes a file.

Error Handling

1
2
int ferror(FILE *filePointer);	/* Returns non zero if an error occurs */
int feof(FILE *filePointer); /* Return non zero if eof occurs */
1
void perror(FILE *filePointer, chars *s);

Prints interactive error message to filePointer if no argument specified Or s.

Low Level Access

1
#include <fcntl.h>	/* Header file for the bellow functions */
1
int open(char *name, int flags, int perms);

Returns an integer associated with the file, which is called a file descriptor.
When shell runs a program three files are open automatically the standard input, standard output and standard error.
Their associated file descriptors are 0, 1 & 2.

Here are some flags:

1
2
3
O_RDONLY - Open file in read only mode
O_WRONLY - Open file in write only mode
O_RDWR - Open file in read / write mode

Perm is the unix file permission specified as a 3 digit octal.

1
int create(char *name, int perms);

Creates a file using name and returns a file descriptor associated with it. Returns -1 if fails.

1
#include <unistd.h>		/* Header file for the bellow functions */
1
int read(int fileDescriptor, char *buffer, int n);

Reads n bytes from a file associated with fileDescriptor into buffer array. Returns number of bytes transferred.
A return value of zero indicates EOF and -1 indicates an error.

1
int write(int fileDescriptor, char *buffer, int n);

Writes n bytes from buffer array to a file associated with fileDescriptor. It returns number of bytes written.

1
long lseek(int fileDescriptor, long offset, int origin);

Set the current position of the file to offset which is taken relative to the location specified by origin.
Orgigin can be 0, 1 or 2 to specify that offset is to be measured from the begaining, current position or end of the file.

1
int unlink(const char *path);

Removes a file. Returns 0 upon success otherwise -1.

1
int close(int fileDescriptor);

Closes a file.


User Defined Types

Structure

Creating a structure:

1
2
3
4
5
struct packet{
int size;
double length;
double breadth;
};

Usage:

1
2
3
4
5
6
7
8
/* structure variable */
struct packet p;
p.size = 50;

/* structure pointer */
struct packet *p;
p = (struct packet *)malloc(sizeof(struct packet));
p->size = 100;

Union

Same as structure but the fields share memory.
All the fields in the union has the same address in memory. Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

typedef const unsigned char *byte_ptr;

void show_bytes(byte_ptr bytes, int size);

int main(int argc, char *argv[]) {
union S {
uint32_t w;
uint16_t hw;
uint8_t b;
};

union S data = {0xABCDEF12};
show_bytes((unsigned char *)&data.w, sizeof(uint32_t));
show_bytes((unsigned char *)&data.hw, sizeof(uint16_t));
show_bytes((unsigned char *)&data.b, sizeof(uint8_t));

// print address of the fields
printf("S.w -- > %p\n", &data.w);
printf("S.hw -- > %p\n", &data.hw);
printf("S.b -- > %p\n", &data.b);
return 0;
}

void show_bytes(byte_ptr bytes, int size) {
for(int i = 0; i < size; i++) {
printf(" %.2x", bytes[i]);
}

printf("\n");
}

Output(Bytes are reversed as this is tested in little endian machine):

1
2
3
4
5
6
12 ef cd ab
12 ef
12
S.w --> 0x7ffee41bda70
S.hw --> 0x7ffee41bda70
S.b --> 0x7ffee41bda70

Enumerated Types

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
enum Type{
INT, // INT = 0
DOUBLE, // DOUBLE = 1
CHAR // CHAR = 2
};

int main(){
/* Can be treated like regular variable */
enum Type t;

/* Value assignment can be one of the enum members */
t = INT;

/* Can be used directly without a enumerated variable */
if(t == INT){
printf("This is an integer.\n");
}
else if(t == DOUBLE){
printf("This is a double.\n");
}
else if(t == CHAR){
printf("This is a character variable.\n");
}

return 0;
}

Bit Fields

Bit field is used to pack several variables into a machine word. Bit fields are declared just like regular structures. But variable type have to be unsigned int and bit length of each variable is specified using : operator.

1
2
3
4
5
6
struct flags{
unsigned int is_color:1 // 1 bit length
unsigned int is_sound:1 // 1 bit length
unsigned int is_open:1 // 1 bit length
unsigned int status:4 // 4 bit length
};

Typedefs

Typedefs are used to give an alias for a type.Structure:

1
typedef TYPE ALIAS

Example:

1
typedef double dist_t; // dist_t can be used instead of double
0%