1 / 33

Review of C/C++ Concepts Arrays, Vectors, Iterators, & Lambdas

Review of C/C++ Concepts Arrays, Vectors, Iterators, & Lambdas. Operating Systems. Arrays of Primitive Types. Arrays of primitive data types are similar in philosophy to Java arrays Y ou don ’ t have to new static arrays. Just define and start using them.

matia
Télécharger la présentation

Review of C/C++ Concepts Arrays, Vectors, Iterators, & Lambdas

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Review of C/C++ ConceptsArrays, Vectors, Iterators, & Lambdas Operating Systems

  2. Arrays of Primitive Types • Arrays of primitive data types are similar in philosophy to Java arrays • You don’t have to newstatic arrays. • Just define and start using them. • They are zero-index based just like in Java int value[10]; /* Array of 10 integers */ int counter = 0; for (counter = 0; (counter < 10); counter++) { value[counter] = counter * counter; }

  3. Initializing Arrays • Arrays can be initialized by specifying an initializer list: int value[] = {1, 2, 3, 4, 5}; /* Array of 5 integers */ • A C-string is nothing but an array of characters! • However, an implicit ‘\0’(ASCII code zero) character is inserted at the end of the string. Therefore the following string actually occupies 6 bytes of memory! char name[] = “raodm”;

  4. Strings • C language does not natively support strings • Strings are implemented as an ‘\0’ (ASCII 0) terminated, partially filled array of characters! • Example: char myString[10] = “Hello!\n”; • The trailing ‘\0’ is added when “” (double quotes) are used. • At al other times you have to explicitly add ‘\0’ to terminate a string • This is a common aspect that most novice C programmers miss out. • It is important to note as some of the OS API methods returns C strings Index positions in myString

  5. Simple C-String Manipulation /* Program to print a given name in reverse. */ #include<stdio.h> char name[] = "Some Name"; int main() { // First count number of characters by searching for // the trailing '\0' in the array of characters int length; for(length = 0; (name[length] != '\0'); length++); // Now using length print characters in reverse while(length >= 0) { printf("%c", name[length]); length--; } printf("\n"); return 0; } Output from this program: emaN emoS

  6. C to C++ Strings • Working with C strings can be cumbersome • It is convenient to convert C strings to C++ std::string • Some OS API may need C strings to operate • Convert C++ std::string to C strings when needed using c_str() method. #include<iostream> #include<string> int main() { charcString[] = "Testing"; std::string s1(cString); std::string s2 = cString; return 0; }

  7. Static 2-D arrays • C provides a built-in syntax for 2-D arrays of various data types • Including user defined data types • 2-D arrays are defined and manipulated in a similar fashion as Java int matrix[2][3] = {{20, 30, 40}, {11, 12, 13}}; Conceptual Layout of matrix matrix[0][0] matrix[1][0] matrix[1][2]

  8. The std::array class • The std::array class is preferred with C++ • With C++ try and avoid using vanilla arrays • The std::array class provides more safety than native arrays • It can be used as if it is a native array • The std::array matches the speed of native arrays in most cases #include <iostream> #include <array> intmain() { inti; conststd::array<std::string, 5> words = {{"zero", "one", "two", "three", "four"}}; std::cout << "Enter a number between 0 and 4: "; std::cin >> i; std::cout << words[i] << std::endl; return 0; } First generic parameter is data type of elements and second parameter is number of elements in the array.

  9. std::vector • The C++ Standard Template Library (STL) provides a dynamic array class called std::vector • This is similar to java.util.ArrayList in Java • Elements can be added/removed dynamically • Provides several methods to operate on list of elements • Refer to online documentation for details on the methods: http://www.cplusplus.com/reference/stl/vector/ • Review Chapter 7 of E-textbook C++ How to Program • Typically this is the list-like data structure of choice • Provides forward and backward iterators

  10. std::vector Example #include<iostream> #include<vector> int main() { std::vector<std::string> wordList; std::string word; // Read words from standard input until EOF while ((std::cin >> word)) { wordList.push_back(word); } // Write words in reverse order to standard output for(int i = wordList.size() - 1; (i >= 0); i--) { std::cout << wordList[i] << std::endl; } return 0; } Program Output (user inputs in green): one two three three two one After typing in inputs press Control+D to generate End-Of-File (EOF)

  11. New for-loop with arrays & vectors #include<iostream> #include<array> int main() { // Define local array of 5 strings. std::array<std::string, 5> fiveWords; // Read 5 strings for(auto & word: fiveWords) { std::cin >> word; } for(auto word: fiveWords) { std::cout << word << std::endl; } return0; } The autokeyword lets the compiler automatically determines the data type. It is always good to explicitly specify data type when known.

  12. Hash Map: unordered_map • The std::unordered_mapprovides a default Hash Map for storing <key, value> pairs • Key, Value are templatized and must be specified. • They are stored and returned as std::pair objects • The std::pair::first is the key • The std::pair::second is the value • Provides methods to add or remove <key, value> pairs. • It can be used as an associative array to add/remove <key, value> pairs • Permits custom hash methods to be used • Look up method details via online API at: http://en.cppreference.com/w/cpp/container/unordered_map

  13. std::unordered_map Example #include<unordered_map> #include<iostream> int main() { std::unordered_map<std::string, int> MonthNum = {{"january", 1}, {"february", 2}, {"march", 3}, {"april", 4}, {"december", 12}, {"november", 11}, {"october", 10}, {"may", 5}, {"june", 6}, {"july", 7}, {"september", 9}}; // Instead of auto, the explicit pair is used to illustrate example for(std::pair<conststd::string, int> k: MonthNum) { std::cout << k.first << " => " << k.second << "\n"; } // Avoid using [] to look-up entries because it will // add an empty entry if element does not exist if (MonthNum["august"] == 0) { std::cout << "ERROR: Month number for august == 0!\n"; } // But [] is convenient to update an entry to the hash_map. MonthNum["august"] = 8; // Look up entry in hash_map std::stringmon; std::cout << "Enter a month: "; std::cin >> mon; if (MonthNum.find(mon) == MonthNum.end()) { std::cout << "The month " << mon << " is not valid.\n"; } return 0; } Program Output: july=> 7 june => 6 may => 5 september => 9 october => 10 november => 11 december => 12 april => 4 march => 3 february => 2 january => 1 ERROR: Month number for august == 0! Enter a month: blah The month blah is not valid.

  14. Iterators • In C++, an iterator is an object that points to an element in a range of elements (such as an array or std::vector) and has ability to iterate through the elements • Use ++ and -- operator to iterate to the next or previous value respectively • Use * operator to dereference the iterator and obtain value it is referring to. • Iterators are powerful concepts in C++ and are extensively used in standard libraries • They are not core language constructs • Provide a convenient abstraction • Agnostic to underlying data structure • C++ has a variety of iterators • Random Access iterator: Access any element in the range • Bidirectionaliterator: Can move forward or backward • Forwarditerator: Unidirectional iterator • Inputiterator: Used to read input streams • Outputiterator: Used to write to output streams • Chapter 22 in E-textbook C++ How to Program covers iterators

  15. Iterators with std::vector #include<iostream> #include<vector> #include<iterator> intmain() { std::vector<std::string> wordList; std::string word; // Read words from standard input (until EOF) while ((std::cin >> word)) { wordList.push_back(word); } // Write words in reverse order to standard output for(std::vector<std::string>::reverse_iteratorcurr = wordList.rbegin(); (curr != wordList.rend()); curr++) { std::cout << *curr << std::endl; } return 0; } Program Output (user inputs in green): one two three three two one After typing in inputs press Control+D to generate End-Of-File (EOF) Access value referred by the iterator

  16. Iterators with std::unorded_map #include<unordered_map> #include<iostream> int main() { typedef std::unordered_map<std::string, int> StrIntMap; constStrIntMapMonthNum = {{"january", 1}, {"february", 2}, {"march", 3}, {"april", 4}, {"december", 12}, {"november", 11}, {"october", 10}, {"may", 5}, {"june", 6}, {"july", 7}, {"september", 9}}; // Use iterators and print all elements in map for(StrIntMap::const_iterator it = MonthNum.cbegin(); (it != MonthNum.cend()); it++) { std::cout << it->first << " => " << it->second << "\n"; } return 0; } Program Output : one two three july => 7 june => 6 may => 5 september => 9 october => 10 november => 11 december => 12 april => 4 march => 3 february => 2 january => 1

  17. Algorithms & Iterators • C++ STL includes several standard algorithms that work with iterators • Iterators hide the actual data structure being used from the algorithms • So the same algorithm can be used on various data structures that support appropriate iterators • Different algorithms require different types of iterators • Refer to online documentation on algorithms package for various methods: http://www.cplusplus.com/reference/algorithm/ • Chapter 22 in E-textbook C++ How to Program introduces some methods in the algorithms package

  18. Common methods in algorithms:for_each • The for_each method iterates over a range of values and calls a method with each value. • Algorithm prototype: template<classInputIterator, classFunction> Function for_each(InputIterator first, InputIterator last, Function fn) • Approximate behavior: template<classInputIterator, classFunction> Functionfor_each(InputIterator first, InputIterator last, Function fn) { while (first != last) { fn (*first); // Call function ++first; } return std::move(fn); }

  19. Example:for_each • The for_each method iterates over a range of values and calls a method with each value. #include<iostream> #include<vector> #include<iterator> #include<algorithm> voidprintStr(conststd::string& str) { std::cout << str << std::endl; } int main() { std::vector<std::string> wordList; std::string word; // Read words from standard input while ((std::cin >> word)) { wordList.push_back(word); } // Write words in reverse order to standard output std::for_each(wordList.rbegin(), wordList.rend(), printStr); return 0; } Program Output (user inputs in green): one two three three two one

  20. Common methods in algorithms:copy, unique_copy&copy_n • The copy,unique_copy, copy_if, and copy_n methods can be used to copy a range of values using iterators • The copy algorithm copies a range of values using iterators template <classInputIterator, classOutputIterator> OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result); • The copy_n algorithm copies first nvalues template <classInputIterator, classSize, classOutputIterator> OutputIteratorcopy_n (InputIterator first, Size n, OutputIterator result); • The copy_if algorithm copies values that satisfy a given predicate (function that returns a Boolean value) template <classInputIterator, classOutputIterator, classUnaryPredicate> OutputIteratorcopy_if (InputIterator first, InputIteratorlast, OutputIteratorresult, UnaryPredicatepred); • The unique_copy algorithm requires entries to be sorted and copies unique entries (there is also a version that accepts a predicate for comparisons) template <classInputIterator, classOutputIterator> OutputIteratorunique_copy (InputIterator first, InputIterator last, OutputIterator result);

  21. Example of:copy, unique_copy&copy_n • The copy,unique_copy and copy_n methods can be used to copy a range of values using iterators • Unique copy requires entries to be sorted and copies unique entries • copy_ncopies first n values #include<iostream> #include<vector> #include<iterator> #include<algorithm> int main() { std::vector<std::string> wordList; std::string word; while((std::cin >> word)) { wordList.push_back(word); } std::vector<std::string> fiveWords(5); // Create 5 empty strings as place holders. std::copy_n(wordList.begin(), 5, fiveWords.begin()); // Now five words has first 5 words from wordList. std::vector<std::string> backup(wordList.size()); // Create empty strings as place holders // Assume worldList is sorted. std::unique_copy(wordList.begin(), wordList.end(), backup.begin()); // NOTE: backup has unique strings & some empty strings return 0; }

  22. Input & Output Iterators with I/O streams • Special input and output iterators are available for use with I/O streams • Eases reading and writing values in data structures • istream_iterator: A unidirectional iterator for reading from an input stream • Data is read using stream extraction operator (operator>>) • ostream_iterator: A unidirectional iterator for writing to an output stream • Data is written using stream insertion operator (operator<<) #include<iostream> #include<vector> #include<iterator> #include<algorithm> int main() { std::istream_iterator<std::string> wordReader(std::cin); std::istream_iterator<std::string> eof; // Dummy iterator for end-of-file (EOF). std::vector<std::string> wordList(wordReader, eof); std::sort(wordList.begin(), wordList.end()); std::copy(wordList.rbegin(), wordList.rend(), std::ostream_iterator<std::string>(std::cout, "\n")); return 0; }

  23. Iterators & Algorithms with Arrays #include<iostream> #include<array> #include<iterator> #include<algorithm> int main() { // Define local array of 5 strings. std::array<std::string, 5> fiveWords; // Read 5 wordsfromstd::cin std::istream_iterator<std::string> wordReader(std::cin); std::copy_n(wordReader, 5, fiveWords.begin()); std::copy(fiveWords.begin(), fiveWords.end(), std::ostream_iterator<std::string>(std::cout, "\n")); return 0; } Refer to the C++ documentation at http://www.cplusplus.com/ for more details on the algorithm package.

  24. Lambdas • A lambda is an anonymous function that you can write inline within another method • Typically used only for small functions • Convenient for use with STL algorithms that accept methods • Syntax (required characters in red): [Capture] (Parameters)->return-type{body} • Capture: The list of variables to be available to the body of the lambda. See next slide for details. • Parameters are list of parameters like any other method • The return-type of the lambda • The body can contain routine C/C++ statements

  25. Examples of Lambdas • A few short examples of lambdas • [](int x, int y) -> int { int z = x + y; return z; } • Simple method that returns sum of parameters • [](int x, int y) { return x + y; } • Implicit return type from 'return' statement • [](int& x) { ++x; } • No return statement. So lambda functions' return type is 'void' • []() { ++global_x; } • no parameters, just accessing a global variable • []{ ++global_x; } • the same as previous example, so () can be omitted

  26. Lambdas with algorithms #include<vector> #include<algorithm> #include<iterator> #include<iostream> int main() { // Read all numbers from a text file std::vector<int> numList(std::istream_iterator <int> (std::cin), std::istream_iterator <int> ()); // sortnumbers in the vector std::sort(numList.begin(), numList.end(), [](int x, int y){ return y < x; }); // Copyonlyevennumbers std::vector<int> evenNumList; std::copy_if(numList.begin(), numList.end(), std::back_inserter(evenNumList), [](int x){return x % 2 == 0; }); // Print "*"s for even numbers std::for_each(evenNumList.begin(), evenNumList.end(), [](int i){std::cout << std::string(i, '*') << std::endl; }); return 0; } Program output (user inputs in green): 5 4 6 1 3 2 ****** **** **

  27. Capture syntax for lambdas • The capture clause in lambdas are used to refer to variables in scope of the lambda • [] : No variables defined in capture. Attempting to use any external variables in the lambda is an error. • [x, &y, …]: x is captured by value, y is captured by reference • [&] : any external variable is implicitly captured by reference if used • [=] : any external variable is implicitly captured by value if used • [&, x, …] : x is explicitly captured by value. Other variables will be captured by reference • [=, &z, …] : z is explicitly captured by reference. Other variables will be captured by value

  28. Stream & File I/O • C++ provides streams for reading and writing data to text files • Most of the file I/O we will do in this course will be text I/O • Streams can also be used for binary I/O • File streams are similar in philosophy and usage as std::cin and std::cout • All the operations on standard streams and file streams have comparable results • Different file streams are provided for different operations • Use std::ifstream for input files • Use std::ostream for output files • Use std::fstream for I/O files

  29. Class hierarchy for I/O streams ios_base ios istream iostream ostream istringstream ifstream ofstream ostringstream cin fstream cout cerr clog

  30. File Stream example:Copy a text file #include<fstream> #include<string> #include<iostream> int main() { std::ifstreaminFile ("input.txt"); if (!inFile.good()) { std::cerr << "Unable to read input.txt\n"; return 1; } std::ofstreamoutFile("output.txt"); std::string line; while (getline(inFile, line)) { outFile << line << std::endl; } inFile.close(); outFile.close(); return 0; }

  31. Iterators with files #include<fstream> #include<vector> #include<algorithm> #include<iterator> #include<iostream> int main() { // Read all numbers from a text file std::ifstreaminFile ("numbers.txt"); std::istream_iterator<int> intReader(inFile); std::vector<int> numList(intReader, std::istream_iterator <int> ()); // sortnumbers in the vector std::sort(numList.begin(), numList.end()); // Write sortednumbers to standard output std::copy(numList.begin(), numList.end(), std::ostream_iterator<int>(std::cout, "\n")); return 0; }

  32. String Streams • C++ provides stream wrappers around strings • The stream wrappers ease reading and writing data to and from strings • std::ostringstream • Write data to a string through a stream • Convenient to convert objects to strings • std::istringstream • Read data from a string • Similar to reading data from std::cin

  33. String Stream Example #include<sstream> #include<iostream> int main() { conststd::stringinputStr = "1 2 3"; std::istringstream reader(inputStr); int i, j; reader >> i >> j; std::ostringstream writer; writer << "i = " << i << " and j = " << j; std::stringoutputStr = writer.str(); std::cout << outputStr << std::endl; return 0; } Program output: i = 1 and j = 2

More Related