Some beginner questions.
I have just recently started to slowly read through "Accelerated C++" in an attempt to learn C++. However, I've came across a couple of things that I don't quite understand and hoping that someone will be able to help me.
In chapter one (1.1) it talks about the input/output buffer, but I don't really understand a couple of things about it. Why does it save my text into a buffer and not output it directly to the console? And I also read that you need to flush the buffer for your text to be outputted to the console, does this mean I need to flush it every time I want to output text?
And in chapter two (2.3) it talks about loop invariants. What exactly is a loop invariant and why do I need to know about it? I've read it over and over and even looked on other websites for their definitions and examples but I still don't get it.
I'm sorry for asking these things but I really like to understand absolutely everything about the subject I'm learning.
The reason for the buffer is the same as you don't buy a glass of milk in the shop each time you want a glass of milk - you buy a few pints at a time.
In the computer case, each character is a glass of milk, and the buffer is a big bottle, and the shop is the operating system. There is a certain amount of time consumed for every call to the OS, just like it takes you time to get to the shop if you want milk. But if we save away a few characters to a bufffer, and THEN ask the OS to print the whole lot at once, we get the same overhead for a whole bunch of characters.
The short answer for using a buffer is "performance".
Originally Posted by Meikj
Writing output to a file/screen/terminal/device has all the overhead associated with interfacing to that device. That overhead is (within certain design limits limits) often the same or comparable whether a single character is written or a larger number of characters. A buffer, however, is just an area of memory. The speed of memory access, however, is much larger than the speed of accessing other devices - because RAM is physically located on the system bus (limited cabling to get in the way), is a short electrical distance from the CPU, etc etc. That differential between memory access speed and speed of accessing other devices is sufficient to give a performance gain: instead of writing small pieces of data to the device, write them to memory and later copy the memory in one larger chunk to the device.
Flushing the buffer is the act of forcing the output to be transferred from the buffer to the intended device, subsequently allowing the buffer to be used for new data.
File streams tend to flush the buffer automatically when needed (eg when the buffer is full). The act of closing or (in C++) destroying streams also implicitly flushes them. In many applications, it is not necessary to flush a buffer .... flushing will eventually happen if all goes well. Some streams (eg stdin and stdout) are also synchronised in pairs so an attempt to read from one causes flushing of output to the other - which means that a prompt can be written to stdout, and the user will see it before the system expects the user to type in data.
However, sometimes, the automatic (or implicit) flushing of streams is insufficient, so explicit flushing has to happen. For example;
1) Should the system crash, the data in any buffers gets lost without ever being written to the file/screen/whatever. If it is critical not to lose that data, then it needs to be explicitly flushed (eg the application forces the streams to be flushed every two seconds, to guarantee that no more than two seconds worth of data is ever lost).
2) With screen output, the user needs to see indicators of progress of lengthy operations as they occur rather waiting for output to be flushed. Buffering can cause the system to appear, to the user, like no progress is occurring but, at the end, suddenly a lot of progress seems to happen at once. Explicit flushing at key progress points ensures progress is reported more accurately.
So the decision "to flush or not to flush" comes down to needs of your program.
An invariant is some property that never changes. A loop invariant is some property that must always be true before, during, or after the loop, otherwise the loop can't be proven to do what is intended.
Originally Posted by Meikj
Consider the simple loop;
The termination condition is x < 10. Let's say that we also have a requirement (in the form of a postcondition) that x will always have the value 10 after the loop, otherwise the code is considered incorrect (eg some later code will function incorrectly if it receives x with a value of 11). To prove this code works as intended, we have to define some testable property that has to be true before, during, and after the loop. One such property is (x <= 10) ... it must be true before the loop, during the loop, and after the loop otherwise we can't prove that the loop has functioned correctly or that changes made by the loop won't cause other code to fail. That condition (x <= 10) is a loop invariant.
while (x < 10)
Other loop invariants are also possible. For example, should do_something_wonderful() require that x >= 0, then the condition (x >= 0 && x <= 10) is also an applicable loop invariant but (x <= 10) is no longer. If code before the loop sets x to be -5, then the loop cannot be proven to function correctly.
Note that this has nothing to do with testing: the point is being able to analyse a program and prove it is correct.
Thanks, I understand now. For some reason I can't cope just knowing the syntax. I need to know what it does, how it does it and why it does it! Ha ha.