2024-08-10
24T2
00

目录

Q1.1. Introduction using a set diff
Answer
Q1.2. Using and Testing std::vector
Answer
Q1.3. Evolution: C to C++
Answer
Q1.4. Gotta Sort It Out
Answer
Q1.5. Catch2 Syntax
Q1.6. Constant Referencing

COMP6771 - Advanced C++ Programming

Weekly Exercise - Week 1

With my own solution (might be incorrect)

Q1.1. Introduction using a set diff

In src/1.1/setdiff.h there is a documentation for a function that removes elements in one vector from another. In the provided test stub in src/1.1/setdiff.test.cpp, write three or more unit tests for this function. Considerations include:

  • a test for invalid input
  • a test for an edge case
  • a test for the average use case

When you are happy with the tests, implement the function in src/setdiff.cpp so that your tests pass.

Answer

C++
// src/setdiff.cpp auto set_difference(std::vector<char>& vec_set, const std::vector<char>& blacklist) -> void { auto is_blacklist = [&blacklist](const char& element) -> bool { return std::find(blacklist.begin(), blacklist.end(), element) != blacklist.end(); }; auto new_end = std::remove_if(vec_set.begin(), vec_set.end(), is_blacklist); vec_set.erase(new_end, vec_set.end()); }

Q1.2. Using and Testing std::vector

One of the most widely used containers from the C++ Standard Library is std::vector. A vector is a dynamic array that looks after its own memory and allows elements to be inserted, retrieved, compared for equality, etc.

Alot can be done with a vector and the purpose of this exercise is to gain familiarity with its various operations (called member functions or methods).

In src/1.2/fib_vector.cpp, there is an incomplete implementation of a function that calculates all of the Fibonacci numbers and returns them in a std::vector<int> as well as a few failing tests. Write a proper implementation of fibonacci() and more tests so that you more become familiar and confident with using a vector (and also with testing!).

Hint: some of the most widely used methods on vectors are:

  • push_back(elem): adds an elements to the vector at the end
  • size(): returns how many elements are currently in the vector
  • empty(): returns true if and only if size() == 0 (N.B. this does not clear() the vector!)
  • at(n): get the nth element from the vector. Can also use [].

A full description of these methods can be found here.

Answer

C++
auto fibonacci(int n) -> std::vector<int> { if (n == 0) { return {}; } std::vector<int> nums(static_cast<size_t>(n), 1); if (n == 1) { return nums; } for (size_t i = 2; i < nums.size(); i++) { nums[i] = nums[i - 1] + nums[i - 2]; } return nums; }

Q1.3. Evolution: C to C++

Write a C++ program in src/1.3/cat.cpp that mimics the C program written below. The program is intended to mimic the behaviour of the UNIX command cat. For each C++ change, think about what advantages C++ provides.

Make sure you check with your tutor that your C++ code is styled according to modern guidelines.

c
#include <stdio.h> int main() { char buffer[100]; fgets(buffer, 100, stdin); printf("%s", buffer); return 0; }

Answer

C++
#include <iostream> #include <string> int main() { std::string buffer; std::getline(std::cin, buffer); std::cout << buffer << std::endl; return 0; }

Q1.4. Gotta Sort It Out

Write a function, called sort3 in src/1.4/sort3.cpp, which takes three int references and sorts them in ascending order.

Then, write two test cases in src/1.4/sort3.test.cpp to confirm that sort3 is correct.

You should then write an overload for sort3 so that it also sorts three std::string references. Don't forget to write at least two more test cases!

Answer

C++
#include <vector> #include <algorithm> auto sort3(int& a, int& b, int& c) -> void { std::vector<int> nums = {a, b, c}; std::sort(nums.begin(), nums.end()); a = nums[0]; b = nums[1]; c = nums[2]; } auto sort3(std::string& a, std::string& b, std::string& c) -> void { std::vector<std::string> nums = {a, b, c}; std::sort(nums.begin(), nums.end()); a = nums[0]; b = nums[1]; c = nums[2]; }

Q1.5. Catch2 Syntax

Answer the following questions:

  1. What is a TEST_CASE?
  • a) A TEST_CASE is a uniquely-named testing scope that must contain every test we write about our program.
  • b) A TEST_CASE is a fancy macro that has no effect in "real" code.
  • c) A TEST_CASE is a uniquely-named testing scope that will keep track of all the CHECKs and REQUIREs that pass or fail.
  • d) A TEST_CASE is a macro where only compile-time evaluable assertions about our code can be written.
  1. What is a CHECK? In what way, if any, is it different to assert()?
  • a) CHECK and assert are both macros and do the exact same thing.
  • b) CHECK and assert are both macros, but a CHECK will evaluate an expression and report it if it's false whereas assert will crash the program.
  • c) CHECK is a function that suggests a fact about our code should be true, but assert enforces it.
  • d) CHECK records the failure of an assertion but does nothing about it and is entirely unrelated to assert.
  1. What is a REQUIRE? In what way, if any, is it different to assert()?
  • a) REQUIRE evaluates an expression and crashes the program if it is false but assert will report it to the user.
  • b) REQUIRE and assert both evaluate expressions and terminate the currently executing test if false.
  • c) assert and REQUIRE both evaluate expressions, but only assert has an effect if the expression is false.
  • d) REQUIRE evalutes an expression and if false will terminate the currently executing test and move onto the next one. It is entirely unrelated to assert.
  1. What are SECTION blocks in Catch2?
  • a) SECTION blocks are ways to divide testing logic in TEST_CASEs. Any state changes in a SECTION are not reflected in SECTIONs at the same level.
  • b) SECTION blocks are a way to break up long tests and have little use other than that.
  • c) SECTIONs are unique testing scopes that can only contain TEST_CASEs.
  • d) SECTIONs are part of Behaviour Driven Development and group together SCENARIOs.
  1. What goes between the parentheses in TEST_CASEs and SECTIONs?
  • a) The function or class name that is currently being tested.
  • b) A succinct and insightful description in plain language of the code under test.
  • c) A description that matches a similarly-worded comment directly above the TEST_CASE/SECTION.
  • d) A note for future readers of your code about what you were thinking at the time of writing this test.

Q1.6. Constant Referencing

Answer the following questions:

  1. Are there any errors in this code and if so what are they?
cpp
auto i = 3; i = 4;
  • a) Yes: auto is a reserved keyword
  • b) Yes: it is illegal to initialise a variable after it is defined.
  • c) Maybe: it depends on what CPU this code is run on.
  • d) No: assignment after initialisation is legal, even in C.
  1. Are there any errors in this code and if so what are they?
cpp
const auto j = 5; --j;
  • a) Yes: j is a constant integer which cannot be modified.
  • b) Maybe: it depends if the programmer prefers east or west const.
  • c) No: decrementing a constant integer creates a new one.
  • d) Yes: auto and const should not be mixed.
  1. Are there any errors in this code and if so what are they?
cpp
auto age = 18; auto& my_age = age; ++my_age;
  • a) Maybe: it depends if the code is compiled as C++98 or C++11 or higher.
  • b) No: my_age is a reference to age, so preincrement is perfectly legal.
  • c) Yes: references are inherently const and so modifying age through my_age is illegal.
  • d) No: my_age is a copy of age and modifying my_age has no impact on age whatsoever.
  1. Are there any errors in this code and if so what are they?
cpp
auto age = 21; const auto &my_age = age; --my_age;
  • a) Yes: auto references can only be used with explicit type annotations.
  • b) Maybe: if this code is compiled with the "-pedantic" flag in GCC, it would be perfectly legal.
  • c) No: my_age is a const reference, but age is not constant, so this is fine.
  • d) Yes: my_age is a reference to a constant integer, which cannot be modified.

本文作者:Jeff Wu

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!