Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
c [2019/01/08 13:50] paul [STL containers] |
c [2020/10/23 02:53] (current) |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Rule of Three ===== | + | ====== C and C++ ====== |
+ | ===== C declerations ===== | ||
+ | |||
+ | A c decleration can be read by following this rule and knowing about precedence. | ||
+ | |||
+ | Go left when you can and right when you must. | ||
+ | |||
+ | < | ||
+ | char *(*(**foo [][8])())[]; | ||
+ | </ | ||
+ | |||
+ | foo is an array to an array of 8 pointers to poiners to a function that returns | ||
+ | a pointer to an array of pointers to char | ||
+ | |||
+ | ===== C++ Interview questions ===== | ||
+ | |||
+ | I was given a pop quiz by a non-tech interviewer once on c++. Here was his questions: | ||
+ | |||
+ | - What is the name of an invalid pointer? | ||
+ | - Weird question and I don't think it's right. Answer he was looking for was null. | ||
+ | - What is the difference between a struct and a class? | ||
+ | - What is the keyword to deallocate memory? Lol | ||
+ | - When using a new keyword where is the memory stored, stack or heap? Heap OBVI. | ||
+ | - If a program crashes and you have a core dump and debugger, what is the first thing you do? | ||
+ | - Look at a backtrace, see where the program crashed, look at what the variable were. | ||
+ | ===== General C++ ===== | ||
+ | |||
+ | Principles of C++: (([[https:// | ||
+ | * Trust the programmer. | ||
+ | * You don't have to pay for something you don't need. | ||
+ | * Don't break existing code. | ||
+ | * Prefer compile time errors over run time errors. | ||
+ | |||
+ | ===== Differences Between C and C++ ===== | ||
+ | |||
+ | Here are some differences I have come across between C and C++. This stuff is | ||
+ | interesting because it highlights the features that make C++ more powerful, and also | ||
+ | gives you a better understanding of the way the two languages work. | ||
+ | |||
+ | * Biggest one: C does not have classes and objects | ||
+ | * C++ has pass by reference. C does not. | ||
+ | * C++ implements name mangling when compiling functions, C does not. | ||
+ | |||
+ | ===== C Preprocessor (CPP) ===== | ||
+ | |||
+ | Much of what I have learned comes from two places: the GNU CPP manual | ||
+ | [[https:// | ||
+ | [[https:// | ||
+ | |||
+ | '' | ||
+ | of ... when used in a variadic macro. | ||
+ | |||
+ | A simple macro is a kind of abbreviation. It is a name which stands for a fragment of | ||
+ | code. Some people refer to these as manifest constants. | ||
+ | |||
+ | Before you can use a macro, you must define it explicitly with the | ||
+ | '' | ||
+ | and then the code it should be an abbreviation for. For example, | ||
+ | |||
+ | <code c++> | ||
+ | #define BUFFER_SIZE 1020 | ||
+ | </ | ||
+ | |||
+ | The use of all upper case for macro names is a standard convention. Programs are easier | ||
+ | to read when it is possible to tell at a glance which names are macros. | ||
+ | |||
+ | The C preprocessor scans your program sequentially, | ||
+ | effect at the place you write them. | ||
+ | |||
+ | <code c++> | ||
+ | foo = X; | ||
+ | #define X 4 | ||
+ | bar = X; | ||
+ | </ | ||
+ | |||
+ | Produces as output: | ||
+ | |||
+ | <code c++> | ||
+ | foo = X; | ||
+ | bar = 4; | ||
+ | </ | ||
+ | |||
+ | You can also use '' | ||
+ | |||
+ | The '' | ||
+ | issues with generating double expressions caused by the addition of a semicolon. | ||
+ | Doing the following: | ||
+ | |||
+ | <code c++> | ||
+ | #define SOME_MACRO(VAR) \ | ||
+ | do { int i = var; \ | ||
+ | i = 12*i; } \ | ||
+ | while (0) | ||
+ | </ | ||
+ | | ||
+ | When you call this macro in the your code as '' | ||
+ | statement which is: | ||
+ | |||
+ | <code c++> | ||
+ | do { ... } while (0); | ||
+ | </ | ||
+ | |||
+ | This way you can use a macro expansion in a if else statement with no curly braces | ||
+ | where more than one statement would mess stuff up. | ||
+ | |||
+ | ===== C Declerations ===== | ||
+ | |||
+ | First, understand the breakdown of a decleration in c. | ||
+ | |||
+ | ===== Rule of Three ===== | ||
===== Rule of Five ===== | ===== Rule of Five ===== | ||
Line 8: | Line 117: | ||
The STL library has 3 types of container classes: | The STL library has 3 types of container classes: | ||
- | * **sequence containers** - container classes that maintain the ordering of elements in the container | + | * **sequence containers** - container classes that maintain the ordering of elements in the container. Examples are vectors, deques, and lists. |
* **associative containers** - container classes that automatically sort their inputs when the inputs are inserted into the container. Eg. are a set, multiset, map or multimap. | * **associative containers** - container classes that automatically sort their inputs when the inputs are inserted into the container. Eg. are a set, multiset, map or multimap. | ||
- | * **container adapters** - special predefined containers that are adapted to specific uses, such as a LIFO stack or a FIFO queue. | + | * **container adapters** - special predefined containers that are adapted to specific uses, such as a LIFO stack or a FIFO queue. |
+ | |||
+ | STL containers provide a mechanism for traversing their contents called an iterator. An iterator is best visualized as a pointer to an element in the list with a set of overloaded operators that provide extra functionality. | ||
+ | |||
+ | Overloaded iterator operators: | ||
+ | * **Operator*** dereferencing an iterator gives the element that the item is pointing to | ||
+ | * **Operator++** advances the iterator to point to the next element | ||
+ | * **Operator== & !=** gives basic comparison for two iterators to see if they point to the same element. | ||
+ | * **Operator=** assign to a new location | ||
+ | |||
+ | |||
+ | Each container has functions that return an iterator. | ||
+ | * **begin()** | ||
+ | * **end()** returns an iterator at the start of the container | ||
+ | * **cbegin()** returns a '' | ||
+ | * **cend()** returns a '' | ||
+ | |||
+ | Iterators are members of an STL container. For example to get an iterator for a specific type of list: | ||
+ | <code c++> | ||
+ | std:: | ||
+ | </ | ||
+ | ==== Vector ==== | ||
+ | |||
+ | An std::vector is a sequence container dynamic array that can grow to add to more elements. | ||
+ | |||
+ | ==== Deque ==== | ||
+ | |||
+ | An '' | ||
+ | |||
+ | ==== Pair ==== | ||
+ | |||
+ | An '' | ||
+ | |||
+ | <code cpp> | ||
+ | // pair::pair example | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | int main () { | ||
+ | std::pair < | ||
+ | std::pair < | ||
+ | std::pair < | ||
+ | |||
+ | product1 = std:: | ||
+ | |||
+ | product2.first = " | ||
+ | product2.second = 39.90; | ||
+ | |||
+ | std::cout << "The price of " << product1.first << " is $" << product1.second << ' | ||
+ | std::cout << "The price of " << product2.first << " is $" << product2.second << ' | ||
+ | std::cout << "The price of " << product3.first << " is $" << product3.second << ' | ||
+ | return 0; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== List ==== | ||
+ | |||
+ | An '' | ||
+ | the next and previous element. You can't randomly access elements, you have to | ||
+ | "walk the list". But inserting elements is very fast if you know where to insert | ||
+ | them. | ||
+ | |||
+ | ==== Set ==== | ||
+ | |||
+ | An '' | ||
+ | sorted as we insert them. | ||
+ | |||
+ | ==== Multiset ==== | ||
+ | |||
+ | An '' | ||
+ | duplicate data which is automatically sorted as we insert them. | ||
==== Map ==== | ==== Map ==== | ||
- | An std::map is an associated array which is a map, symbol table or dictionary that has a collection of key value pairs such that a key only shows up once. | + | An '' |
+ | dictionary that has a collection of key value pairs such that a key only shows | ||
+ | up once. | ||
+ | |||
+ | Data pairs must be inserted into a map, and while you do this they are | ||
+ | automatically sorted. You can make pairs with the '' | ||
+ | function. | ||
+ | |||
+ | <code cpp> | ||
+ | std:: | ||
+ | myMap.insert(std:: | ||
+ | </ | ||
===== Memory Leaks ===== | ===== Memory Leaks ===== | ||
- | For every new there must be a delete. Use the following valgrind command to profile for mem leaks((https:// | ||
- | < | + | For every new there must be a delete. Use the following valgrind command to |
+ | profile for memory leaks [[https:// | ||
+ | |||
+ | < | ||
+ | valgrind --tool=memcheck --leak-check=yes name_of_exec | ||
</ | </ | ||
+ | |||
+ | ===== Lambda Functions ====== | ||
+ | |||
+ | Lambda functions are: | ||
+ | * functions without a name | ||
+ | * define their functionality right in place | ||
+ | * can be copied like data | ||
+ | |||
+ | Lambda functions should be precise and self explaining. | ||
+ | |||
+ | The syntax is as follows: | ||
+ | |||
+ | {{:: | ||
+ | * [] : captures the used variables per copy of per reference | ||
+ | * () : is required for parameters | ||
+ | * -> : is required for a return value | ||
+ | * {} : may include expressions and statements | ||
+ | |||
+ | ===== Range-based for statement ===== | ||
+ | |||
+ | C++ 11 introduced the range-based '' | ||
+ | < | ||
+ | for ( for-range-declaration : expression ) statement | ||
+ | </ | ||
+ | |||
+ | Example: | ||
+ | <code cpp> | ||
+ | int array[5] = { 1, 2, 3, 4, 5 }; | ||
+ | for (int& x : array) | ||
+ | x *= 2; | ||
+ | </ | ||
+ | |||
+ | ===== Debugging ===== | ||
+ | |||
+ | There are lots of options for debugging. I make extensive use of DDD with ROS | ||
+ | which helped a lot. gdbgui is an interesting web based front end, but i tried it | ||
+ | for 5 mins and ran into issues with it debugging a simple program. | ||
+ | |||
+ | ==== GDB ==== | ||
+ | |||
+ | Debugging in GDB is not that bad! It is also really useful when looking at simple | ||
+ | stuff for learning stuff. | ||
+ | |||
+ | This is a really nice intro [[http:// | ||
+ | |||
+ | This is a really nice video on gdbtui (which is the text user input) mode [[https:// | ||
+ | |||
+ | To debug in GDB you need to compile a program with a debug with a '' | ||
+ | option. | ||
+ | |||
+ | For macros see the following [[https:// | ||
+ | |||
+ | |||
+ | ===== Mutable ===== | ||
+ | |||
+ | '' | ||
+ | <code cpp> | ||
+ | int main() | ||
+ | { | ||
+ | int n1 = 0; // non-const object | ||
+ | const int n2 = 0; // const object | ||
+ | int const n3 = 0; // const object (same as n2) | ||
+ | volatile int n4 = 0; // volatile object | ||
+ | const struct | ||
+ | { | ||
+ | int n1; | ||
+ | mutable int n2; | ||
+ | } x = {0, 0}; // const object with mutable member | ||
+ | |||
+ | n1 = 1; // ok, modifiable object | ||
+ | // n2 = 2; // error: non-modifiable object | ||
+ | n4 = 3; // ok, treated as a side-effect | ||
+ | // x.n1 = 4; // error: member of a const object is const | ||
+ | x.n2 = 4; // ok, mutable member of a const object isn't const | ||
+ | |||
+ | const int& r1 = n1; // reference to const bound to non-const object | ||
+ | // r1 = 2; // error: attempt to modify through reference to const | ||
+ | const_cast< | ||
+ | |||
+ | const int& r2 = n2; // reference to const bound to const object | ||
+ | // r2 = 2; // error: attempt to modify through reference to const | ||
+ | // const_cast< | ||
+ | } | ||
+ | </ | ||
+ | Output: | ||
+ | < | ||
+ | # typical machine code produced on an x86_64 platform | ||
+ | # (only the code that contributes to observable side-effects is emitted) | ||
+ | main: | ||
+ | movl $0, -4(%rsp) # volatile int n4 = 0; | ||
+ | movl $3, -4(%rsp) # n4 = 3; | ||
+ | xorl %eax, %eax # return 0 (implicit) | ||
+ | ret | ||
+ | </ | ||
+ | |||
+ | ==== Pointer Syntax ==== | ||
+ | |||
+ | |||
+ | <code cpp> | ||
+ | |||
+ | Does not declare 3 pointers - it is one pointer and 2 objects. | ||
+ | |||
+ | <code cpp> | ||
+ | sf::Sprite* unfortunately does not apply to all the variables declared following it, just the first. It is equivalent to | ||
+ | |||
+ | sf::Sprite* re_sprite_hair; | ||
+ | sf::Sprite re_sprite_body; | ||
+ | sf::Sprite re_sprite_eyes; | ||
+ | </ | ||
+ | |||
+ | You want to do: | ||
+ | |||
+ | <code cpp> | ||
+ | sf::Sprite *re_sprite_hair, | ||
+ | </ | ||
+ | |||
+ | ===== Smart Pointers ===== | ||
+ | |||
+ | The STL library provides three types of "smart pointers", | ||
+ | |||
+ |