程序源代码地址:https://github.com/buaadf/learncpp
git:git clone git@github.com:buaadf/learncpp.git
1 整型变量
1.1 变量名
C++提倡使用有一定含义的变量名。
- 在名称中只能使用字母字符、数字和下划线;
- 名称的第一个字符不能是数字;
- 区分大小写;
- 不能将C++关键字作为变量名;
- 以两个下划线(__)或下划线和大写字母(_A)打头的名称被保留给实现(编译器及其使用的资源)使用。以一个下划线开头的名称被保留给实现,用作全局标识符;
- C++对于名称的长度没有限制,名称中所有的字符都有意义,但有些平台有长度限制。
1.2 整型
C++的基本整型有:
char、short、int、long、long long,其中每种类型都有有符号版本和无符号版本。
char类型最常用来表示字符,而不是数字。
- short至少16位;
- int至少与short一样长;
- long至少32位,且至少与int一样长;
- long long至少64位,且至少与long一样长。
#include<iostream>
#include<climits>
int main()
{
using namespace std;
int n_int = INT_MAX;
short n_short = SHRT_MAX;
long n_long = LONG_MAX;
long long n_llong = LLONG_MAX;
cout << "int is " << sizeof(int) << " bytes." << endl;
cout << "short is " << sizeof n_short << " bytes." << endl;
cout << "long is " << sizeof n_long << " bytes." << endl;
cout << "long long is " << sizeof n_llong << " bytes." << endl<< endl;
cout << "Maximum values:" << endl;
cout << "int: " << n_int << endl;
cout << "short: " << n_short << endl;
cout << "long: " << n_long << endl;
cout << "long long: " << n_llong << endl<< endl;
cout << "Minimum int value = " << INT_MIN << endl;
cout << "Bits per byte = " << CHAR_BIT << endl;
cin.get();
return 0;
}
下面是64位win10下的输出结果:
运算符sizeof返回类型或变量的长度,单位为字节,头文件climits中包含了关于整型限制的信息。
可对类型名或变量名使用sizeof,对类型名(如int)使用sizeof时,应将名称放在括号中;但对变量名(如n_short)使用sizeof是,括号是可选的。
符号常量 | 表示 |
CHAR_BIT | char的位数 |
CHAR_MAX | char的最大值 |
CHAR_MIN | char的最小值 |
SCHAR_MAX | signed char的最大值 |
SCHAR_MIN | signed char的最小值 |
UCHAR_MAX | unsigned char的最大值 |
SHRT_MAX | short的最大值 |
SHRT_MIN | short的最小值 |
USHRT_MAX | unsigned short的最大值 |
INT_MAX | int的最大值 |
INT_MIN | int的最小值 |
UINT_MAX | unsigned int的最大值 |
LONG_MAX | long的最大值 |
LONG_MIN | long的最小值 |
ULONG_MAX | unsigned long的最大值 |
LLONG_MAX | long long的最大值 |
LLONG_MIN | long long的最小值 |
ULLONG_MAX | unsigned long long的最大值 |
初始化将赋值和声明合并在一起:
int n_int = INT_MAX;
int uncles = 5;
int aunts = uncles;
int chairs = aunts +uncles +4;
如果将uncles的声明移到语句列表的最后,将导致另外两条初始化语法非法。
上面的初始化语法来自C语言,在C++中,还有一种初始化语法:
int wrents(432);
将变量声明和赋值分开,可能会带来瞬时的悬而未决的情况。
C++11初始化方式:
int emus{7};
int rheas = {12};
int rocs = {}; //变量将被初始化为0
int psychics{}; //变量将被初始化为0
1.3 无符号类型
前面介绍的4种整型都有一种不能存储负数的无符号变体,其优点是可以增大变量能够存储的最大值。
unsigned short
unsigned int
unsigned long
unsigned long long
unsigned本身是unsigned int的缩写。
程序3.2
#include<iostream>
#define ZERO 0
#include<climits>
int main()
{
using namespace std;
short sam = SHRT_MAX;
unsigned short sue = sam;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited." << endl
<< "Add $1 to each account." << endl << "Now ";
sam = sam + 1;
sue = sue + 1;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited.\nPoor Sam!" << endl;
sam = ZERO;
sue = ZERO;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited." << endl;
cout << "Take $1 to each account." << endl << "Now ";
sam = sam - 1;
sue = sue - 1;
cout << "Sam has " << sam << " dollars and Sue has " << sue;
cout << " dollars deposited." << endl << "Lucky Sue!" << endl;
cin.get();
cin.get();
return 0;
}
运行结果:
程序3.2演示了如何使用无符号类型,并说明了程序试图超越整型的限制时将产生的后果。
1.4 不同进制的整型
C++使用前一(两)位来识别进制:
- 如果第一位是1~9,则为十进制;
- 如果第一位是0,第二位是1~7,则为八进制;
- 如果前两位是0x,或0X,则为十六进制。
程序3.3
#include<iostream>
int main()
{
using namespace std;
int chest = 42; //十进制
int waist = 0x42; //十六进制
int inseam = 042; //八进制
cout << "Monsieur cuts a striking figure!\n";
cout << "chest = " << chest << " (42 in decimal)\n";
cout << "waist = " << waist << " (0x42 in hex)\n";
cout << "inseam = " << inseam << " (042 in octal)\n";
cin.get();
return 0;
}
运行结果:
默认情况下,cout使用十进制显示整数,而不管这些整数在程序中是如何书写的。
不管将整数值书写为几进制,都以二进制存储在计算机中。
如果要以十六进制或八进制的方式显示值,可以使用控制符dec、hex、oct使cout以十进制、十六进制、八进制显示整数。如程序3.4.
程序3.4
#include<iostream>
using namespace std;
int main()
{
int chest = 42;
int waist = 42;
int inseam = 42;
cout << "Monsieur cuts a striking figure!" << endl;
cout << "chest = " << chest << " (decimal for 42)" << endl;
cout << hex;
cout << "waist = " << waist << " (hexadecimal for 42)" << endl;
cout << oct;
cout << "inseam = " << inseam << " (octal for 42)" << endl;
cin.get();
return 0;
}
运行结果:
cout<<hex; cout<< oct; 这些语句不会在屏幕上显示任何内容,只是修改cout显示整数的方式。
1.5 C++如何确定常量的类型
来看一条语句:
cout << "year = " << 1492 << "\n";
程序将把1492存储为int、long还是其他整型呢?
答案是,除非有理由存储为其他类型(如使用了特殊的后缀来表示特定的类型,或者值太大,不能存储为int),否则将整型常量存储为int。
后缀:
- l或L表示该整数为long型;
- u或U表示unsigned int常量;
- ul或uL或Ul或UL或LU或…(由于小写l像1,因此最好用L)表示unsigned long常量;
- ull或Ull或…表示unsigned long long。
- 对不带后缀的十进制整数,将使用int、long或long long中能够存储概述的最小类型;
- 对不带后缀的十六进制或八进制整数,将使用int、unsigned int、long、unsigned long、long long、unsigned long long中能够存储该数的最小类型。
1.6 char类型:字符和小整数
char类型是另一种整型,能够表示目标计算机系统中的所有基本符号——字母、数字、标点符号等。
最常用的符号集是ASCII码表。
程序3.5
#include<iostream>
int main()
{
using namespace std;
char ch;
cout << "Enter a character: " << endl;
cin >> ch;
cout << "Hola! ";
cout << "Thank you for the " << ch << " character." << endl;
cin.get();
cin.get();
return 0;
}
#include<iostream>
int main()
{
using namespace std;
char ch = 'M';
int i = ch;
cout << "The ASCII code for " << ch << " is " << i << endl;
cout << "Add one to the character code: " << endl;
ch = ch + 1;
i = ch;
cout << "The ASCII code for " << ch << " is " << i << endl;
cout << "Displaying char ch using cout.put(ch): ";
cout.put(ch);
cout.put('!');
cout << endl << "Done" << endl;
cin.get();
return 0;
}
成员函数cout.put():这个函数显示一个字符。 其中句点.称为成员函数符。cout.put()的意思是通过对象cout来使用函数put()。
转义字符:
可以基于字符的八进制和十六进制编码来使用转义序列。例如,Ctr+Z的ASCII码为26,对应的八进制编码为032,十六进制编码为0x1a。将这些编码用单引号括起,可以得到相应的字符常量,如'\032','\x1a',也可以将它们放在字符串中,如”hi\x1a there"。
在可以使用数字转义序列或符号转义序列时,应使用符号序列,因为数字与编码方式有关,而符号适用于任何编码方式。
程序3.7
#include<iostream>
int main()
{
using namespace std;
cout << "\aOperation \"HyperHype\" is now actived!\n";
cout << "Enter your agent code:________\b\b\b\b\b\b\b\b";
long code;
cin >> code;
cout << "\aYou entered " << code << "...\n";
cout << "\aCode verified! Proceed with Plan Z3!\n";
cin.get();
cin.get();
return 0;
}
程序3.7使用了一些转义序列,使用振铃来提起注意,使用换行符使光标前进,使用退格字符使光标向左退一格。
wchar_t(宽字符类型)可以表示扩展字符集,iostream头文件的最新版本提供了处理wchar_t流的wcin和wcout。另外,可以通过加上前缀L来指示宽字符常量和宽字符串。下面的代码将字母P的wchar_t版本存储到变量bob中,并显示单词tall的wchar_t版本:
wchar_t bob = L'P';
wcout << L"tall" <<endl;
C++11新增了char16_t和char32_t:
char16_t长16位,无符号,用前缀u表示,如u'C'和u"be good";
char32_t长32位,无符号,用前缀U表示,如U'R'和U"dirty rat"。
1.7 bool类型
true真 false假
字面值true和false都可以通过提升转换为int类型,true被转换为1,false被转换为0:
int ans = true; //ans值为1
int promise =false; //promise值为0
任何数字值或指针值都可以被隐式转换为bool值。任何非零值都被转换为true,而零被转换为false:
bool start = -100; //start值为true
bool stop = 0; //stop值为false
1.8 const限定符
C++有一种更好的处理符号常量的方法,这种方法就是使用const关键字来修改变量声明和初始化。
const int Months = 12; //Months表示整数12
这样,便可以在程序中使用Months来代替12了(有实际意义的12)。
常量(如Months)被初始化后,其值就被固定了,编译器将不再允许修改该常量的值。
注意:应在声明中对const进行初始化。
const比#define好,首先,它能明确类型;其次,可以使用C++的作用域规则将定义限制在特定的函数或文件中;第三,可以将const用于更复杂的类型,如数组和结构。
浮点类型是C++的第二种基本类型,可以表示带小数点的数字。计算机将这样的值分为基准值和缩放因子两部分。
如3.14159和314.159只是小数点位置不同,它们的基准值都是0.314159,而只是缩放因子(10和1000)不同,缩放因子的作用是移动小数点的位置,浮点因此得名。
2 浮点数
2.1 浮点数的书写方式
第一种是标准小数形式:12.34,0.006,3.1415926,8.0
第二种是指数表示法(E表示法):2.52e10,7E5,-9.11e-11 ( E6表示10的6次方)
2.2 浮点类型float、double、long double
float、double、long double表示不同长度的有效数字:
- float至少32位;
- double至少48位,且不少于float;
- long double至少和double一样。
另外,这三种类型的指数范围至少是-37到37。可以从头文件cfloat或float.h中找到系统限制。
程序3.8
#include<iostream>
int main()
{
using namespace std;
cout.setf(ios_base::fixed, ios_base::floatfield);
float tub = 10.0 / 3.0;
double mint = 10.0 / 3.0;
const float million = 1.0e6;
cout << "tub = " << tub;
cout << ", a million tubs = " << million * tub;
cout << ",\nand ten million tubs = " << 10 * million * tub << endl;
cout << "mint = " << mint << " and a million mints = " << million * mint << endl;
cin.get();
cin.get();
return 0;
}
运行结果:
cout.setf(ios_base::fixed, ios_base::floatfield); 迫使输出使用定点表示法,以便更好的了解不同类型的精度,防止程序把较大的值切换为E表示法,并使程序显示小数点后6位。
从运行结果可以看出float和double类型表示不同长度的有效数字。
2.3 浮点常量
默认情况下,8.24和2.4E8这样的浮点常量都属于double类型;
如果希望常量为float类型,应使用f或F后缀;
如果希望常量为long double类型,应使用L后缀。
2.4 浮点数的优缺点
优点:可表示整数之间的值,表示范围大;
缺点:浮点运算的速度慢,精度低。
程序3.9
#include<iostream>
int main()
{
using namespace std;
float a = 2.34e22f;
float b = a + 1.0f;
cout << "a = " << a << endl;
cout << "b - a = " << b - a << endl;
cin.get();
return 0;
}
运行结果:
程序3.9说明了浮点运算的精度较低。