C++/Hello I have some c++ questions.
Okay well I am teaching myself C++. I'm currently reading "Sams Teach Yourself C++". Anyway, I've come across many questions. I've learned the parts of a program, learned what a preprocessor directive is, learned what namespaces are and the std library, learned cout and cin, I learned how to create a fucntion, call a function, declare a variable, set a value to a variable, etc etc. Well I JUST got to the variable types. I was using int all along because that is what the book was using. I have some questions regarding some of these variable types. My questions are:
1)What is the main difference between unsigned and signed integers? I don't think I'm understanding it right.. One only allows positive, the other negative integers? Why would they have separate types for this? Why wouldn't it just be easier to have one type that supports both? If they do have something like that then why do these two exist?
2) What is bool exactly? What could I use it for? I understand it is "true or false" but what can I really do with bool?
3)Float and double. These two are confusing the hell out of me. I'm stressing over what these are for... I know these integers can have decimals in them.. but what is the difference between these two? Again.. could you please give me a scenario where Float/double would/could be used?
I picked this book up from the library 2 days ago.Would you say I'm over-thinking everything? I feel like I'm not understanding because I'm thinking it is soooo much harder than it is. I also feel like sometimes I do not understand because of how the book words certain stuff... ugh... Well I plan to go to college next year for software development. But I want to learn c++ and have a very good understanding of it and be able to write my own stuff before then.. I was told once you learn c++ other languages would be easier to learn. Thank you soooo much!
I'll start with you last point:
No you are not over thinking these things.
As you seem to be just starting out there is a lot of details we old hands take for granted, but obviously you have to find these things out for yourself at some point!
One thing you should appreciate about C++ is that as well as being a reasonably good application programming language it is also intended to be used as a system programming language - i.e. one that you can write operating systems and the like in. One of its goals it that there is no need for a language other than C++ to do such system level things (Java for example has the Java Native Interface to interface Java with C code and the like for those times when you need to do lower level or system things).
Another point to get used to is that the Internet, and the WWW in particular has lots and lots of information on such technical things - Google, or whatever your search engine of choice is you friend here, and for such foundational topics as you are likely to come across in you immediate pursuit of programming / computing enlightenment is Wikipedia. Do not be surprised that I refer you to various articles for greater information. I also recommend you that you perform your own searches for supporting information.
1/ Signed / unsigned integers
You make a good point - why have both and not just one type (i.e. signed integers) that handle both. In fact some languages do just this - Java I think only supports signed integers.
However signed values are represented at the machine level differently from unsigned values - and there is more than one signed integer format. See for example:
The most common format - and the one you will most certainly find in use on PCs, tablets etc. - is two's complement. Because signed values have to encode the signedness information they will have a lower maximum positive number they can represent - typically around half that of an unsigned value of the same word bit size.
Sometimes we are not really interested in the value a word in memory represents but the various bits within the word might have meaning. When treating values as just a bunch of bits it is much safer to work with them using unsigned operations. This one of those low level system things that C++ - and C - are meant to be good at so it is unsurprising that both signed and unsigned integer types are supported.
Shifting bits within a word from the most significant toward the least is one example where processors usually support signed and unsigned operation variants. If using unsigned the bit notionally shifted into the space left by the vacating most significant bit (MSB) will be written as 0, while if done as a signed number will be left as the value of the MSB (assuming 2's complement signed integer representation), which will be 1 if the value is negative or 0 if not. In fact if the shift is by more than one bit position then all the intervening places will be so sign-extended. Example (using 8-bit words - commonly called bytes - for brevity):
MSB -> 10101010 <- Least Significant Bit (LSB)
10101010 shifted right one bit as UNSIGNED -> 01010101 and we loose the 1 in the LSB position.
10101010 shifted right 3 bits as UNSIGNED -> 00010101 and we loose the LS 3 bits.
00001111 shifted right 3 bits as UNSIGNED -> 00000001 and we loose the LS 3 bits.
10101010 shifted right one bit as SIGNED -> 11010101 and we loose the 1 in the LSB position.
10101010 shifted right 3 bits as SIGNED -> 11110101 and we loose the LS 3 bits.
00001111 shifted right 3 bits as SIGNED -> 00000001 and we loose the LS 3 bits.
In this case the C and C++ operators for right shift are only portably defined for positive values (i.e. unsigned or signed positive values), the exact wording in the C++11 standard is:
"The value of E1 >> E2 is E1 right-shifted E2 bit positions. ...
If E1 has a signed type and a negative value, the resulting value is implementation-defined."
This is dome because processors differ in exactly what such an operation does (maybe some processor does not support sign-bit extending 'signed' right shift operations at all).
In other cases however, the selection of unsigned over signed integer values is less clear cut. Size of something for example is obviously ever only a positive value, and so using an unsigned integer type to represent a size seems logical - until you try to subtract two sizes which of course may result in a negative value! C++ compilers often warn about mixing signed and unsigned arithmetic as the results can be surprising. In twos complement storing the result of 3 - 2 (i.e. -1) in an unsigned integer results in a value that is the maximum value of the type (i.e. all bits are 1) - thus such negative signed values interpreted as unsigned frequently result in very large positive values - something the code logic often is not expecting and does not handle correctly - oops a bug!
Decisions are based on true/false results of expressions, for example:
if I have at least one orange eat it
else if I have at least one apple eat it
else if I have any other food eat that
Can be represented like so:
if ( number_of_oranges > 0 )
else if ( 0 < number_of_apples )
else if ( have_any_other_food() )
number_of_oranges > 0
0 < number_of_apples
Result in Boolean (i.e. bool) values - or values that can be converted to bool.
have_any_other_food() is a call to the function have_any_other_food(). We presume, as I have not really though much about it, that have_any_other_food() returns a bool - i.e. it returns true if there is some other food or false if there is not.
One thing that people do not get at first is that we can store the results of Boolean expressions in variables:
bool have_fruit = number_of_oranges > 0;
and can modify them:
have_fruit = have_fruit || 0 < number_of_apples;
Will be the logical OR of the previous value of have_fruit (i.e. true if there are some oranges, false if there is not) and whether there are any apples.
Other uses of bools are as state flags:
busy = ... // logic to see if still busy having a true or false result
Presumably determining if the loop should continue (i.e. still busy) occurs while in the middle of the repeated logic and so has to be stored.
3)Float and double.
First these types are _not_ integers.
They represent floating point arithmetic types and are used to approximate real numbers. See for example:
The difference between float, double and long double is similar to that of short, int, long and long long - they are used to specify range and precision required: float the least, long double the most. Note that like the integer types all that is required is that the next 'bigger' type is at least at 'big' as it immediate 'smaller' type or, as it says in the standard:
"The type double provides at least as much precision as float, and the type long double
provides at least as much precision as double. The set of values of the type float is
a subset of the set of values of the type double; the set of values of the type double
is a subset of the set of values of the type long double."
Typically float is a 32-bit value and double a 64-bit. The long double type is often the same as the double type but might be 80-bits or maybe even 128 bits in size.
Floating point types are useful when performing scientific, engineering or mathematical calculations where integers just do not cut it - i.e. wherever you might use real numbers outside of a computer. One area that might be of interest to you is 3D graphics, where coordinates are often specified using float values.
Floating point operations are trickier than integer operations, are handled by different processor functional units - FPUs (floating point units) that not all processors possess - particularly older or less powerful embedded processors making them much slower than integers to process on such beasts. They also have lots of gotchas for the unwary!
Sorry to go on at such length but hope there is enough here to lead you to further knowledge.
ps: sorry, did not have time to fully proof read before posting - so apologies for any typos etc.