Tuesday, 31 October 2023

Chapter 27 // Exercise 14 - Principles & Practice Using C++

In this exercise I'm using Visual Studio 2022 and ISO C11 Standard.

Chapter 27 // Exercise 14

Write a function that takes an array of ints as its input and finds the smallest and the largest elements. It should also compute the median and mean. Use a struct holding the results as the return value.

Ah finally, a nicer "easy" one. This reminded me a lot of the exercises we did way back in chapter 4. God, that feels like a lifetime ago.

Monday, 30 October 2023

Chapter 27 // Exercise 13 - Principles & Practice Using C++

In this exercise I'm using Visual Studio 2022 and ISO C11 Standard.

Chapter 27 // Exercise 13

Write a program that does the equivalent of strings; cin >> s; in C; that is, define an input operation that reads an arbitrarily long sequence of whitespace-terminated characters into a zero-terminated array of chars.

I was a bit confused on this one as cin stop reading in characters when it encounters whitespace; have to use getline() to include the whitespace. So with the statement "define an input operation that reads an arbitrarily long sequence of whitespace-terminated characters" I decided instead he meant more of a getline() so we include whitespace characters. So if you were to type "this is a sentence", it captures the entire sentence and prints "this is a sentence". Maybe that's not what he meant though.

Sunday, 29 October 2023

Chapter 27 // Exercise 12 - Principles & Practice Using C++

In this exercise I'm using Visual Studio 2022 and ISO C11 Standard.

Chapter 27 // Exercise 12

Implement a (C-Style string, int) lookup table with operations such as find(struct table*, const char*), insert(struct table*, const char*, int) and remove(struct table*, const char*). The representation of the table could be and array of a struct pair or pair of arrays (const char*[] and int*); you choose. Also choose return types for your functions. Document your design decisions.

I originally did a really simple hash function however ended up with collision in the table quickly. I did some searching around and came across the terms "linear probing" where we keep going through slots to find a new one, wrapping round to beginning if needed.

The implementation isn't perfect but it'll do. For my design decisions:

Representation: I chose an array of struct pairs because it keeps the key-value pairs together, which makes it more intuitive.

Return Types: For find(), I return the int value associated with the key. If the key isn't found, I' return a special value, like -1.
For insert(), I return 0 if the insertion was successful and -1 if not (for example, if the table is full).
For remove(), I return 0 if the key was successfully removed and -1 if the key was not found.

Handling Collisions: For simplicity, I handled simple collisions only. This means the table has a fixed size, and if it's full, you can't insert more items.

Capacity: The table has a fixed size, which for this example, is set to 100. it will wrap round to find free slots but after that it won't insert any more.

Saturday, 28 October 2023

Chapter 27 // Exercise 10, 11 - Principles & Practice Using C++

In this exercise I'm using Visual Studio 2022.

Chapter 27 // Exercise 10

Make a list of C language features adopted from C++ or C with Classes (section 27.1).

Github: N/A

  1. Inline Functions: Initially a C++ thing, it lets you suggest to the compiler that a function should be inlined for performance.
  2. Single-line Comments: I believe // was first used in B, then brought back in C++ because /**/ is tedious.
  3. Variable Declaration Anywhere: Instead of only at the beginning of blocks, you can now declare variables anywhere in C, much like in C++.
  4. Mixed Declarations and Code: Kinda related to the previous one. You can intermix variable declarations with executable code.
  5. Boolean Type (_Bool or bool with stdbool.h): I was shocked the first time I tried to use a bool in C and found out it had to be added to the language in C89.
  6. Compound Literals: Lets you create temporary structures or arrays in the middle of an expression, similar to how you'd do in C++.
  7. Designated Initializers: A more expressive way to initialize struct or array members.
  8. Static Assertions (_Static_assert): Helps catch errors at compile-time based on constant expressions.

Chapter 27 // Exercise 11

Make a list of C language features not adopted by C++.

Github: N/A

Had to look these ones up. It was actually very interesting.
  1. Complex Number Support (_Complex and _Imaginary): C has built-in support for complex numbers, while C++ relies on the std::complex template class.
  2. Different Treatment of inline Functions: In C, an inline function's definition can be present in multiple translation units. In C++, inline functions have external linkage by default, but in C they have internal linkage.
  3. Allowing Implicit Function Declarations: Older versions of C allowed functions to be called without a previous declaration (not recommended, though!). C++ never allowed this.
  4. Named Address Spaces: Some C compilers for specific platforms (like embedded systems) support this feature, but it's not a part of C++.
  5. Non-constant Aggregate Initializers: In C, global and static aggregates can be initialized with non-constant values. C++ doesn't allow this.

Friday, 27 October 2023

Chapter 27 // Exercise 9 - Principles & Practice Using C++

In this exercise I'm using Visual Studio 2022.

Chapter 27 // Exercise 9

Using only C facilities, including the C standard library, read a sequence of words from stdin and write them to stdout in lexicographical order. Hint: The C sort function is called qsort(); look it up somewhere. Alternatively, insert the words into an ordered list as you read them. There is no C standard library list.

I could not get EOF to work in the slightest with scanf and ctrl+z. I decided to go with the qsort approach because no thank you to the list, so you have to enter the max amount of words to get it to quite the loop. Sometimes it would register the EOF, sometimes it wouldn't, sometimes I had to spam it on the keyboard and it would eventually register it.

Thursday, 26 October 2023

Chapter 27 // Exercise 8 - Principles & Practice Using C++

In this exercise I'm using Visual Studio 2022.

Chapter 27 // Exercise 8

What is the lexicographical order on your machine? Write out every character on your keyboard together with its integer value; then, write the characters out in the order determined by their integer value.

Ah finally, a nice "easy" one. Although I kind of cheated. I basically just looped through the ascii table from 0 to 255 and printed everything. I think maybe he wanted us to actually write a string and fill it with the actual characters on our keyboard but I have no idea how to get special characters out of my keyboard so I just left it to the for loop.

Wednesday, 25 October 2023

Chapter 27 // Exercise 6, 7 - Principles & Practice Using C++

In this exercise I'm using Visual Studio 2022.

Chapter 27 // Exercise 6

Change the representation of Link and List from section 27.9 without changing the user interface provided by the functions. Allocate Links in an array of links and have the members first, last, pre, and suc be ints (indices into the array).

I honestly had no idea what he meant when I read this so I asked ChatGPT to explain it to me like I'm 5. It was very helpful and I realised that what he wanted us to do was kind of create a vector where you can traverse the list via an index and then access the data at that index.

I had a stab at it for a couple of hours but honestly, my head just wasn't in it. I cannot stand anything to do with linked lists, never mind linked lists in C. So I left it half finished. The code I linked above kind of works but it also kinda doesn't.

Chapter 27 // Exercise 7

What are the advantages and disadvantages of intrusive containers compared to C++ standard (non-intrusive) containers? Make a list of pros and cons.

Github: N/A

I won't write an entire essay but from what I've seen intrusive containers would've been very normal back when C ruled the land. They're extremely lightweight versions of C++ templated containers, only you don't get the flexibility/generic-ness of the templated container but you get better performance. 

I suppose they would be useful in embedded systems where you know exactly what you're working with and have specific memory constraints. 

Tuesday, 24 October 2023

Chapter 27 // Exercise 4, 5 - Principles & Practice Using C++

In this exercise I'm using Visual Studio 2022.

Chapter 27 // Exercise 4

If you didn't already, write a C++ version of the intrusive List example in section 27.9 and test it using every function.

This took me a good hour. I still hate linked lists. For this one I decided to make the list templated instead of Name storing a linked list. All the functions are now part of the list and I considered having it use a std::unique_ptr but in the end decided to just go with new and delete as the whole point of an intrusive list is to be as efficient as possible.

Chapter 27 // Exercise 5

Compare results of exercises 3 and 4.

Github: N/A

I think it's obvious that I much prefer exercise 4. I don't like having all the functions on their own, the classes aren't managing their own memory and the syntax to create new ones of different types is just hideous.