第二章-#include编译指令、main()函数、cout、cin、声明和使用变量、定义和使用简单函数
2.1 C++简单介绍
注释: 由前缀 “//” 标识 放在代码的上方或者同行,也可以使用C注释方法 "/* 注释的内容 */"
预处理编译指令:#include
main()函数 通常定义为 int main(); 因此需要return 0; (C++每条完整的指令需要使用分号结束)
有关头文件名的约定
头文件类型 | 约定 | 示例 | 说明 |
C++旧式风格 | 以.h结尾 | iostream.h | C++程序可以用 |
C旧式风格 | 以.h结尾 | math.h | C、C++程序可用 |
C++新式风格 | 无结尾 | iostream | C++程序可以用,需要using namespace std |
转化后的C | 加上前缀c,无结尾 | cmath | C++程序可以用,需要using namespace std |
使用 命名空间 using namespace std; 能够使用std命名空间中定义的名称 而不必使用std::前缀
// method 1
using namespace std; // 函数1和2都可以使用命名空间std
void Fnc1(){ }
void Fnc2(){ }
// method 2 // 仅函数1内部可以使用命名空间std
void Fnc1(){
using namespace std;
}
// method 3 // 仅可以使用命名空间特定对象的缩写
using std::cout;
void Fnc1(){ }
2.2 C++语句
声明语句:使用一个变量前,必须先声明,使用"="进行简单的赋值
输出语句:在使用了using namespace std;或者using std::cout;后可以使用 cout << “Hello World!”将“Hello World!”打印出来;使用’\n‘或者cout<<endl;可以添加换行
使用cout.put();可以输出一个字符;之所以有这个函数是因为Release2.0前cout无法打印单个字符
输入语句:使用cin.get();可以使得程序读取您按Enter键前所输入的内容
使用cin >> getInput; 可以读取您按Enter键前所输入的内容赋值给getInput变量,请记得提前声明该变量
2.3 函数和返回值
void代表该函数不需要返回值
第三章 处理数据-变量命名规则、整型、浮点型、const、算术运算符、自动/强制类型转化
3.1 简单变量 变量的初始化
变量名命名规则:
- 在名称中只能使用字母字符、数字和下划线
- 名称第一个字符不能是数字
- 区分大写字符和小写字符
- 不能使用C++关键字
- 以两个下划线或下划线加大写字母开头的名称保留给实现使用。使用一个下划线开头的名称用作全局标识符。
如果想用两个或者更多单词组成 一个名称,通常的做法是使用下划线字符将单词分开,例如cost_of_trip;或者从第二个单词开始将每个单词的第一个字母大写,例如costOfTrip
警告:如果不对函数内部定义的变量初始化,该变量的值是不确定的,值应为该变量创建前内存所保留的值。
在C++11中 可以使用多种初始化方式 (尽可能使用=或者{}进行初始化);使用{}称为列表初始化
int n1 = 1;
int n2(22);
int n3{33};
int n4 = {44};
int n5 = {}; // n5 = 0;
3.2 各种数据类型 sizeof() climits
数据类型 | 位数 bit | 表示范围 |
short | 16 二字节 | |
int | 16or32 二或四字节 | 四:-32768到+32767 |
long和long long | 至少64 八字节 | |
unsigned | 默认为int的无符号类型 | 也可修饰以上其他类型 |
float | 至少32 | 6位小数 |
double | 至少48 常见为64 | |
char | 8 一个字节 |
使用cout << hex; cout << oct; 将接下来输出的数打印为 十六进制 和 八进制
运算符 sizeof 和头文件 climits 使用方法: sizeof(int) 或者 int value;sizeof(value);
符号常量 | 表示 |
CHAR_BIT | char的位数 |
CHAR_MIN/CHAR_MAX | char的最大,最小值 |
SCHAR_MIN/MAX | signed char的最大,最小值 |
UCHAR_MAX | unsigned char的最大值255 |
SHRT_MIN/MAX | short的最大,最小值 |
USHRT_MAX | unsigned short的最大值 |
INT_MAX/MIN | int的最大,最小值 |
UNIT_MAX | unsigned int 的最大值 |
LONG_MAX/MIN | long 的最大,最小值 |
ULONG_MAX | unsigned long 的最大值 |
LLONG_MAX/MIN | long long 的最大,最小值 |
ULLONG_MAX | unsigned long long 的最大值 |
bool | 任何非零值都转为true,反之 |
注意:使用unsigned 修饰的并没有最小值;C++对字符变量使用单引号,对字符串变量使用双引号。
数据类型中还有一种 wchar_t表示宽字符
wchar_t tmp = L'P'; // P 的宽字符类型
wcout << L"tall" << endl; // 输出宽字符串
C++11 新增的类型 char16_t 和 char32_t
char16_t:无符号 占据16位 char32_t:无符号 占据32位
3.3 const 限定符
在C++中提供了const限定符来表示一个只读的变量 与C中的#define不同的是它能够确定常量的类型、并限定在指定的作用域中、并声明数组的长度 在定义常量时 建议使用
const int NAME = value; // 请在声明时定义 变量名全大写
3.4 算术运算符 加减乘除 取模 运算符优先级 除法的类型转化
先乘除 后加减 其中 取模%的运算优先级相同
如果两个数都为整数 那么使用除法后得到的结果也为整数,小数部分舍去;若其中某一个为浮点数,则结果为浮点数。(注意 浮点数常量在默认情况下为double类型)
自动执行的类型转化的情况:
- 将一种算术类型的值赋值给另外一种算术类型的变量
- 表达式中包含不同的类型时
- 将参数传递给函数时
使用列表初始化的时候不允许将占位多的赋值给占位小的,如float可转int,int不可转float
表达式中的转化根据以下从前往后进行执行:
- 如果有操作数类型位long double 则其他转化位logn double
- 若有double则其他转化为double
- 若有float则转化为float
- 否则,说明全部为整型,进行整型提升
- 在这种情况下,若两个操作数都为有符号或无符号的,且其中一个操作数的级别比另一个低,则转化为级别高的类型
- 若一个操作数为有符号另一个操作数为无符号,且无符号操作数的级别比有符号的高,则将有符号的操作数转为无符号操作数所属的类型
- 否则,若有符号类型可表示无符号类型的所有可能取值,则将无符号操作数转化为有符号操作数所属类型
- 否则,将两个操作数都转化为有符号类型的无符号版本
有符号整数的级别从高到底为 long long 、long 、int 、short 、signed char。无符号整型的排列顺序相同。类型 char 、signed char 和 unsigned char 的级别相同。类型 bool 的级别最低。 wchar_t 、char16_t 和 char32_t 的级别和底层类型相同。
强制类型转化
(typeName) value; // 转化类型为typeName 来自C语言
tyepName (value); // 转化类型 来自C++
// 比以上更严格的强制类型转化
static_cast<typeName> (value);
auto声明 根据初始值来推断变量类型
第四章 符合类型-(动态)数组、C风格字符串、string类、getline()和get()、结构、共用体、枚举、指针、new/delete、自动存储,静态存储,动态存储,vector类和array类
4.1 数组
数组的声明应指出以下三点:
1、存储的元素的类型 2、数组名 3、数组中的元素数目
声明数组的通用格式为:typeName arrayName(arraySize); 此处的arraySize必须为常量
int ayname[10]; // int类型数组声明,没有默认的值,存放的值为之前该内存中存放的内容
int ayname[3] = {1,2,3}; // int类型数组声明及初始化
int ayname[] = {4,5}; // int类型数组声明及初始化 不建议使用该方式
int n1 = sizeof(ayname); // 得到的 n1 = 8; 整个数组所占内存大小
int n2 = sizeof(ayname[0]); // n2 = 4; 单个元素的类型所占据的内存大小
// 在C++中数组初始化可以使用以下方式
unsigned c[10] = {}; // 所有元素被赋值为0
float f[20] {}; // 所有元素被赋值为0
long l[3] {1 2 3}; // 省略=号进行初始化
注意:不能使用数组来对另外一个数组进行声明
float arrayName[5] = {3.0, 3.3}; // 将数组的前两个元素进行初始化 其他元素被默认初始化为0
// 因此可以根据编译器默认初始化其他元素为0来对整个数组进行赋0的初始化
long totals[200] = {0};
4.2 字符串 C风格的字符串
使用char数组来表示字符串,C-风格字符串以'\0'标记为结尾,其ASCII码为0.
// 使用char数组和列表表达式对c风格string进行初始化 若省略'\0'则声明错误
char dog[8] = {'b','e','a','c','d',' ','3','a'}; // not a string
char cat[4] = {'c','a','t','\0'}; // a string
// 使用双引号进行字符串常量声明 默认将末尾添加'\0'
char dog[11] = "Mr. Cheeps"; //加上'\0'则char个数为11个
char cat[] = "some string";
注意:字符串常量(使用双引号)不能与字符常量(使用单引号)互换。字符常量(如'S')是字符串编码的简写方式。在ASCII系统上,'S'是83的另一种写法,但是"S"不是字符常量,他表示的是两个字符(字符'S'和字符'\0')组成的字符串。"S"实际上表示的是字符串所在的内存地址。
sizof(arrayName)得到的是数组的长度 多少个字节
strlen()只计算可见的字符,而不把空字符计算在内
4.3 每次读取一行字符串输入 get() 与 getline()
istream中的类提供了一些面向行的类成员函数:get()与getline()。这两个函数都读取一行输入直至换行符。然而getline()将丢弃换行符,而get()将换行符保留在输入系列中。
char name1[1024], name2[1024];
// getline() 读取换行符并将换行符换做'\0'存储
cin.getline(getInput,1024);
// get() 不读取换行符 因此每次需要保证输出流中第一个字符不为换行符
cin.get(name,1024);
// get() 提供不带参数的调用来读取换行符 因此可以使用以下方式读取两行
cin.get(name,1024);
cin.get();
cin.get(name2,1024);
// cin.getline(name.ArSize)和cin()返回一个cin对象,因此可以使用以下方式来读取两行
cin.get(name1,ArSize).get(); // 读取一行和换行符
cin.get(name2,ArSize).get(); // 读取第二行及换行符
cin.getline(name1,ArSize).getline(name2,ArSize);
getline()使用更简单一些,get()使得检查错误更简单些。使用get()后只需要检查下一个输入字符是否为换行符便可以分辨是否读取整行,分辨读取停止的原因是由于数组存满还是读取完毕。
空行和其他问题以及混合输入字符串和数字问题:
使用cin读取输入时,需要使用get()来将换行符从输出队列里读取。
4.4 string类
更详细的使用方法请参考:Mark string的相关用法-CSDN博客
要使用string类,必须在程序中包含头文件string,string类位于命名空间std中,因此必须提供一条using编译指令,或者使用std::string来引用它。
string对象与字符数组的相同点:
- 可以使用C-风格字符串来初始化string对象。
- 可以使用cin来将键盘输入存储到string对象。
- 可以使用cout来打印string对象。
- 可以使用数组表示的方法,及索引的方式访问存储在string对象的字符。
类设计让程序能够自动处理string的大小
string str;
cin >> str; // 根据输入调整str的大小
使用string类时,可以将一个string对象赋值给另一个string,但是char数组不能这样做
string类简化了字符串合并操作,可以使用“+”将两个string对象合并起来,可以使用运算符“+=”将字符串附加到string对象的末尾。
strcpy()和strcat()以及strlen()函数 :略;可以使用赋值 + 来代替
使用getline(cin,str)将输入的字符串读取到变量中(原书4.3.5 略)
4.5 结构体
结构体由关键字struct+名字+左大括号+结构成员+右大括号+分号来声明:
struct newTypeName{
int int_n[10];
char chr_n[10];
float f_n[10];
};
// 声明结构变量
struct newTypeName name1; // 在C语言中关键词struct被强制要求存在
newTypeName name2; // 在C++中可以忽略struct关键词
// 使用.来访问结构体成员变量
name1.int_n; name1.f_n;
对结构体进行初始化时可以使用如下方式:
struct animal{
string name;
float price;
float weight;
}
animal duck = {
"duck",
1.8864,
2.3553
};
// 或者使用如下方式
animal guest = {"guest",1.88,29.99};
// 或者
animal guest {"guest",1.88,29.99};
// 注意使用空列表将每个成员的每个字节设置为0
animal guest {};
对于结构体变量(注意与结构体成员变量区分开,结构体变量是被新定义的结构体类型声明的变量,结构体成员变量是结构体内部大括号里面的变量),可以使用赋值运算符(=)来将一个变量赋值给另外一个同类型的变量。注意 当某些结构体成员变量未被初始化时,将默认使用0填充内存
// 注意以下的代码 以下代码创建两个perks类型的结构体变量
struct perks{
int key;
char name[10];
} var1, var2;
// 使用以下代码 定义结构体的同时声明变量并初始化
struct s2{
string name;
int age;
} fox = {
"fox",
18
};
// 使用以下代码创建唯一一个该结构体类型的变量 之后无法再创建同类型变量
struct {
string name;
int age;
} fox = {
"fox",
18
};
重点:结构体的位字段
与C语言一样,C++运行指定占用特定位数的结构体成员,使用结构体成员变量声明并加上冒号加上指定的使用位数。每个成员称为位字段。位字段通常使用在更基础的编程中。
struct typeName{
unsigned int SN : 4; // 4 bits for SN value
unsigned int : 4; // 4 bits unused
bool flag1 : 1; // 1 bit for flag1
bool flag2 : 1; // 1 bit for flag2
};
4.6 共用体(union)
共用体(union)是一种数据格式,它能够存储不同的数据类型,但只能同时使用其中的一种类型。共用体的形式与结构体类同。
union one4all{
int int_val;
char chr_val;
float f_val;
};
one4all var;
var.int_val = 1; // store an int
cout << var.int_val; // printf 1
var.chr_val = 'a'; // store a char , and delete var.int_val;
由于共用体每次只能存储一个值,因此它必须有足够空间来存储最大的成员,所以共用体的长度为其最大成员的长度。
共用体的用途之一是,当数据项使用两种或更多种格式(但不会同时使用)时,可节省空间。一种神奇的用法之匿名共用体:匿名共用体没有名称,其成员将成为位于相同地址处的变量。显然只有一个成员是当前的成员。
struct widget{
char brand[20];
int type;
union{ // anonymous union
long id_num;
string id_string;
};
};
widget prize;
if (prize.type == 1_
cin >> prize.id_num;
else
cin >> prize.id_string;
4.7 枚举
C++的enum工具提供了创建符号常量的另一种方式,这种方式可以代替const。它还允许定义新类型,但必须按严格的限制进行。使用enum的句法与使用结构体类似:
enum spectrum {red, orange, yellow, green, blue, violet, indigo, ultraviolet};
spectrum band; // band a variable of type spectrum
band = blue; // valid blue is an enumerator
// 注意枚举类型可以转化为整型 但是整型不能转化为枚举类型 0-7
int color = band; // valid, color = 4;
// 但是可以使用强制类型转化
band = spectrum(1); // band = orange;
// 可以使用赋值运算符显示设置枚举量的值 指定的值必须为整数,也可以只显示定义其中某些枚举量的值
// 默认情况下没有指定值的枚举量比前面指定值的量大一 也可以创建多个值相等的枚举量
enum bit{one = 1, two = 2, four = 4, eight = 8};
枚举的取值范围:寻找离枚举量的值最近的2的幂 如最大值101最近的为128因此最大取值为127 最小值-3 的最近幂为 -4,因此最小取值为-3,但若枚举量都大于0则最小取值为0
4.8 指针、数组、指针算术、new和delete
该部分较为复杂且重要,将额外开篇进行记录,记录地址:4.8 指针、数组、指针算术、new和delete-CSDN博客