Wednesday, 30 September 2020

Chapter 17 // Exercise 7, 8 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.

Chapter 17 // Exercise 7, 8

7. Write a program that reads characters from cin into an array that you allocate on the free store. Read individual characters until an exclamation mark (!) is entered. Do not use a std::string. Do not worry about memory exhaustion.
8. Do exercise 7 again, but this time read into a std::string rather than to memory you put on the free store (string knows how to use the free store for you).

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2017/Exercise%207,%208

There's no need to re-invent the wheel here as cin will do all the hardwork for you, all you need to do is supply it with a maximum stream buffer size. Back in chapter 7, we extensively used cin.get() during the creation of the calculator. cin.get() has quite a few different overloads which you can find here:

I used the c-string version istream& get(char* s,  streamsize n, char delim). This allows you to give cin a custom delimiting character (in our case !) and will read characters in and store them at the given address up to streamsize. Simples.

Technically it's cheating but he did say use cin.

As for 8, getline() also has a version that allows you to specify a delimiting character:

Tuesday, 29 September 2020

Chapter 17 // Exercise 6 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.

Chapter 17 // Exercise 6

This chapter does not say what happens when you run out of memory using new. That's called 'memory exhaustion'. Find out what happens. You have two obvious alternatives: look for documentation, or write a program with an infinite loop that allocates but never deallocates. Try both. Approximately how much memory did you manage to allocate before failing.

Fortunately, Windows happens to be a good operating system and good OS's stop your program from eating up all the ram. It got to 2GB (which is my pagefile allowance) before it crashed on a bad memory allocation.

Chapter 17 // Exercise 5 - Principles & Practice Using C++

 In this exercise I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.

Chapter 17 // Exercise 5

Write a function, char* findx(const char* s, const char* x), that finds the first occurrence of the C-style string x in s.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2017/Exercise%205

I'm not entirely sure what he meant by this so I interpreted it as "finds the first occurrence of the C++-style string in the C-Style string".

Also, he did not specify not to use the standard library on this one. There is already the function strstr() to do this that takes in two const char*. 


The actual definition of this function though is deep in the bowels of VS runtime string headers but it basically takes in two pointers to the start of the char arrays and then returns a pointer to the start of the occurrence. This means that if you print the pointer, it will print everything starting from that occurrence.

I mimicked this behaviour and also cast that const away (just like the standard library does).


Saturday, 26 September 2020

Chapter 17 // Exercise 4 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.

Chapter 17 // Exercise 4

Write a function, char* strdup(const char* c), that copies a C-style string into memory it allocates on the free store. Do not use any standard library functions.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2017/Exercise%204

With const pointers I find it really stupid that you can't change the object that the pointer is pointing at, but you can change what the pointer is pointing at. In this exercise, c can be changed to point at some random garbage address but god forbid you want to assign the pointer to a non-const pointer. Unreal has a problem with this because pretty much everything gets passed round as const pointers but this allows for people to change what it's pointing at and no one will be none the wiser because it says const in the argument parameters. A lot of programmers assume (and rightly so) that this means their arguments won't be modified in the function body.

We have a senior engineer who prefers us all to use const references as you cannot change the object OR change what it's pointing at and less mistakes can be made.

Also, strdup() is a deprecated std library function so I renamed it so it would compile.

Friday, 25 September 2020

Chapter 17 // Exercise 1, 2, 3 - Principles & Practice Using C++

In this exercise I am using Visual Studio 2017 and the std_lib_facilities header provided by Stroustrup.

Chapter 17 // Exercise 1, 2, 3

1. What is the output format of pointer values on your implementation? Hint: don't read the documentation.
2. How many bytes are there in an int? In a double? In a bool? Do not use of sizeof except to verify your answer.
3. Write a function, void to_lower(char* s), that replaces all uppercase characters in the C-style string s with their lowercase equivalents. For example, Hello, World! becomes hello, world!. Do not use any standard library functions. A C-style string is a zero-terminated array of characters. So if you find a char with the value 0 you are at the end.

Github: https://github.com/l-paz91/principles-practice/blob/master/Chapter%2017/Exercise%203

1. Addresses are printed in capitals as "010FFA44", so in hex without the 0x prefix.
2. At least on my pc an int is 32 bits (4 bytes), a double is 64 bits (8 bytes) and a bool is 8 bits (1 byte). I'm not sure if he wanted us to verify this?

3. I used some of my assembly knowledge to do this. ASCII is very clever and well thought out. When it comes to letters, lowercase characters always have their 5th bit set to 1 and uppercase characters have it set to 0; so you can easily switch between upper and lower by just inverting bit 5.

That's what I did here:
Chapter 17 // Exercise 1, 2, 3  - Principles & Practice Using C++

On line 22, we access the contents of s, then OR bit number 5 with 1. As uppercase are 0 in bit 5, when you OR 0 with 1, you get 1, so it flips the upper character to lower.

This does not affect already lower case letters or punctuation (as 1 OR 1 is 1). Some more examples:
Chapter 17 // Exercise 1, 2, 3  - Principles & Practice Using C++
You can also use char ^= (1 << 5) to toggle the bit instead of setting it once.

A warning; s will now be pointing at the end of the array. You can also do while(s[i] != 0; ++i) to avoid this (where i is the length of the array) or assign the pointer to another pointer for the function.