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 778f1bc0 authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

Cleaning-up part 5 (still in progress).

parent 0c371225
......@@ -4,7 +4,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# [Getting started in C++](/) - [Useful concepts and STL](/notebooks/5-UsefulConceptsAndSTL/0-main.ipynb) - [RAII idiom](/notebooks/5-UsefulConceptsAndSTL/2-RAII.ipynb)"
"# [Getting started in C++](/) - [Useful concepts and STL](./0-main.ipynb) - [RAII idiom](./2-RAII.ipynb)"
]
},
{
......@@ -27,7 +27,7 @@
"\n",
"Often, people who criticizes the language say C++ is really tricky and that is extremely easy to leak memory all over the way, and that it sorely miss a [**garbage collector**](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)) which does the job of cleaning-up and freeing the memory when the data are no longer used.\n",
"\n",
"However, garbage collection, used for instance in Python and Java, is not without issues itself: the memory is not always freed as swiftly as possible, and the bookkeeping of references is not without a toll on the efficiency of the program itself.\n",
"However, garbage collection, used for instance in Python and Java, is not without issues itself: the memory is not always freed as swiftly as possible, and the bookkeeping of references is not without a toll on the efficiency of the program.\n",
"\n",
"C++ provides in fact the best of both worlds: a way to provide safe freeing of memory as soon as possible... provided you know how to adequately use it.\n",
"\n",
......@@ -152,7 +152,7 @@
"metadata": {},
"source": [
"\n",
"© _CNRS 2016_ - _Inria 2018-2019_ \n",
"© _CNRS 2016_ - _Inria 2018-2020_ \n",
"_This notebook is an adaptation of a lecture prepared 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 written by Sébastien Gilles and Vincent Rouvreau (Inria)_"
]
......@@ -162,14 +162,14 @@
"kernelspec": {
"display_name": "C++17",
"language": "C++17",
"name": "xeus-cling-cpp17"
"name": "xcpp17"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".cpp",
"mimetype": "text/x-c++src",
"name": "c++",
"version": "-std=c++17"
"version": "17"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
......
......@@ -4,7 +4,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# [Getting started in C++](/) - [Useful concepts and STL](/notebooks/5-UsefulConceptsAndSTL/0-main.ipynb) - [Containers](/notebooks/5-UsefulConceptsAndSTL/3-Containers.ipynb)"
"# [Getting started in C++](/) - [Useful concepts and STL](./0-main.ipynb) - [Containers](./3-Containers.ipynb)"
]
},
{
......@@ -58,7 +58,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
......@@ -77,9 +77,19 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\n",
"0\n",
"0\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -100,9 +110,19 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"4.3\n",
"4.3\n",
"4.3\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -123,9 +143,19 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3\n",
"5\n",
"6\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -141,14 +171,24 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"* And of course copy and move constructions"
"* And of course copy (and move) constructions"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3\n",
"5\n",
"6\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -177,9 +217,17 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Size = 3\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -195,14 +243,23 @@
"source": [
"### Adding new elements\n",
"\n",
"`std::vector` provides an easy and (most of the time) cheap to add an element **at the end of the array**. The method to add a new element is `push_back`:"
"`std::vector` provides an easy and (most of the time) cheap way to add an element **at the end of the array**. The method to add a new element is `push_back`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Size = 3\n",
"Size = 4\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -232,15 +289,23 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"foo[1] = 5\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
"{\n",
" std::vector<int> foo { 3, 5, 6 };\n",
" std::cout << \"foo[1] = \" << foo[1] << std::endl;\n",
" std::cout << \"foo[1] = \" << foo[1] << std::endl; // Remember: indexing starts at 0 in C and C++\n",
"}"
]
},
......@@ -253,9 +318,17 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"foo[4] = 0\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -274,9 +347,25 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"foo[4] = "
]
},
{
"ename": "Standard Exception",
"evalue": "vector",
"output_type": "error",
"traceback": [
"Standard Exception: vector"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -311,9 +400,26 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Vector: size = 0 and capacity = 0\n",
"Vector: size = 1 and capacity = 1\n",
"Vector: size = 2 and capacity = 2\n",
"Vector: size = 3 and capacity = 4\n",
"Vector: size = 4 and capacity = 4\n",
"Vector: size = 5 and capacity = 8\n",
"Vector: size = 6 and capacity = 8\n",
"Vector: size = 7 and capacity = 8\n",
"Vector: size = 8 and capacity = 8\n",
"Vector: size = 9 and capacity = 16\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -344,16 +450,33 @@
"\n",
"### `reserve()` and `resize()`\n",
"\n",
"`reserve()` is the method to set manually the size of the capacity. When you have a clue of the expected number of elements, it is better to provide it: even if your guess was flawed, it limits the number of reallocations:\n",
"`reserve()` is the method to set manually the value of the capacity. When you have a clue of the expected number of elements, it is better to provide it: even if your guess was flawed, it limits the number of reallocations:\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Vector: size = 0 and capacity = 5\n",
"Vector: size = 1 and capacity = 5\n",
"Vector: size = 2 and capacity = 5\n",
"Vector: size = 3 and capacity = 5\n",
"Vector: size = 4 and capacity = 5\n",
"Vector: size = 5 and capacity = 5\n",
"Vector: size = 6 and capacity = 10\n",
"Vector: size = 7 and capacity = 10\n",
"Vector: size = 8 and capacity = 10\n",
"Vector: size = 9 and capacity = 10\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -380,7 +503,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
......@@ -420,9 +543,19 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Size = 2 Capacity = 2 Content = [3, 5]\n",
"Size = 8 Capacity = 8 Content = [3, 5, 10, 10, 10, 10, 10, 10]\n",
"Size = 3 Capacity = 8 Content = [3, 5, 10]\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -449,9 +582,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Size = 2 Capacity = 2 Content = [3, 5]\n",
"Size = 8 Capacity = 8 Content = [3, 5, 10, 10, 10, 10, 10, 10]\n",
"Size = 3 Capacity = 8 Content = [3, 5, 10]\n",
"Size = 3 Capacity = 3 Content = [3, 5, 10]\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -484,9 +628,26 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Digit = 0\n",
"Digit = 0\n",
"Digit = 0\n",
"Digit = 0\n",
"Digit = 0\n",
"Digit = 3\n",
"Digit = 1\n",
"Digit = 4\n",
"Digit = 1\n",
"Digit = 5\n"
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -518,7 +679,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
......@@ -542,7 +703,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
......@@ -591,9 +752,17 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3 8 9 -12.3 -32.35 "
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -611,15 +780,23 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"It is not extremely efficient: at each call to `operator[]`, the program must figure out the element to draw without using the fact it had just fetched the element just in the previous memory location. Iterators provides this more efficient access:\n",
"It may not extremely efficient: at each call to `operator[]`, the program must figure out the element to draw without using the fact it had just fetched the element just in the previous memory location (in practice now compilers are rather smart and figure this out...) Iterators provides this more efficient access:\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\t3 1\t8 2\t9 3\t-12.3 4\t-32.35 "
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -644,7 +821,7 @@
"There are several flavors:\n",
"* Constant iterators, used here, with which you can only read the value under the iterator.\n",
"* Iterators, with which you can also modify it.\n",
"* Reverse iterators, to iterate the container from the last to the first.\n",
"* Reverse iterators, to iterate the container from the last to the first (avoid them if you can: they are a bit messy to use and may not be used in every algorithms in which standard iterators are ok...)\n",
"\n",
"There are default values for each container:\n",
"\n",
......@@ -660,9 +837,17 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Size = 9 Capacity = 12 Content = [2, 3, 4, 5, 7, 18, 4, 6, 20]\n"
]
}
],
"source": [
"#include <vector>\n",
"\n",
......@@ -694,9 +879,18 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3 8 9 -12.3 -32.35 \n",
"3 8 9 -12.3 -32.35 "
]
}
],
"source": [
"#include <vector>\n",
"#include <iostream>\n",
......@@ -735,9 +929,9 @@
"\n",
"`std::vector` is not the only possible choice; I will present very briefly the other possibilities here:\n",
"\n",
"* `std::list`: A double-linked list: the idea is that each element knows the address of the element before and the element after. It might be considered if you need to add often elements at specific locations in the list: adding a new element is just changing 2 pointers and setting 2 new ones for instances. You can't access directly an element by its index with a `std::list`.\n",
"* `std::list`: A double-linked list: the idea is that each element knows the addresses of the element before and the element after. It might be considered if you need to add often elements at specific locations in the list: adding a new element is just changing 2 pointers and setting 2 new ones. You can't access directly an element by its index with a `std::list`.\n",
"* `std::slist`: A single-linked list: similar as a `std::list` except only the pointer to the next element is kept.\n",
"* `std::deque`: For \"double ended queue\"; this container may be helpful if you need to store a really huge amount of data that might not fit within a `std::vector`. It might also be of use if you are to add often elements in front on the list: there is `push_front()` method as well as a `push_back` one. Item 18 of \\cite{Meyers2001} recommends using `std::deque` with `bool`: `std::vector<bool>` was an experiment to provide a specific implementation to spare memory that went wrong...\n",
"* `std::deque`: For \"double ended queue\"; this container may be helpful if you need to store a really huge amount of data that might not fit within a `std::vector`. It might also be of use if you are to add often elements in front on the list: there is `push_front()` method as well as a `push_back` one. Item 18 of \\cite{Meyers2001} recommends using `std::deque` with `bool`: `std::vector<bool>` was an experiment to provide a specific implementation to spare memory that went wrong and should therefore be avoided...\n",
"* `std::array`: You should use this one if the number of elements is known at compile time and doesn't change at all.\n",
"* `std::string`: Yes, it is actually a container! I will not tell much more about it; just add that it is the sole container besides `std::vector` that ensures continuous storage.\n",
"\n",
......@@ -759,7 +953,7 @@
"metadata": {},
"source": [
"\n",
"© _CNRS 2016_ - _Inria 2018-2019_ \n",
"© _CNRS 2016_ - _Inria 2018-2020_ \n",
"_This notebook is an adaptation of a lecture prepared 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 written by Sébastien Gilles and Vincent Rouvreau (Inria)_"
]
......@@ -769,14 +963,14 @@
"kernelspec": {
"display_name": "C++17",
"language": "C++17",
"name": "xeus-cling-cpp17"
"name": "xcpp17"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".cpp",
"mimetype": "text/x-c++src",
"name": "c++",
"version": "-std=c++17"
"version": "17"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
......
......@@ -4,7 +4,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# [Getting started in C++](/) - [Useful concepts and STL](/notebooks/5-UsefulConceptsAndSTL/0-main.ipynb) - [Associative containers](/notebooks/5-UsefulConceptsAndSTL/4-AssociativeContainers.ipynb)"
"# [Getting started in C++](/) - [Useful concepts and STL](./0-main.ipynb) - [Associative containers](./4-AssociativeContainers.ipynb)"
]
},
{
......@@ -243,7 +243,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"That's somewhere I dislike in this very useful class: error handling is not up to my taste... \n",
"That's something I dislike in this very useful class: error handling is not up to my taste as you have to remember to check explicitly all went right...\n",
"\n",
"### Access to one element: don't use `operator[]`!\n",
"\n",
......@@ -279,9 +279,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"So if you provide a wrong key; it doesn't yell and create on the spot a new entry, filling the associated value with the default constructor for the type...\n",
"So if you provide a wrong key, it doesn't yell and create on the spot a new entry, filling the associated value with the default constructor for the type...\n",
"\n",
"To do it properly (but more verbose!), use the `find()` method (if you're intrigued by the use of iterator there, we will present them more in details in the notebook about [algorithms](/notebooks/5-UsefulConceptsAndSTL/7-Algorithms.ipynb)):"
"To do it properly (but more verbose!), use the `find()` method (if you're intrigued by the use of iterator there, we will present them more in details in the notebook about [algorithms](./7-Algorithms.ipynb)):"
]
},
{
......@@ -411,7 +411,7 @@
"metadata": {},
"source": [
"\n",
"© _CNRS 2016_ - _Inria 2018-2019_ \n",
"© _CNRS 2016_ - _Inria 2018-2020_ \n",
"_This notebook is an adaptation of a lecture prepared 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 written by Sébastien Gilles and Vincent Rouvreau (Inria)_"
]
......@@ -421,14 +421,14 @@
"kernelspec": {
"display_name": "C++17",
"language": "C++17",
"name": "xeus-cling-cpp17"
"name": "xcpp17"
},
"language_info": {
"codemirror_mode": "text/x-c++src",
"file_extension": ".cpp",
"mimetype": "text/x-c++src",
"name": "c++",
"version": "-std=c++17"
"version": "17"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
......
......@@ -4,7 +4,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# [Getting started in C++](/) - [Useful concepts and STL](/notebooks/5-UsefulConceptsAndSTL/0-main.ipynb) - [Move semantics](/notebooks/5-UsefulConceptsAndSTL/5-MoveSemantics.ipynb)"
"# [Getting started in C++](/) - [Useful concepts and STL](./0-main.ipynb) - [Move semantics](./5-MoveSemantics.ipynb)"
]
},
{
......@@ -297,7 +297,7 @@