《Beginning C++17》-學習筆記-Chapter 02-Introducing Fundamental Types of Data
#include <iostream> int main() { //int apple_count{ 15.5 }; /*此行會導致編譯錯誤。錯誤型別是narrowing conversion。*/ int apple_count{ 15 }; /*第一種賦值形式;The braces enclosing the initial value are called a braced initializer.這種賦值形式自C++11開始引入。commonly referred to as uniform initialization. */ int orange_count( 5 ); /*第二種賦值形式;Functional notation*/ int total_fruit = apple_count + orange_count; //第三種賦值形式; assignment notation;initial value for a variable can be an expression*/ std::cout << total_fruit <<std::endl; /*輸出結果為20*/ }
#include <iostream> int main() { int counter_01 { 0 }; // counter_01 initiated to 0 std::cout << counter_01 << std::endl; int counter_02{}; /*counter_02 initiated to 0 as well;Zero initialization works for any fundamental type.For all fundamental numeric types, an empty braced initializer is always assumed to contain the number zero.*/ std::cout << counter_02 <<std::endl; }
#include <iostream> int main() { int written_with_single_quote = 1'234;/*since C++14, you can use the single quote character, ', to make numeric literals more readable. */ std::cout << written_with_single_quote<< std::endl;//輸出結果為數字 1234 int hex_num{ 0x4D2 };//hexadecimal literal is prefixed with 0x or 0X std::cout << hex_num << std::endl;//輸出結果為十進位制數1234 int octal_num{ 02322 };//hexadecimal literal is prefixed with 0x or 0X std::cout << octal_num << std::endl;//輸出結果為十進位制數1234 int bi_lit{ 0B100'1101'0010 };/*Binary literals were introduced by the C++14 standard. You write a binary integer literal as a sequence of binary digits(0 or 1) prefixed by either 0b or 0B. You can use a single quote as a separator in any integer literal to make it easier to read. */ std::cout << bi_lit;//輸出結果為十進位制數1234 }
It is defined such that, for all integers x and y, (x / y) * y + (x % y) equals x.
The result of both the division and modulus operator is undefined when the right operand is zero—what’ll happen depends, in other words, on your compiler and computer architecture.
#include <iostream>
int main()
{
int positive_num = 345;
int negtive_num = -positive_num; /*The minus sign is a unary operator and it negates the value of a variable.*/
std::cout << negtive_num<< std::endl;//輸出結果為數字 -345;
//int denominator = 0;//denominator是分母的意思
//int div_by_zero = positive_num / denominator;//這個statement可以編譯通過,但是執行程式時會導致程式出錯,中斷。
}
#include <iostream>
/* you cannot read and store spaces using the >> operator for a stream, even when you store them in variables that store characters.*/
/*When the execution sequence runs beyond the end of main(), it is equivalent to executing return 0.*/
int main()
{
int a, b, c;
std::cout << "Enter three numbers seperated by spaces.";
std::cin >> a >> b >> c;
std::cout << a << std::endl << b << std::endl << c << std::endl;
char d, e, f;
std::cout << "Enter three numbers seperated by spaces.";
std::cin >> d >> e >> f;
std::cout << d << e << f;
}
#include <iostream>
int main()
{
int x{ 1 }, y{ 10 };
x *= y + 1;//assignment operator *= 的優先順序小於 +
std::cout << x << std::endl;//輸出結果為11
x = 1;
y = 10;
x = x * (y + 1);
std::cout << x << std::endl;//輸出結果也是11
}
You can eliminate the need to qualify a name with the namespace name in a source file with a using declaration. Here’s an
example:
using std::cout;
This tells the compiler that when you write cout, it should be interpreted as std::cout. With this declaration before the main() function definition, you can write cout instead of std::cout, which saves typing and makes the code look a little less cluttered.
#include <iostream>
using std::cout;
int main()
{
char x;
cout << "Enter a character" << std::endl;//此行編譯無問題
cin >> x;//此行會導致編譯錯誤,identifier "cin" is undefined。需要在前面加上std::
}
A using directive imports all the names from a namespace. Here’s how you could use any name from the std namespace without the need to qualify it:
using namespace std; // Make all names in std available without qualification
With this at the beginning of a source file, you don’t have to qualify any name that is defined in the std namespace. At first sight this seems an attractive idea. The problem is it defeats a major reason for having namespaces. It is unlikely that you know all the names that are defined in std, and with this using directive you have increased the probability of accidentally using a name from std.
We recommend that you make use of using directives only when there’s a good reason to do so.
#include <iostream>
using namespace std; // Make all names in std available without qualification
int main()
{
char x;
cout << "Enter a character" << endl;//此行編譯無問題
cin >> x;//此行編譯無問題
}
#include <iostream>
int main()
{
int count{5};
int total;
total = count++ + 6;
std::cout << total<< std::endl;//輸出11
std::cout << count;//輸出6
}
You cannot use the unsigned or signed modifiers with floating-point types; floating-point types are always signed.
/* float literals have f (or F) appended and
long double literals have L (or l) appended. Floating-point literals without a suffix are of type double.
A floating-point literal includes either a decimal point or an exponent, or both; a numeric literal with neither
is an integer.*/
#include <iostream>
int main()
{
float pi{ 3.1415926f }; // Ratio of circle circumference to diameter
double inches_to_mm{ 25.4 };
long double root_of_2{ 1.4142135623730950488L }; // Square root of 2
}
#include <iostream>
#include <limits>
#include <cmath>
int main()
{
double a{ 1.5 }, b{}, c{};
std::cout << ::isinf(a / b); //輸出1
std::cout << ::isnan(b /c ); //輸出1
}
#include <iostream>
#include <limits>
#include <cmath>
int main()
{
std::cout << ceil(2.5) << std::endl;//輸出3;Computes a floating-point value that is the smallest integer greater than or equal to arg
std::cout << floor(2.5) << std::endl;//輸出2;Computes a floating-point value that is the largest integer less than or equal to arg
std::cout << std::round(-1.5f) << std::endl;//輸出-2;Halfway cases are rounded away from zero.
}
The area of a circle is given by the formula πr2, where r is the radius.
#include <iostream>
#include <iomanip>
int main()
{
int a{ 16 }, b{ 66 };
std::cout << std::setbase(16) << std::showbase << "a = " << a << " b = " << b << std::endl;//以16進位制顯示
std::cout << std::setbase(8) << std::showbase << "a = " << a << " b = " << b << std::endl;//以8進位制顯示
std::cout << std::setbase(10) << std::showbase << "a = " << a << " b = " << b << std::endl;//以10進位制顯示
}
With each operation with operands of different types, the compiler chooses the operand with the type
that has the more limited range of values as the one to be converted to the type of the other. In effect, it ranks
the types in the following sequence, from high to low:
1. long double 2. double 3. float 4. unsigned long long 5. long long 6. unsigned long 7. long 8. unsigned int 9. int
#include <iostream>
int main()
{
unsigned int x{ 20u };
int y{ 30 };
std::cout << x - y << std::endl;
/*You might expect the output to be -10, but it isn’t. The output is 4294967286, not -10!
This is because the value of y is converted to unsigned int to match the type of x, so the result of the subtraction is an unsigned integer value.
And -10 cannot be represented by an unsigned type. For unsigned integer types, going below zero always wraps around to the largest possible integer value.
That is, for a 32-bit unsigned int type, -1 becomes 2的32次方 - 1 or 4294967295. This of course means that -10 indeed becomes 2的32次方 - 10, or 4294967286.*/
}
#include <iostream>
int main()
{
double value1{ 10.9 };
double value2{ 15.9 };
int tot = value1 + value2;
int whole_number{ static_cast<int>(value1) + static_cast<int>(value2) };/*The static_cast keyword reflects the fact that the cast is checked statically, that is, when the code
is compiled.
Note that as with integer division, casting from a floating-point type to an integral type uses truncation.
That is, it simply discards the entire fractional part of the floating-point number.*/
std::cout << whole_number << std::endl;
}
#include <iostream>
int main()
{
std::cout << "Maximum value of type double is " << std::numeric_limits<double>::max()<< std::endl;//輸出double資料型別能代表的最大值
std::cout << "Minimum value of type signed int is " << std::numeric_limits<signed int>::min()<< std::endl;//輸出signed int資料型別能代表的最小值
std::cout << "Number of bits of type signed int(excluding the sign bit) is " << std::numeric_limits<signed int>::digits;//輸出結果為31;For signed integer types, you’ll get the number of bits in the value, that is, excluding the sign bit.
}
/*Type wchar_t is a fundamental type that can store all members of the largest extended character set
that’s supported by an implementation.
There are also escape sequences that specify a character by its code expressed as either an octal or a
hexadecimal value.The escape sequence for an octal character code is one to three octal digits preceded
by a backslash.The escape sequence for a hexadecimal character code is one or more hexadecimal digits
preceded by \x.You write either form between single quotes when you want to define a character literal.*/
#include <iostream>
#include <iomanip>
int main()
{
wchar_t wch{ L'李' };/*wide-character literal is prefixed with L*/
std::cout << std::setbase(16) << std::showbase << wch<< std::endl;/*輸出漢字李的16進位制Unicode編碼 0X674e;*/
}
Constants of any kind are called literals. All literals have a type.
Type wchar_t stores a wide character and occupies either two or four bytes, depending on your compiler. Types char16_t and char32_t may be better for handling Unicode characters in a cross-platform manner.
//設定輸出數字顯示的位數
#include <iostream>
#include <iomanip>
int main()
{
const double pi{ 3.141592653589793238 }; // Initialize constant variable
int precision;
std::cout << "Please enter the desired precision of pi (significant figures):";
std::cin >> precision;
std::cout << std::setprecision(precision);
std::cout << "\npi now is " << pi << std::endl;
}
/*the integer between the parentheses in setprecision() specifies the output precision for floating-point values, which
is the total number of digits before and after the decimal point. You can make the parameter specify the
number of digits after the decimal point—the number of decimal places in other words—by setting the
mode as fixed. */
#include <iostream>
#include<iomanip>
int main()
{
std::cout << std::setprecision(1) << 3.1415926 << std::endl;//輸出3
std::cout << std::fixed << std::setprecision(1) << 3.1415926 << std::endl;//輸出3.1
}
//不借助function,直接用基本的算數運算子計算找出兩個正整數中哪個較大,哪個較小
// Exercise 2-6. Finding the largest of two integers without comparing them.
// The expressions depend on the fact that smaller/larger will be 0 with integer arithmetic
// whereas larger/smaller will be some positive non-zero integer.
#include <iostream>
int main()
{
long a{};
long b{};
std::cout << "Enter a positive integer: ";
std::cin >> a;
std::cout << "Enter another different positive integer: ";
std::cin >> b;
// The trick is to find arithmetic expressions for each of the larger
// and the smaller of the two integers
const long larger{ (a * (a / b) + b * (b / a)) / (a / b + b / a) };
const long smaller{ (b * (a / b) + a * (b / a)) / (a / b + b / a) };
std::cout << "The larger integer is " << larger << ".\n"
<< "The smaller integer is " << smaller << '.' << std::endl;
}