Commit 33635dbe authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

Minor corrections done while proof-reading the lecture.

parent ce2a5787
......@@ -89,29 +89,9 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[1minput_line_11:3:16: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mexpected ';' at end of declaration\u001b[0m\n",
" int foo = 5 // COMPILATION ERROR!\n",
"\u001b[0;1;32m ^\n",
"\u001b[0m\u001b[0;32m ;\n",
"\u001b[0m"
]
},
{
"ename": "Interpreter Error",
"evalue": "",
"output_type": "error",
"traceback": [
"Interpreter Error: "
]
}
],
"outputs": [],
"source": [
"{\n",
" int foo = 5 // COMPILATION ERROR!\n",
......@@ -120,7 +100,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
......@@ -138,7 +118,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
......@@ -170,7 +150,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
......@@ -180,31 +160,9 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[1minput_line_17:2:6: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mredefinition of 'i'\u001b[0m\n",
" int i = 1; // If the cell above was run, compilation error as `i` is al...\n",
"\u001b[0;1;32m ^\n",
"\u001b[0m\u001b[1minput_line_16:2:6: \u001b[0m\u001b[0;1;30mnote: \u001b[0mprevious definition is here\u001b[0m\n",
" int i = 2; // Should be fine on the first call. But if you have execute...\n",
"\u001b[0;1;32m ^\n",
"\u001b[0m"
]
},
{
"ename": "Interpreter Error",
"evalue": "",
"output_type": "error",
"traceback": [
"Interpreter Error: "
]
}
],
"outputs": [],
"source": [
"int i = 1; // If the cell above was run, compilation error as `i` is already defined."
]
......@@ -219,7 +177,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
......@@ -230,7 +188,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
......@@ -245,33 +203,14 @@
"source": [
"### Input / output\n",
"\n",
"Inputs and outputs aren't directly a part of the language itself, but are in the standard library (often abbreviated as STL for Standard Template Library even if some purist may well and explain it's not 100 % the same thing...). You therefore need to __include__ a file named `iostream`; doing so will enable the use of the input / output facilities."
"Inputs and outputs aren't directly a part of the language itself, but are in the standard library (often abbreviated as STL for Standard Template Library even if some purist may yell and explain it's not 100 % the same thing...). You therefore need to __include__ a file named `iostream`; doing so will enable the use of the input / output facilities."
]
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[1minput_line_26:3:10: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mno member named 'cout' in namespace 'std'\u001b[0m\n",
" std::cout << \"Hello world!\" << std::endl; // Should fail (unless yo...\n",
"\u001b[0;1;32m ~~~~~^\n",
"\u001b[0m"
]
},
{
"ename": "Interpreter Error",
"evalue": "",
"output_type": "error",
"traceback": [
"Interpreter Error: "
]
}
],
"outputs": [],
"source": [
"{\n",
" std::cout << \"Hello world!\" << std::endl; // Should fail (unless you run a cell that includes iostream before)\n",
......@@ -280,17 +219,9 @@
},
{
"cell_type": "code",
"execution_count": 21,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello world!\n"
]
}
],
"outputs": [],
"source": [
"#include <iostream>\n",
"\n",
......@@ -303,7 +234,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"- `std::cout` is the symbol to designate the standard output\n",
"- `std::cout` is the symbol to designate the standard output (i.e. your screen...)\n",
"- `std::endl` is the symbol to clean-up the stream and go to next line.\n",
"\n",
"The operator `<<` is used to indicate what you direct toward the stream; here std::cout << \"Hello world!\" tells to redirect the string toward the standard output.\n",
......
%% Cell type:markdown id: tags:
# [Getting started in C++](/) - [Getting started with the tutorial](/notebooks/getting_started_with_tutorial.ipynb)
%% Cell type:markdown id: tags:
<h1>Table of contents<span class="tocSkip"></span></h1>
<div class="toc"><ul class="toc-item"><li><span><a href="#About-the-choice-of-a-Jupyter-notebook" data-toc-modified-id="About-the-choice-of-a-Jupyter-notebook-1">About the choice of a Jupyter notebook</a></span></li><li><span><a href="#When-the-notebook-is-not-enough..." data-toc-modified-id="When-the-notebook-is-not-enough...-2">When the notebook is not enough...</a></span></li><li><span><a href="#Few-guidelines-about-Jupyter" data-toc-modified-id="Few-guidelines-about-Jupyter-3">Few guidelines about Jupyter</a></span><ul class="toc-item"><li><span><a href="#Restarting-the-kernel" data-toc-modified-id="Restarting-the-kernel-3.1">Restarting the kernel</a></span></li></ul></li><li><span><a href="#Very-basic-C++-syntax-(in-notebook-and-in-general)" data-toc-modified-id="Very-basic-C++-syntax-(in-notebook-and-in-general)-4">Very basic C++ syntax (in notebook and in general)</a></span><ul class="toc-item"><li><span><a href="#Semicolons" data-toc-modified-id="Semicolons-4.1">Semicolons</a></span></li><li><span><a href="#Blocks" data-toc-modified-id="Blocks-4.2">Blocks</a></span></li><li><span><a href="#Input-/-output" data-toc-modified-id="Input-/-output-4.3">Input / output</a></span></li></ul></li></ul></div>
%% Cell type:markdown id: tags:
## About the choice of a Jupyter notebook
This notebook uses up [xeus-cling](https://xeus-cling.readthedocs.io/en/latest/), a special instance of Jupyter able to run C++ code based upon xeus (tool to build Jupyter kernels for any language) and cling (a creation from CERN to be able to run C++ as an interpreted language).
The reasons for these choices is to really access directly to handle C++ code without the hassle of explaining how to compile and run stuff, which is an especially cumbersome way to start with this (or any really...) language.
This is not to say this tutorial will ignore entirely these topics (see the dedicated [chapter](/notebooks/6-InRealEnvironment/0-main.ipynb), just that we will first focus on C++ code. However keep in mind that this notebook's fancy interpreter is not a typical C++ environment.
Jupyter Xeus-Cling is still under active development: you should really get a recent version and keep it up-to-date. Some examples in this lecture didn't work at first and were properly dealt with with a version one month later!
## When the notebook is not enough...
As we shall see repeatedly, Xeus-cling notebooks are far from being full-proof: some stuff that are perfectly acceptable C++ aren't accepted in them, and some others required work-arounds. When such an issue appears:
* It will be indicated explicitly in the notebook if a specific work around is used. We do not want you to take Jupyter work-arounds as a legit advice on how to write proper C++.
* If Jupyter can't deal with the code, we will use [Coliru](https://coliru.stacked-crooked.com/). Coliru is a C++ online compiler; others are listed [here](https://arne-mertz.de/2017/05/online-compilers/) ([Wandbox](https://wandbox.org/) deserves a shout out as it enables testing the same code with a great variety of compiler versions).
%% Cell type:markdown id: tags:
## Few guidelines about Jupyter
You might not be familiar with Jupyter notebooks, so here are few tips to run it smoothly (the _Help_ menu will help you find more if you need it).
In a Jupyter notebook the content is divided into _cells_, in our case we are using two kind of cells:
* Markdown cells, such as the ones into these very words are written.
* Code cells, which are running code. In these notebooks the chosen kernel is C++17, so the code is C++17 which is interpreted by cling.
There are two modes:
* Edit mode, in which you might change the content of a cell. In this mode the left part of the cell is in green.
* Command mode, in which you might take actions such as changing the type of a cell, create or delete a new one, etc...
To enter in edit mode, simply type on 'Enter'.
To enter in command mode, type 'Esc'.
To execute a cell, type 'Shift + Enter'. For a markdown cell it will edit nicely the content by interpreting the markdown, and for a code cell it will run the code.
In command mode, several handy shortcuts are there; I would recommend especially:
* `a` (add a cell above)
* `b` (add a cell below)
* `x` (cut a cell)
* `M` (change cell mode to Markdown)
The complete list is available in _Help_ > _Keyboard_ shortcut.
If for some reason the code in the notebook seems stuck, you might try to restart the kernel with one of the restart option in the _Kernel_ menu.
### Restarting the kernel
Sometimes something that should work doesn't... In this case try restarting the kernel: it might fix your issue!
%% Cell type:markdown id: tags:
## Very basic C++ syntax (in notebook and in general)
### Semicolons
In C++ most instructions end by a semicolon `;`. If you forget it, the underlying compiler doesn't understand the syntax.
%% Cell type:code id: tags:
``` C++17
{
int foo = 5 // COMPILATION ERROR!
}
```
%%%% Output: stream
input_line_11:3:16: error: expected ';' at end of declaration
int foo = 5 // COMPILATION ERROR!
 ^
 ;

%%%% Output: error
Interpreter Error:
%% Cell type:code id: tags:
``` C++17
{
int foo = 5; // OK
}
```
%% Cell type:markdown id: tags:
Spaces, end lines and tabulations act as word separators; utterly unreadable code as the one below is perfectly fine from the compiler standpoint:
%% Cell type:code id: tags:
``` C++17
# include <string>
{
int nombre ; nombre = 1
; std::string nom;
nom=
"truc" ;
nombre = 2
;
}
```
%% Cell type:markdown id: tags:
### Blocks
You may have notices the braces `{` and `}` in the examples above. They are here a technicality to make cling interpreter work better in a Jupyter environment, but that is also useful in a real C++ code.
What is between both braces constitute a **block**; variables that are initialized inside are destroyed once the closing brace is past (don't worry - we will come back to that [later](/notebooks/1-ProceduralProgramming/5-DynamicAllocation.ipynb#Stack)).
This is an incredibly useful feature: you may ensure this way that a variable is not kept any longer than necessary. We will come back to this feature (called the **locality of reference** later); let's see why they are useful in a notebook environment.
In C++, at a given scope a same variable can't be defined twice. So for instance if I defined twice a same variable, the compiler will yell about redefinition of a variable:
%% Cell type:code id: tags:
``` C++17
int i = 2; // Should be fine on the first call.
// But if you have executed it already, a new attempt will make the compiler yell.
```
%% Cell type:code id: tags:
``` C++17
int i = 1; // If the cell above was run, compilation error as `i` is already defined.
```
%%%% Output: stream
input_line_17:2:6: error: redefinition of 'i'
int i = 1; // If the cell above was run, compilation error as `i` is al...
 ^
input_line_16:2:6: note: previous definition is here
int i = 2; // Should be fine on the first call. But if you have execute...
 ^

%%%% Output: error
Interpreter Error:
%% Cell type:markdown id: tags:
The only way to circumvent this is to restart the kernel... and you may then run only one of this cell, and only once.
So you might now see the usefulness of the braces: by putting them I define the variables in a cell in a block, and it is only defined inside this block. Same variable may this way be defined in different cells:
%% Cell type:code id: tags:
``` C++17
{
int i = 2; // Fine
}
```
%% Cell type:code id: tags:
``` C++17
{
int i = 1; // Also fine
}
```
%% Cell type:markdown id: tags:
### Input / output
Inputs and outputs aren't directly a part of the language itself, but are in the standard library (often abbreviated as STL for Standard Template Library even if some purist may well and explain it's not 100 % the same thing...). You therefore need to __include__ a file named `iostream`; doing so will enable the use of the input / output facilities.
Inputs and outputs aren't directly a part of the language itself, but are in the standard library (often abbreviated as STL for Standard Template Library even if some purist may yell and explain it's not 100 % the same thing...). You therefore need to __include__ a file named `iostream`; doing so will enable the use of the input / output facilities.
%% Cell type:code id: tags:
``` C++17
{
std::cout << "Hello world!" << std::endl; // Should fail (unless you run a cell that includes iostream before)
}
```
%%%% Output: stream
input_line_26:3:10: error: no member named 'cout' in namespace 'std'
std::cout << "Hello world!" << std::endl; // Should fail (unless yo...
 ~~~~~^

%%%% Output: error
Interpreter Error:
%% Cell type:code id: tags:
``` C++17
#include <iostream>
{
std::cout << "Hello world!" << std::endl; // Should work: std::cout and std::endl are now known.
}
```
%%%% Output: stream
Hello world!
%% Cell type:markdown id: tags:
- `std::cout` is the symbol to designate the standard output
- `std::cout` is the symbol to designate the standard output (i.e. your screen...)
- `std::endl` is the symbol to clean-up the stream and go to next line.
The operator `<<` is used to indicate what you direct toward the stream; here std::cout << "Hello world!" tells to redirect the string toward the standard output.
We will see that a bit more in detail in [a later chapter](/notebooks/1-ProceduralProgramming/6-Streams.ipynb), but printing something is really helpful early on hence this brief introduction here.
%% Cell type:markdown id: tags:
© _CNRS 2016_ - _Inria 2018-2019_
_This notebook is an adaptation of a lecture prepared and redacted by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_
_The present version has been redacted by Sébastien Gilles and Vincent Rouvreau (Inria)_
......
......@@ -41,7 +41,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 2,
"metadata": {},
"outputs": [
{
......@@ -60,7 +60,7 @@
" int number; // integer variable\n",
" double real; // floating-point variable\n",
"\n",
"std::cout << number << std::endl;\n",
" std::cout << number << std::endl; \n",
" std::cout << real << std::endl;\n",
"}\n",
"\n"
......@@ -77,15 +77,14 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Although not mandatory, it is strongly recommended to give a\n",
"Although not mandatory, it is **strongly** recommended to give a\n",
"initial value to your variables, as an expression between brackets. \n",
"\n",
"Not providing an initial value may lead to unexpected behaviour. For instance you can't make hypothesis upon the values of `number` and `real` in the cell above: you might end-up with any value... and someone else might get other values on his computer!\n",
"\n",
"\n",
"If you give braces without values, a predefined and associated value\n",
"to the type is used (usually a form of 0).\n",
"If you give nothing , the behaviour is undefined: you might end up with a 0-like value or something"
"to the type is used (usually a form of 0)."
]
},
{
......@@ -97,7 +96,7 @@
"{\n",
" int nb1 { 1 }; // integer variable set with the value 1\n",
" int nb2 {}; // same as int nb2{0};\n",
" double pi { 3.14 } ; // real variable\n",
" double pi { 3.14 }; // real variable\n",
"}"
]
},
......@@ -107,13 +106,13 @@
"source": [
"C++ actually supports many other historical forms\n",
"of initialization, which you will encounter everywhere, including in this tutorial,\n",
"with brackets and/or an equal sign. There are some subtile differences\n",
"with brackets and/or an equal sign. There are some subtle differences\n",
"between each other... that you can ignore most of the time."
]
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
......@@ -175,6 +174,36 @@
"} "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Affectations may be chained:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a = 5, b = 5 and c = 5\n"
]
}
],
"source": [
"{\n",
" int a {}, b {}, c {};\n",
" \n",
" a = b = c = 5; \n",
" \n",
" std::cout << \"a = \" << a << \", b = \" << b << \" and c = \" << c << std::endl;\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
......@@ -184,7 +213,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 5,
"metadata": {},
"outputs": [
{
......@@ -229,7 +258,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 8,
"metadata": {},
"outputs": [
{
......@@ -252,8 +281,7 @@
" a++; // increment a by 1.\n",
" ++a; // same, both are actually equivalents here.\n",
" \n",
" int c = a + b;\n",
" \n",
" int c = a + b; \n",
" std::cout << \"a = \" << a << \", b = \" << b << \" and c = \" << c << std::endl;\n",
" \n",
" c = a-- + b; // first a + b is evaluated, and only then a is decremented. \n",
......@@ -273,7 +301,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 9,
"metadata": {},
"outputs": [
{
......@@ -281,7 +309,7 @@
"output_type": "stream",
"text": [
"a = 7, b = 3 and c = 10\n",
"a = 6, b = 3 and c = 9\n",
"a = 6, b = 3 and c = 10\n",
"a = 6, b = 4 and c = 10\n"
]
}
......@@ -295,17 +323,14 @@
"\n",
" int c = a + b;\n",
" std::cout << \"a = \" << a << \", b = \" << b << \" and c = \" << c << std::endl;\n",
" \n",
" --a; // equivalent to a-- but for reasons related to the standard library I advise you to rather use the\n",
" // pre-increment form.\n",
" \n",
" c = a + b; // first a + b is evaluated, and only then a is decremented. \n",
" \n",
" c = a + b;\n",
" --a; // equivalent to a-- but for reasons related to the standard library I advise you \n",
" // to rather use the pre-increment form when both are equivalent.\n",
" std::cout << \"a = \" << a << \", b = \" << b << \" and c = \" << c << std::endl;\n",
" \n",
" \n",
" ++b; // same: equivalent to b++;\n",
" \n",
" c = a + b; // first a is incremented, and only then a + b is evaluated.\n",
" \n",
" ++b; // same: equivalent to b++; \n",
" c = a + b;\n",
" std::cout << \"a = \" << a << \", b = \" << b << \" and c = \" << c << std::endl;\n",
"}"
]
......@@ -404,7 +429,7 @@
"in this case we use the pointer name directly, or we want to modify the variable\n",
"pointed, in which case the name is prefixed with `*`.\n",
"\n",
"We can therefore see the pointer as a kind of redefinable reference."
"We can therefore see the pointer as a kind of redefinable reference; pointers are a feature from C language."
]
},
{
......@@ -477,7 +502,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 10,
"metadata": {},
"outputs": [
{
......@@ -491,7 +516,7 @@
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[1minput_line_16:4:62: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1mnull passed to a callee that requires a non-null argument [-Wnonnull]\u001b[0m\n",
"\u001b[1minput_line_24:4:62: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1mnull passed to a callee that requires a non-null argument [-Wnonnull]\u001b[0m\n",
" std::cout << \"\\t p: address = \" << p << \", value = \" << *p << std::endl; // Dereferencing p is misguided!\n",
"\u001b[0;1;32m ^\n",
"\u001b[0m"
......@@ -562,7 +587,7 @@
"{\n",
" const double pi = 3.1415927;\n",
" double const pi_2 = 3.1415927; // equally valid; it is just a matter of taste. Mine is to put it before,\n",
" // so that is what you will see in the remaining of the tutorial.\n",
" // so that is what you will see in the remaining of the lecture.\n",
" pi = 5.; // COMPILATION ERROR!\n",
" pi_2 = 7.; // COMPILATION ERROR!\n",
"}"
......@@ -577,7 +602,7 @@
},
{
"cell_type": "code",
"execution_count": 35,
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
......@@ -592,17 +617,17 @@
},
{
"cell_type": "code",
"execution_count": 39,
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[1minput_line_74:6:7: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mcannot assign to variable 'p' with const-qualified type 'int *const'\u001b[0m\n",
"\u001b[1minput_line_27:6:7: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mcannot assign to variable 'p' with const-qualified type 'int *const'\u001b[0m\n",
" p = &b; // COMPILATION ERROR - if you comment it it will \n",
"\u001b[0;1;32m ~ ^\n",
"\u001b[0m\u001b[1minput_line_74:4:16: \u001b[0m\u001b[0;1;30mnote: \u001b[0mvariable 'p' declared const here\u001b[0m\n",
"\u001b[0m\u001b[1minput_line_27:4:16: \u001b[0m\u001b[0;1;30mnote: \u001b[0mvariable 'p' declared const here\u001b[0m\n",
" int* const p { &a }; // Value is modifiable, but not the address pointed to.\n",
"\u001b[0;1;32m ~~~~~~~~~~~^~~~~~~~\n",
"\u001b[0m"
......@@ -629,14 +654,14 @@
},
{
"cell_type": "code",
"execution_count": 40,
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[1minput_line_75:7:8: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mread-only variable is not assignable\u001b[0m\n",
"\u001b[1minput_line_28:7:8: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mread-only variable is not assignable\u001b[0m\n",
" *p = 5; // COMPILATION ERROR \n",
"\u001b[0;1;32m ~~ ^\n",
"\u001b[0m"
......@@ -795,17 +820,17 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[1minput_line_18:7:32: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1marray index 10 is past the end of the array (which contains 10 elements) [-Warray-bounds]\u001b[0m\n",
"\u001b[1minput_line_30:7:32: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1marray index 10 is past the end of the array (which contains 10 elements) [-Warray-bounds]\u001b[0m\n",
" std::cout << \"i[10] = \" << i[10] << \" (undefined behaviour: out of range. Warning identifies the issue)\" << std::endl ;\n",
"\u001b[0;1;32m ^ ~~\n",
"\u001b[0m\u001b[1minput_line_18:3:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0marray 'i' declared here\u001b[0m\n",
"\u001b[0m\u001b[1minput_line_30:3:5: \u001b[0m\u001b[0;1;30mnote: \u001b[0marray 'i' declared here\u001b[0m\n",
" int i[10] ; // Array of 10 integers - not initialised properly!\n",
"\u001b[0;1;32m ^\n",
"\u001b[0m"
......@@ -815,8 +840,8 @@
"name": "stdout",
"output_type": "stream",
"text": [
"i[2] = 149375929 (may be nonsense: undefined behaviour due to lack of initialization!)\n",
"i[10] = -87424866 (undefined behaviour: out of range. Warning identifies the issue)\n",
"i[2] = 50428857 (may be gibberish: undefined behaviour due to lack of initialization!)\n",
"i[10] = -2038759403 (undefined behaviour: out of range. Warning identifies the issue)\n",
"x[1] = 2 (expected: 2.)\n"
]
}
......@@ -843,7 +868,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 16,
"metadata": {},
"outputs": [
{
......@@ -891,7 +916,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 17,
"metadata": {},
"outputs": [
{
......
%% Cell type:markdown id: tags:
# [Getting started in C++](/) - [Procedural programming](/notebooks/1-ProceduralProgramming/0-main.ipynb) - [Predefined types](/notebooks/1-ProceduralProgramming/1-Variables.ipynb)
%% Cell type:markdown id: tags:
<h1>Table of contents<span class="tocSkip"></span></h1>
<div class="toc"><ul class="toc-item"><li><span><a href="#Ordinary-variables" data-toc-modified-id="Ordinary-variables-1">Ordinary variables</a></span><ul class="toc-item"><li><span><a href="#Declaration" data-toc-modified-id="Declaration-1.1">Declaration</a></span></li><li><span><a href="#Initialisation" data-toc-modified-id="Initialisation-1.2">Initialisation</a></span></li><li><span><a href="#Affectation" data-toc-modified-id="Affectation-1.3">Affectation</a></span></li><li><span><a href="#Increment-and-decrement-operators" data-toc-modified-id="Increment-and-decrement-operators-1.4">Increment and decrement operators</a></span></li><li><span><a href="#Comparing-values" data-toc-modified-id="Comparing-values-1.5">Comparing values</a></span></li></ul></li><li><span><a href="#References" data-toc-modified-id="References-2">References</a></span></li><li><span><a href="#Pointers" data-toc-modified-id="Pointers-3">Pointers</a></span><ul class="toc-item"><li><span><a href="#nullptr" data-toc-modified-id="nullptr-3.1"><code>nullptr</code></a></span></li></ul></li><li><span><a href="#Constant-variables-and-pointers" data-toc-modified-id="Constant-variables-and-pointers-4">Constant variables and pointers</a></span></li><li><span><a href="#Arrays" data-toc-modified-id="Arrays-5">Arrays</a></span><ul class="toc-item"><li><span><a href="#Arrays-and-pointers" data-toc-modified-id="Arrays-and-pointers-5.1">Arrays and pointers</a></span></li></ul></li></ul></div>
%% Cell type:markdown id: tags:
## Ordinary variables
%% Cell type:markdown id: tags:
### Declaration
%% Cell type:markdown id: tags:
To be usable in a C++ program, a variable must be declared. This declaration shall include at least the type of
the variable, followed by its name and a semicolon.
%% Cell type:code id: tags:
``` C++17
#include <iostream>
{
int number; // integer variable
double real; // floating-point variable
std::cout << number << std::endl;
std::cout << number << std::endl;
std::cout << real << std::endl;
}
```
%%%% Output: stream
32766
1.37345e-70
%% Cell type:markdown id: tags:
### Initialisation
%% Cell type:markdown id: tags:
Although not mandatory, it is strongly recommended to give a
Although not mandatory, it is **strongly** recommended to give a
initial value to your variables, as an expression between brackets.
Not providing an initial value may lead to unexpected behaviour. For instance you can't make hypothesis upon the values of `number` and `real` in the cell above: you might end-up with any value... and someone else might get other values on his computer!
If you give braces without values, a predefined and associated value
to the type is used (usually a form of 0).
If you give nothing , the behaviour is undefined: you might end up with a 0-like value or something
%% Cell type:code id: tags:
``` C++17
{
int nb1 { 1 }; // integer variable set with the value 1
int nb2 {}; // same as int nb2{0};
double pi { 3.14 } ; // real variable
double pi { 3.14 }; // real variable
}
```
%% Cell type:markdown id: tags:
C++ actually supports many other historical forms
of initialization, which you will encounter everywhere, including in this tutorial,
with brackets and/or an equal sign. There are some subtile differences
with brackets and/or an equal sign. There are some subtle differences
between each other... that you can ignore most of the time.
%% Cell type:code id: tags:
``` C++17
{
int a = 5;
int b(5);
int c = { 5 };
}
```
%% Cell type:markdown id: tags:
In all cases, even if there is an equal sign, it is important to remember
that it is an initialization, not an assignment (this will be
important when we will define our own types).
%% Cell type:markdown id: tags:
### Affectation
A new value is stored in an existing variable using the operator
of assignment `=`. The name of the variable is on the left; the expression
on the right of the `=` sign is evaluated, and its result is assigned to the variable.
%% Cell type:code id: tags:
``` C++17
#include <iostream> // for std::cout and std::endl
{
int a {}, b {}, c {} ; // default initialization; set the values to 0
std::cout << "Default initialization: a = " << a << ", b = " << b << " and c = " << c << std::endl;
a = 4;
b = 7;
c = a + b;
std::cout << "After affectations: a = " << a << ", b = " << b << " and c = " << c << std::endl;
}
```
%%%% Output: stream
Default initialization: a = 0, b = 0 and c = 0
After affectations: a = 4, b = 7 and c = 11
%% Cell type:markdown id: tags:
Affectations may be chained:
%% Cell type:code id: tags:
``` C++17
{
int a {}, b {}, c {};
a = b = c = 5;
std::cout << "a = " << a << ", b = " << b << " and c = " << c << std::endl;
}
```
%%%% Output: stream
a = 5, b = 5 and c = 5
%% Cell type:markdown id: tags:
It is also possible to define (slightly) more advanced operators of assignments that modify the value currently stored by a simple operation:
%% Cell type:code id: tags:
``` C++17
#include <iostream>
{
int a {}, b {}, c {} ; // default initialization; set the values to 0
a += 4; // add 4 to the curre