IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ Primer Plus 笔记(3~4章) -> 正文阅读

[C++知识库]C++ Primer Plus 笔记(3~4章)

3 处理数据

3.1 简单变量

3.1.1 命名规则

  • 在名称中只能使用字母字符,数字,下划线

  • 名称的第一个字符不能是数字

  • 区分大写字符与小写字符

  • 不能将C++关键字用作名称

  • 以两个下划线打头或以下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用。以一个下划线开头的名称被保留给实现,用作全局标识符

  • C++对于名称的长度没有限制,名称中所有的字符都有意义,但有些平台有长度限制

3.1.2 整型

  • short 至少16位

  • int 至少与short一样长

  • long 至少32位,且至少与int一样长

  • long long 至少64位,且至少与long一样长

3.1.3 编程特性

运算符sizeof和头文件limits

cout << "int is" << sizeof (int) << "bytes.\n";
cout << "short is" << sizeof n_short << "bytes.\n"; //对变量名使用时括号可不加

以下为climits中的一些符号常量

符号常量表示
CHAR_BITchar的位数
CHAR_MAXchar的最大值
CHAR_MINchar的最小值
SCHAR_MAXsigned char的最大值
SCHAR_MINsigned char的最小值
UCHAR_MAXunsigned char的最大值
INT_MAXint的最大值
INT_MINint的最小值
USHRT_MAXunsigned char的最大值

C++11的初始化方式

int emus{7};
int rheas = {12};
int psychics{} //表示它初始化为0
int rocs = {} //同上

3.1.4 无符号类型

4种整型都有对应的无符号变体,可以增大变量所能存储的最大值。如short的范围为-32768~32767,而无符号版本为0~65535

要创建无符号版本的基本整型,只需使用关键字unsigned来修改声明即可

unsigned short change;
unsigned int rovert;
unsigned quarterback // 默认为int类型

3.1.5 选择整型类型

通常,int被设置为对目标计算机而言最为“自然”的长度。自然长度指的是计算机处理起来效率最高的长度

如果变量表示的值不能为负,则可以使用无符号类型

如果知道变量可能表示的值超过16位,则使用long,即使在32位系统上也可以这样做,这样,移植到16位系统时就不会无法工作。如果超过29亿,则使用long long

通常,仅当有大型整数数组时,有节省内存的需求时,才有必要使用short

3.1.6 整型字面值

十进制:第一位为1~9

八进制:第一位为0,第二位为1~7

十六进制:前两位为0x或0X

int chest = 42;
int inseam = 042;
int waist = 0x42;

cout的特性

#include <iostream>
using namespace std;
int main()
{
    int chest = 42;
    int waist = 42;
    int inseam = 42;
?
    cout << "chest = " << chest << endl; //十进制
    cout << hex; //切换为16进制
    cout << "waist = " << waist << endl; //16进制
    cout << oct; //切换为8进制
    cout << "inseam = " << inseam << endl; //8进制
    return 0;
}

3.1.7 char类型:字符和小整数

#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++;
    i = ch;
    cout << "The ASCII code for " << ch << " is " << i << endl;
?
    cout << "Displaying char ch using cout.put(ch): ";
    cout.put(ch);
}

成员函数cout.put()

提供了另一种显示字符的方法,可以代替<<运算符

常见转义字符

字符名称C++代码
换行符\n
水平制表符\t
垂直制表符\v
退格\b
回车\r
振铃\a
反斜杠\\
问号\?
单引号\'
双引号\"

signed char 和 unsigned char

unsigned char 类型的表示范围通常为0~255,而signed char 的表示范围为-128~127

char 在默认情况下既不是没有符号,也不是有符号,是否有符号由C++决定,但可以显式地设置

wchar_t

wchar_t可以表示扩展字符集,它的类型时一种整数类型,有足够的空间,与另一种整型(底层[underlying]类型)的长度和符号属性相同

cin和cout将输入输出看作是char流,因此不适于用来处理wchar_t类型。iostream头文件中提供了功能相似的工具——wcin和wcout,可用于处理wchar_t流,另外,可以通过加上前缀L来指示宽字符常量和宽字符串

wchar_t bob = L'P';
wcout << L"tall" << endl;

3.1.8 bool类型

bool is_ready = true;
?
bool start = -100; //非零数均为true
bool stop = 0;  //false

3.2 const限定符

使用const关键字来修改变量声明和初始化,是处理符号常量的一种方法

const int Months = 12; //Months值被固定,不可更改

注意:尽量要在声明中进行初始化

3.3 浮点数

3.3.1 书写浮点数

2.52e+8;
8.33E-4;
7E5; //和7E+5相同
-18.32e13 //前面可以有正负号(指数值的正负)

3.3.2 浮点数类型

  • float至少32位

  • double至少48位,且不少于float

  • long double至少和double一样多

#include <iostream>
int main()
{
    using namespace std;
    cout.setf(ios_base::fixed, ios_base::floatfield);
    float tub = (10.0 / 3.0)*1e6;   //6位
    double mint = (10.0 / 3.0)*1e6; //15位
    cout << "tub = " << tub << "\n";
    cout << "mint = " << mint;
}
?
?
/*
结果:
tub = 3333333.250000
mint = 3333333.333333
*/

cout会删除结尾的0,调用cout.setf可以将这种行为覆盖,另外cout只会打印后6位

3.3.3 浮点数常量

通常,浮点数常量默认为double型,但可以添加后缀进行更改

1.23f;	//float
1.24F;	//float
2.23L;	//long double
2.24l;	//long double

3.4 C++算术运算符

3.4.1 运算符优先级和结合性

算术运算符的优先级遵循代数优先级,如果优先级相同,则考虑操作数的结合性,乘除法都是从左向右结合的

但当操作数不同时,则规则不适用

3.4.2 除法分支

当使用“ / ”时,如果两个操作数都是整数,则小数部分将被丢弃,否则不会

3.4.3 类型转换

强制类型转换

(long) thorn;
long (thorn);

以{}的方式初始化时进行转换

char c = {66};

int x = 66;
char c = {x}; //报错,x是变量

4 复合类型

4.1 数组

数组声明应指出以下三点:

  • 存储在每个元素中的值的类型

  • 数组名

  • 数组中的元素数

short months[12];

4.1.1 数组的初始化规则

  • 只有在定义数组时才能使用初始化,此后就不能使用了,也不能将一个数组赋值给另一个数组,但可以给元素赋值

  • 初始化时,提供的值可以少于数组的元素数目,其他元素为0

  • 如果【】中为空,则数组大小为{ }内元素个数

4.1.2 C++11的一些特性

double earnings[4] {1,2,4,3}; //省略等号
?
unsigned int counts[10] = {}; //设置为0
float balances[100]{};
?
char plifs[] = {25,92,3.0}; //报错,列表初始化禁止缩窄转换
char slifs[4] = {'h','i',1122011,'\0'}; //同上

4.2 字符串

C++处理字符串的方式有两种,一种来自C语言,被称为C风格字符串,本章先介绍它

C风格字符串具有一个特殊的性质:以空字符结尾,空字符被写作\0,其ASCII码为0,用来标记字符串结尾

用引号括起的字符串隐式地包括结尾的空字符,另外,C++对字符串长度没有限制

4.2.1 拼接字符串常量

任何两个由空白(空格,制表符和换行符)分割的字符串常量豆浆自动拼接成一个

cout << "I'd give my right arm to be" "a great violinist.\n";

4.2.2 在数组中使用字符串

#include <iostream>
#include <cstring>
int main()
{
    using namespace std;
    const int size = 15;
    char name2[size] = "C++owboy";
}

4.2.3 字符串输入

cin使用空白(空格,制表符和换行符)来确定字符串的结束位置,这意味着cin在获取字符数组输入时只读取一个单词。读取该单词后,cin将该字符串放到数组中,并自动在结尾添加空字符

另一个问题是,输入字符串可能比目标数组长,使用cin不能防止将包含30个字符的字符串放到29个字符的数组中的情况发生

4.2.4 每次读取一行字符串输入

面向行的输入:getline( )

它使用通过回车键输入的换行符来确定输入结尾,函数中有两个参数,数组的名称以及读取字符数,例如:

cin.getline(name,20); //将姓名读入到一个包含20个元素的name数组中

函数最多读19个字符,余下空间用于存储自动在结尾处添加的空字符

面向行的输入:get( )

与前者大致相同,但get并不再读取并丢弃换行符,而是将其留在输入队列中

解决方法:使用cin.get( )读取换行符

cin.get(name,Arsize);
cin.get();
cin.get(dessert,Arsize);

也可以将两个类成员函数拼接起来,如下所示:

cin.get(name,Arsize).get();

cin.get(name,Arsize)返回一个cin对象,该对象随后将被用来调用get(),同理:

cin.getline(name1,Arsize).getline(name2,Arsize); //把连续输入的两行分别读入两个数组中

空行和其他问题

当get()读取空行后将设置失效位,接下来的输入将被阻断,可以用下面的命令来恢复输入:

cin.clear();

如果输入行包含的字符数比指定的多,则getline()和get()将把余下的字符留在输入队列,而getline()还会设置失效位,并关闭后面的输入

4.2.5 混合输入字符串和数字

#include <iostream>
int main()
{
	using namespace std;
	cout << "What year was your house built?\n";
	int year;
	cin >> year;
	cout << "What is its street address?\n";
	char address[80];
	cin.getline(address, 80);
	cout << "Year built : " << year << endl;
	cout << "Address: " << address << endl;
	return 0;
}

在上述程序中,用户无法输入地址。当cin读取年份,将回车键生成的换行符留在了输入队列,后面的cin.getline看到换行符后,默认为空行,将空字符串赋值给address,解决方法是把换行符读取并吃掉

//运用get()
cin >> year;
cin.get();
//也可以拼接
(cin >> year).get();

4.3 string类简介

使用string对象的方式与使用字符数组相同:

  • 可以使用C风格字符串来初始化string对象

  • 可以使用cin来将键盘输入存储到string对象中

  • 可以使用cout来显示string对象

  • 可以使用数组表示法来访问存储在string对象中的字符

string对象和字符数组的主要区别是,可以将string对象声明为简单变量,而不是数组

string str1;
string str2 = "panther";

另外,程序可以自动处理string大小

4.3.1 C++11字符串初始化

char first_date[] = {"Le Chapon Dodu"};
char second_date[] {"The Elegant Plate"};
string third_date = {"The Bread Bowl"};
string fourth_date {"Hank's Fine Eats"};

4.3.2 赋值,拼接,附加

string str1;
string str2 = "panther";
str1 = str2; //可以直接赋值
str3 = str1 + str2; //可以用‘+’拼接
str3 += str1; //附加

4.3.3 string类的其他操作

一些C风格字符串的操作:

strcpy(charr1,charr2);  //copy
strcat(charr1,charr3);  //附加在末尾
?
int len = strlen(charr4); //长度
int len2 = str4.size(); //同上

4.3.4 string类I/O

getline(cin,str);

这里没有用句点表示法,表明这个getline()不是类方法,它将cin作为参数,指出到哪里去查找输入

另外,由于string对象自动调整大小,故不需要指出参数,也可以采用下述方法:

cin >> str;

4.4 结构体简介

结构体是一种比数组更灵活的数据格式,因为同一个结构可以存储多种类型的数据

4.4.1 在程序中使用结构体

#include <iostream>
struct inflatable
{
	char name[20];
	float volume;
	double price;
};

int main()
{
	using namespace std;
	inflatable guest =
	{
		"mrc",
		1.88,
		29.99
	};
	inflatable pal =
	{
		"xzq",
		3.12,
		32.99
	};
	cout << "Expend your guest list with " << guest.name;
	cout << " and " << pal.name << "!\n";
	cout << "You can have both for $";
	cout << guest.price + pal.price << "!\n";
	return 0;
}

结构体声明可以放在main()函数内,也可以在外部声明,如果想被其他函数调用的话则必须使用外部声明

4.4.2 C++结构初始化

  • 等号可省略

  • 如果初始化对象的{ }中未包含任何东西,则默认设置为0

4.4.3 可以将string类作为成员

struct inflatable
{
    std::string name;
    float volume;
    double price;
}

4.4.4 其他结构属性

  • 不同成员间可以进行赋值

  • 可以在定义结构的同时创建结构体变量

struct perks
{
	int key;
}perk1,perk2;

//甚至还可以这样
struct perks
{
    int key;
}perk3 = 
{
	7    
};
  • 可以声明没有名称的结构体类型(省略名称),同时定义一种结构体类型及其变量

struct
{
	int x;
    int y;
}position	//创建一个名为position的结构体变量,可以访问它的成员(position.x),但不能创建同类型的变量

4.4.5 结构体数组

inflatable guest[2]=
{
    {"Bambi",0.5,21.99},
    {"Godezilla",2000,565.99}
};

4.5 共用体

共用体与结构体的不同在于,共用体只能存储一种类型,而结构体可以存储多种。二者语法相似

匿名共用体没有名称,其成员将成为位于相同地址处的变量

struct widget
{
 ? ?char brand[20];
 ? ?int type;
 ? ?union
 ?  {
 ?      long id_num;
 ? ? ? ?char id_char[20];
 ?  };
};
...
widget prize;
...
if(prize.type == 1)
 ? ?cin >> prize.id_num;
else
 ? ?cin >> prize.id_char;

4.6 枚举

C++的enum工具提供了另一种创建符号常量的方式,可以替代const,还允许定义新类型,语法与结构体相似

enum spectrum {red,orange,yellow,green,blue};

这条语句完成两项工作:

  • 让spectrum成为新类型的名称,它被称为枚举,就像struct被称为结构体一样

  • 将red,orange等作为符号常量,他们对应整数值0~4,这些常量被称为枚举量

枚举变量只能赋予这5个值中的一个,另外,枚举没有算术运算

enum spectrum {red,orange,yellow,green,blue};
spectrum band;
band = ff; // 无效
band++; // 无效
band = orange + red; //无效,orange+red等于1,为int型,不能赋值给band(spectrum)

枚举是整型,可以被提升为int型,反之则不行

int color = blue; //有效
band = 3; //无效
color = 3 + red; //有效

如果int值是有效的,则可以强制转换

band = spectrum(3);

4.6.1 设置枚举量的值

enum bits{one = 1,two = 2,four = 4,eight = 8};
enum bigstep{first,second = 100,third};
enum{zero,null = 0,one,numero_uno = 1};

4.7 指针和自由存储空间

4.7.1 声明和初始化指针

int updates = 4;
int * p_updates;
p_updates = &updates;

4.7.2 指针的危险

在C++中创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的数据内存,为数据提供空间是一个独立的步骤

long * fellow;
*fellow = 223323;

fellow是一个指针,但没有将地址赋给fellow,程序不知道223323将被放在哪里,所以将它解释为存储的地址

4.7.3 指针和数字

指针不是整型,虽然计算机通常把地址当作整数来处理,但从概念上看,两者是截然不同的

int * pt;
pt = 0xB8000000; //pt是int值的地址并不意味着pt本身的类型是int

4.7.4 使用new来分配内存

int * pn = new int;

new int 告诉程序,需要适合存储int的内存,并根据类型确定需要多少字节,然后它找到这样的内存,并返回地址

接下来,将地址赋给pn,pn是被声明为指向int的指针,而*pn是存储在那里的值

4.7.5 使用delete释放内存

delete作用于new出来的地址,如:

int * ps = new int;
int * pq = ps;
delete pq;

4.7.6 使用new来创建动态数组

使用new创建动态数组

short * ps = new short [500];

注意事项:

  • 不要使用delete来释放不是new分配的内存

  • 不要使用delete释放同一个内存块两次

  • 如果使用new[ ]为数组分配内存,则应使用delete[ ]来释放

  • 如果使用new为一个实体分配内存,则应使用delete来释放

  • 对空指针应用delete是安全的

使用动态数组

#include <iostream>
int main()
{
    using namespace std;
    double* p3 = new double[3];
    p3[0] = 0.2;
    p3[1] = 0.5;
    p3[2] = 0.8;
    cout << "p3[1] is " << p3[1] << ".\n";
    p3++;
    cout << "Now p3[0] is " << p3[0] << " and ";
    cout << "p3[1] is " << p3[1] << ".\n";
    p3--;
    delete[] p3;
    return 0;
}

4.8 指针,数组和指针算术

指针和数组等价的原因在于指针算术和C++内部处理数组的方式,将指针变量加1后,增加的量等于它指向的类型的字节数

比如,将double指针加1,则数值加8(8位存储),将short加1,则数值加2

4.8.1 程序

#include <iostream>
int main()
{
    using namespace std;
    double wages[3] = { 10.0,20.0,30.0 };
    short stacks[3] = { 1,2,3 };
?
    double* pw = wages;
    short* ps = &stacks[0];
?
    cout << "pw = " << pw << ", *pw = " << *pw << endl;
    pw++;
    cout << "add 1 to the pw pointer:\n";
    cout << "pw = " << pw << ", *pw = " << *pw << "\n\n";
    cout << "ps = " << ps << ", *ps = " << *ps << endl;
    ps++;
    cout << "add 1 to the ps pointer:\n";
    cout << "ps = " << ps << ", *ps = " << *ps << "\n\n";
    cout << "stacks[0] = " << stacks[0] 
         << ", stacks[1] = " << stacks[1] << endl;
    cout << "*stacks = " << *stacks
         << ", *{stacks + 1} = " << *(stacks + 1) << endl;
    cout << sizeof(wages) << "= size of wages array\n";
    cout << sizeof(pw) << " = size of pw pointer\n";
    return 0;
}
?
?
输出结果:
pw = 00AFF7B8, *pw = 10
add 1 to the pw pointer:
pw = 00AFF7C0, *pw = 20
?
ps = 00AFF7A8, *ps = 1
add 1 to the ps pointer:
ps = 00AFF7AA, *ps = 2
?
stacks[0] = 1, stacks[1] = 2
*stacks = 1, *{stacks + 1} = 2
24 = size of wages array
4 = size of pw pointer

4.8.2 指针小结

声明指针

double * pn;

给指针赋值

double * pa;
char * pc;
int *pd;
double bubble = 3.2;
pa = &bubble;
pc = new char;
pd = new double[30];

对指针解除引用

cout << *pn;
*pc = 'S';

区分指针和指针所指向的值

int * pt = new int;
*pt = 5;

数组名

int chaos[10]; //此时与&chaos[0]相同

指针算术

int tacos[10] = {5,2,8,1,2,2,4,6,9,8};
int * pt = tacos;
pt++;
int * pe = &tacos[9];
pe--;
int diff = pe - pt;

数组的动态联编和静态联编

int tacos[10];  //静态联编
?
int size;
cin >> size;
int * pz = new int[size]; //动态联编
...
delete [] pz;

数组表示法与指针表示法

int * pt = new int [10];
* pt = 5;
pt[0] = 6;
pt[9] = 44;
int coats[10];
*(coats + 4) = 12;

4.9 数组的替代品

4.9.1 模板类vector

vector类似于string类,也是一种动态数组,使用前要包含头文件

#include <vector>
...
using namespace std;
vector<int>vi;
int n;
cin >> n;
vector<double>vd(n); //名为vd,存储n个double类型元素的对象

4.9.2 模板类array(C++11)

array长度固定,使用栈(静态内存分配),效率与数组相同,但更方便,更安全(比vector快)

#include <array>
...
using namespace std;
array<int,5>ai; // 创建一个存有5个int类型的元素的对象
array<double,4>ad = {1.2,2.1,3.43,4.3};
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 11:49:05  更:2021-08-07 11:51:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/8 18:17:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码