Attention une mise à jour du service Gitlab va être effectuée le mardi 30 novembre entre 17h30 et 18h00. Cette mise à jour va générer une interruption du service dont nous ne maîtrisons pas complètement la durée mais qui ne devrait pas excéder quelques minutes. Cette mise à jour intermédiaire en version 14.0.12 nous permettra de rapidement pouvoir mettre à votre disposition une version plus récente.

Commit 801042ae authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

Re-reading in progress (and adding new stuff in the process...).

parent 5cc2a2a5
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# [Getting started in C++](/) - [Getting started with the tutorial](/notebooks/getting_started_with_tutorial.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"toc": true
},
"source": [
"<h1>Table of contents<span class=\"tocSkip\"></span></h1>\n",
"<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",
"metadata": {},
......@@ -10,7 +27,14 @@
"\n",
"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.\n",
"\n",
"This is not to say this tutorial will ignore entirely these topics, 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."
"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.\n",
"\n",
"## When the notebook is not enough...\n",
"\n",
"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:\n",
"\n",
"* 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++.\n",
"* 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).\n"
]
},
{
......@@ -19,7 +43,7 @@
"source": [
"## Few guidelines about Jupyter\n",
"\n",
"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).\n",
"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).\n",
"\n",
"In a Jupyter notebook the content is divided into _cells_, in our case we are using two kind of cells:\n",
"* Markdown cells, such as the ones into these very words are written.\n",
......@@ -32,7 +56,7 @@
"To enter in edit mode, simply type on 'Enter'. \n",
"To enter in command mode, type 'Esc'.\n",
"\n",
"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.\n",
"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.\n",
"\n",
"In command mode, several handy shortcuts are there; I would recommend especially:\n",
"* `a` (add a cell above)\n",
......@@ -40,16 +64,20 @@
"* `x` (cut a cell)\n",
"* `M` (change cell mode to Markdown)\n",
"\n",
"The complete list is available in Help > Keyboard shortcut.\n",
"The complete list is available in _Help_ > _Keyboard_ shortcut.\n",
"\n",
"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.\n"
"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.\n",
"\n",
"### Restarting the kernel\n",
"\n",
"Sometimes something that should work doesn't... In this case try restarting the kernel: it might fix your issue!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## C++ syntax (in notebook and in general)\n",
"## Very basic C++ syntax (in notebook and in general)\n",
"\n",
"### Semicolons\n",
"\n",
......@@ -102,7 +130,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Spaces, end lines and tabulations act as word separators; unreadable code as the one below is perfectly fine from the compiler standpoint:"
"Spaces, end lines and tabulations act as word separators; utterly unreadable code as the one below is perfectly fine from the compiler standpoint:"
]
},
{
......@@ -130,7 +158,7 @@
"\n",
"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.\n",
"\n",
"What is between both braces constitute a **block**; variables that are initialized inside are destroyed one the closing brace is past. \n",
"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/6-DynamicAllocation.ipynb#Stack)).\n",
"\n",
"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.\n",
"\n",
......@@ -183,7 +211,7 @@
"metadata": {},
"source": [
"The only way to circumvent this is to restart the kernel... and you may then run only one of this cell, and only once.\n",
"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 in the inside of the block. Same variable may this way be defined in different cells:"
"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:"
]
},
{
......@@ -212,7 +240,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Input / output\n",
"### 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."
]
......@@ -272,11 +300,22 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"`std::cout` is the symbol to designate the standard output\n",
"`std::cerr` is the symbol to designate the error output\n",
"`std::endl` is the symbol to clean-up the stream and go to next line.\n",
"- `std::cout` is the symbol to designate the standard output\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",
"std::cin is a bit trickier to showcase, especially so early in the tutorial, so I'll just skip it and let [this page](http://www.cplusplus.com/doc/tutorial/basic_io/) explain it if you can't wait (I introduced `std::cout` this early because it will be featured heavily in the notebooks)."
"\n",
"We will see that a bit more in detail in [a later chapter](/notebooks/1-ProceduralProgramming/7-Streams.ipynb), but printing something is really helpful early on hence this brief introduction here.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"© _CNRS 2016_ - _Inria 2018_ \n",
"_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/)_ \n",
"_The present version has been redacted by Sébastien Gilles and Vincent Rouvreau (Inria)_"
]
}
],
......@@ -292,6 +331,37 @@
"mimetype": "text/x-c++src",
"name": "c++",
"version": "-std=c++17"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
"autoclose": false,
"autocomplete": true,
"bibliofile": "biblio.bib",
"cite_by": "apalike",
"current_citInitial": 1,
"eqLabelWithNumbers": true,
"eqNumInitial": 1,
"hotkeys": {
"equation": "Ctrl-E",
"itemize": "Ctrl-I"
},
"labels_anchors": false,
"latex_user_defs": false,
"report_style_numbering": false,
"user_envs_cfg": false
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": false,
"sideBar": true,
"skip_h1_title": true,
"title_cell": "Table of contents",
"title_sidebar": "Table of contents",
"toc_cell": true,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": true
}
},
"nbformat": 4,
......
......@@ -14,7 +14,10 @@
"* [Variables, initialisation, affectation](/notebooks/1-ProceduralProgramming/1-Variables.ipynb)\n",
"* [Condition and loops](/notebooks/1-ProceduralProgramming/2-Conditions-and-loops.ipynb)\n",
"* [Predefined types](/notebooks/1-ProceduralProgramming/3-Types.ipynb)\n",
"* [Functions](/notebooks/1-ProceduralProgramming/4-Functions.ipynb)"
"* [Functions](/notebooks/1-ProceduralProgramming/4-Functions.ipynb)\n",
"* [TP 1](/notebooks/1-ProceduralProgramming/5-TP-1.ipynb)\n",
"* [Dynamic allocation](/notebooks/1-ProceduralProgramming/6-DynamicAllocation.ipynb)\n",
"* [Input/output](/notebooks/1-ProceduralProgramming/7-Streams.ipynb)"
]
},
{
......@@ -26,13 +29,6 @@
"_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/)_ \n",
"_The present version has been redacted by Sébastien Gilles and Vincent Rouvreau (Inria)_"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
......@@ -47,6 +43,37 @@
"mimetype": "text/x-c++src",
"name": "c++",
"version": "-std=c++17"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
"autoclose": false,
"autocomplete": true,
"bibliofile": "biblio.bib",
"cite_by": "apalike",
"current_citInitial": 1,
"eqLabelWithNumbers": true,
"eqNumInitial": 1,
"hotkeys": {
"equation": "Ctrl-E",
"itemize": "Ctrl-I"
},
"labels_anchors": false,
"latex_user_defs": false,
"report_style_numbering": false,
"user_envs_cfg": false
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": false,
"sideBar": true,
"skip_h1_title": true,
"title_cell": "Table of contents",
"title_sidebar": "Table of contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": true
}
},
"nbformat": 4,
......
......@@ -7,6 +7,16 @@
"# [Getting started in C++](/) - [Procedural programming](/notebooks/1-ProceduralProgramming/0-main.ipynb) - [Predefined types](/notebooks/1-ProceduralProgramming/1-Variables.ipynb)"
]
},
{
"cell_type": "markdown",
"metadata": {
"toc": true
},
"source": [
"<h1>Table of contents<span class=\"tocSkip\"></span></h1>\n",
"<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",
"metadata": {},
......@@ -25,21 +35,35 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"To be usable in a C++ program, a variable must be\n",
"previously declared. This declaration shall include at least the type of\n",
"To be usable in a C++ program, a variable must be declared. This declaration shall include at least the type of\n",
"the variable, followed by its name and a semicolon."
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 5,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"32766\n",
"1.37345e-70\n"
]
}
],
"source": [
"#include <iostream>\n",
"\n",
"{\n",
" int number; // integer variable\n",
" double real; // floating-point variable\n",
"}"
"\n",
"std::cout << number << std::endl;\n",
" std::cout << real << std::endl;\n",
"}\n",
"\n"
]
},
{
......@@ -54,9 +78,14 @@
"metadata": {},
"source": [
"Although not mandatory, it is strongly recommended to give a\n",
"initial value to your variables, as an expression between brackets.\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)."
"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"
]
},
{
......@@ -78,20 +107,20 @@
"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 differences\n",
"with brackets and/or an equal sign. There are some subtile differences\n",
"between each other... that you can ignore most of the time."
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"{\n",
" int a = 5 ;\n",
" int b(5) ;\n",
" int c = { 5 } ;\n",
" int a = 5;\n",
" int b(5);\n",
" int c = { 5 };\n",
"}"
]
},
......@@ -130,7 +159,7 @@
}
],
"source": [
"#include <iostream>\n",
"#include <iostream> // for std::cout and std::endl\n",
"\n",
"{\n",
" int a {}, b {}, c {} ; // default initialization; set the values to 0\n",
......@@ -190,12 +219,17 @@
"source": [
"### Increment and decrement operators\n",
"\n",
"Finally, C++ also provides a shortcut when value is either incremented or decremented by adding `++` or `--` before or after the name of the variable. The position of these signs are better explained by examples:"
"Finally, C++ also provides a shortcut when value is either incremented or decremented by adding `++` or `--` before or after the name of the variable. \n",
"\n",
"* If the sign is placed before the variable, it is a **pre-increment**. \n",
"* If the sign is placed after the variable, it is a **post-increment**. \n",
"\n",
"An example is the better way to explain the difference between both:\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": 7,
"metadata": {},
"outputs": [
{
......@@ -294,7 +328,7 @@
"| `a <= b` | `true` if a is less than or equal to b |\n",
"\n",
"\n",
"These operators are defined for most ordinary types and may be defined for your own types.\n"
"These operators are defined for most ordinary types and may be defined for your own types (we'll see that [later](/notebooks/3-Operators/2-Comparison.ipynb)).\n"
]
},
{
......@@ -303,16 +337,17 @@
"source": [
"## References\n",
"\n",
"A reference is a variable that shares its value with another.\n",
"It can be seen as a kind of alias, another name for the same value.\n",
"A reference is a variable that acts as a kind of alias, and provides another name for the same value.\n",
"\n",
"When defining a reference, it must be immediately initialized by\n",
"indicating on which variable it should point. It cannot be changed after that."
"indicating on which variable it should point; it cannot be changed after that.\n",
"\n",
"The syntax is to add a `&` character just after the type:"
]
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 8,
"metadata": {},
"outputs": [
{
......@@ -330,10 +365,10 @@
"#include <iostream> \n",
"\n",
"{\n",
" int a { 2 } ;\n",
" int b { a } ;\n",
" b = b + 1 ;\n",
" int& c { a } ;\n",
" int a { 2 };\n",
" int b { a };\n",
" b = b + 1;\n",
" int& c { a }; // c is a reference to a\n",
"\n",
" std::cout << \"Initial values : a = \" << a << \", b = \" << b << \" and c = \" << c << std::endl;\n",
" b = b + 5;\n",
......@@ -345,6 +380,13 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Reference is a purely C++ concept that doesn't exist in C."
]
},
{
"cell_type": "markdown",
"metadata": {},
......@@ -365,7 +407,7 @@
},
{
"cell_type": "code",
"execution_count": 33,
"execution_count": 9,
"metadata": {},
"outputs": [
{
......@@ -373,19 +415,19 @@
"output_type": "stream",
"text": [
"Initial values: \n",
"\t p: address = 0x7ffee3c019b4, value = 2\n",
"\t a: address = 0x7ffee3c019b4, value = 2\n",
"\t b: address = 0x7ffee3c019b0, value = 10\n",
"\t p: address = 0x7ffeea882974, value = 2\n",
"\t a: address = 0x7ffeea882974, value = 2\n",
"\t b: address = 0x7ffeea882970, value = 10\n",
"\n",
"After value pointed by p is incremented:\n",
"\t p: address = 0x7ffee3c019b4, value = 3\n",
"\t a: address = 0x7ffee3c019b4, value = 3\n",
"\t b: address = 0x7ffee3c019b0, value = 10\n",
"\t p: address = 0x7ffeea882974, value = 3\n",
"\t a: address = 0x7ffeea882974, value = 3\n",
"\t b: address = 0x7ffeea882970, value = 10\n",
"\n",
"p now points to the address of b:\n",
"\t p: address = 0x7ffee3c019b0, value = 10\n",
"\t a: address = 0x7ffee3c019b4, value = 3\n",
"\t b: address = 0x7ffee3c019b0, value = 10\n"
"\t p: address = 0x7ffeea882970, value = 10\n",
"\t a: address = 0x7ffeea882974, value = 3\n",
"\t b: address = 0x7ffeea882970, value = 10\n"
]
}
],
......@@ -393,8 +435,8 @@
"#include <iostream>\n",
"\n",
"{ \n",
" int a { 2 }, b { 10 } ;\n",
" int* p { &a } ;\n",
" int a { 2 }, b { 10 };\n",
" int* p {&a}; // define a pointer p which is initialized with the address of a\n",
"\n",
" std::cout << \"Initial values: \" << std::endl;\n",
" std::cout << \"\\t p: address = \" << p << \", value = \" << *p << std::endl;\n",
......@@ -402,14 +444,14 @@
" std::cout << \"\\t b: address = \" << &b << \", value = \" << b << std::endl;\n",
" \n",
" std::cout << std::endl;\n",
" *p = *p + 1 ;\n",
" *p = *p + 1; // increment the integer value present at address p\n",
" std::cout << \"After value pointed by p is incremented:\" << std::endl;\n",
" std::cout << \"\\t p: address = \" << p << \", value = \" << *p << std::endl;\n",
" std::cout << \"\\t a: address = \" << &a << \", value = \" << a << std::endl;\n",
" std::cout << \"\\t b: address = \" << &b << \", value = \" << b << std::endl;\n",
" \n",
" std::cout << std::endl;\n",
" p = &b;\n",
" p = &b; // change the address pointed by p\n",
" std::cout << \"p now points to the address of b:\" << std::endl;\n",
" std::cout << \"\\t p: address = \" << p << \", value = \" << *p << std::endl;\n",
" std::cout << \"\\t a: address = \" << &a << \", value = \" << a << std::endl;\n",
......@@ -421,13 +463,14 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"A pointer can also designate no variables, if it is assigned the value\n",
"special `nullptr`. It is then a mistake to try to access its pointed value.\n",
"Any program that accepts pointers as parameters must handle this case, which increases\n",
"its complexity. This is one of the reasons why it is preferable to use\n",
"references rather than pointers whenever possible.\n",
"### `nullptr`\n",
"\n",
"It is strongly recommended to initialize a pointer when creating it: if you define an uninitialized pointer, it points to an arbitrary area of memory, which can create undefined behaviors that are not necessarily reproducible."
"A pointer can also designate no variables, if it is assigned the special value\n",
" `nullptr`. It is then a mistake to try to access its pointed value (as we shall see later, an [`assert`](/notebooks/5-UsefulConceptsAndSTL/1-ErrorHandling.ipynb#Assert) is a good idea to ensure we do not try to dereference a `nullptr` value).\n",
"\n",
"It is strongly recommended to initialize a pointer when creating it: if you define an uninitialized pointer, it points to an arbitrary area of memory, which can create undefined behaviors that are not necessarily reproducible.\n",
"\n",
"If the pointed area is known at initialization and never changes throughout the program, you should consider a reference rather than a pointer."
]
},
{
......@@ -441,19 +484,25 @@
},
{
"cell_type": "code",
"execution_count": 34,
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[1minput_line_69:4:8: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mcannot assign to variable 'pi' with const-qualified type 'const double'\u001b[0m\n",
"\u001b[1minput_line_23:6:8: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mcannot assign to variable 'pi' with const-qualified type 'const double'\u001b[0m\n",
" pi = 5.; // COMPILATION ERROR!\n",
"\u001b[0;1;32m ~~ ^\n",
"\u001b[0m\u001b[1minput_line_69:3:18: \u001b[0m\u001b[0;1;30mnote: \u001b[0mvariable 'pi' declared const here\u001b[0m\n",
"\u001b[0m\u001b[1minput_line_23:3:18: \u001b[0m\u001b[0;1;30mnote: \u001b[0mvariable 'pi' declared const here\u001b[0m\n",
" const double pi = 3.1415927;\n",
"\u001b[0;1;32m ~~~~~~~~~~~~~^~~~~~~~~~~~~~\n",
"\u001b[0m\u001b[1minput_line_23:7:10: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mcannot assign to variable 'pi_2' with const-qualified type 'const double'\u001b[0m\n",
" pi_2 = 7.; // COMPILATION ERROR!\n",
"\u001b[0;1;32m ~~~~ ^\n",
"\u001b[0m\u001b[1minput_line_23:4:18: \u001b[0m\u001b[0;1;30mnote: \u001b[0mvariable 'pi_2' declared const here\u001b[0m\n",
" double const pi_2 = 3.1415927; // equally valid; it is just a matter of taste. Mine is to put it before,\n",
"\u001b[0;1;32m ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~\n",
"\u001b[0m"
]
},
......@@ -469,7 +518,8 @@
"source": [
"{\n",
" const double pi = 3.1415927;\n",
" double const pi_2 = 3.1415927; // equally valid; it is just a matter of taste.\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",
" pi = 5.; // COMPILATION ERROR!\n",
" pi_2 = 7.; // COMPILATION ERROR!\n",
"}"
......@@ -613,11 +663,10 @@
"metadata": {},
"source": [
"\n",
"**IMPORTANT**: Even if declared `const`, the pointed value is not\n",
"**IMPORTANT**: Even if declared `const`, the pointed value is\n",
"not intrinsically constant. It just can't be\n",
"modified through this precise pointer.\n",
"\n",
"If other variables reference the same memory area and do not\n",
"If other variables reference the same memory area and \n",
"are not constant, they are able to modify the value:\n"
]
},
......@@ -644,7 +693,7 @@
" \n",
" std::cout << \"Value pointed by p (which doesn't allow value modification) is: \" << *p << std::endl;\n",
" \n",
" int* p2 {&a};\n",
" int* p2 {&a}; // Pointer to the same memory area, but no constness here.\n",
" *p2 = 10;\n",
" \n",
" std::cout << \"Value pointed by p (and modified through p2) is: \" << *p << std::endl; \n",
......@@ -655,21 +704,21 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"On the other hand, the language prohibits to create a pointer to modify a constant:"
"On the other hand, pointers can't be used as a work-around to modify a constant value:"
]
},
{
"cell_type": "code",
"execution_count": 46,
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[1minput_line_85:4:17: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mcannot initialize a variable of type 'int *' with an rvalue of type 'const int *'\u001b[0m\n",
" int * p_n { &n }; // COMPILATION ERROR\n",
"\u001b[0;1;32m ^~\n",
"\u001b[1minput_line_25:4:16: \u001b[0m\u001b[0;1;31merror: \u001b[0m\u001b[1mcannot initialize a variable of type 'int *' with an rvalue of type 'const int *'\u001b[0m\n",
" int* p_n { &n }; // COMPILATION ERROR\n",
"\u001b[0;1;32m ^~\n",
"\u001b[0m"
]
},
......@@ -685,7 +734,8 @@
"source": [
"{\n",
" const int n { 3 };\n",
" int * p_n { &n }; // COMPILATION ERROR\n",
" int* p_n { &n }; // COMPILATION ERROR\n",
" const int* p_n2 { &n }; // OK\n",
"}"
]
},
......@@ -697,8 +747,7 @@
"\n",
"The operator `[]` enables the creation of an array.\n",
"\n",
"\n",
"In C++, the indexes of an array start at 0."
"**Beware:** In C++, the indexes of an array start at 0."
]
},
{
......@@ -778,21 +827,21 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"**IMPORTANT**: so far we have considered only the case of _static_ arrays, for which the size is already known at compilation. We will deal with dynamic ones later in this tutorial (and also with the standard libraries alternative such as std::vector or std::array which are actually much more compelling)."
"**IMPORTANT**: so far we have considered only the case of _static_ arrays, for which the size is already known at compilation. We will deal with dynamic ones [later in this tutorial](/notebooks/1-ProceduralProgramming/6-DynamicAllocation.ipynb#Arrays-on-heap) (and also with the standard libraries [alternatives](/notebooks/5-UsefulConceptsAndSTL/3-Containers.ipynb) such as std::vector or std::array which are actually much more compelling)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Arrays and pointers\n",
"### Arrays and pointers\n",
"\n",
"The variable designating an array is similar to a constant pointer pointing to the beginning of the array. Increasing this pointer is like moving around in the array.\n"
]
},
{
"cell_type": "code",
"execution_count": 60,
"execution_count": 13,
"metadata": {},
"outputs": [
{
......@@ -802,7 +851,7 @@