c++ primer学习笔记(二)

目录

第三章

一、命名空间的using声明

二、标准库的string类型

1、string对象的定义和初始化

2、string对象的读写

3、string对象的操作

4、string对象中字符的处理

三、标准库的vector类型

1、vector对象的定义和初始化

2、vector对象的操作

四、迭代器简介

1、简介

 2、begin和end操作

3、vector迭代器的自增与解引用运算

4、==或!=操作符

5、应用

6、const_iterator

7、迭代器的算术操作

五、标准库bitset类型

 1、用unsigned值初始化bitset对象

 2、用string对象初始化bitset对象

3、bitset对象上的操作


第三章

一、命名空间的using声明

1、::是作用域操作符。含义是右操作数的名字可以在左操作数的作用域中找到。

例:std::cin是说cin是在命名空间std中定义的。

2、使用using声明可以直接引用名字,不需要再引用该名字的命名空间。

#include <string>
#include <iostream>

using std::cin;
using std::string;

int main()
{
    string s;
    cin>>s;
    cout<<s;
    std::cout<<s;
}

 3、但是,在头文件中必须使用完全限定的标准库名字。并且头文件中应该只定义必要的东西。

(如果在头文件中放置using声明,相当于在包含该头文件的每个程序中都放置了同一using声明,不论该程序是否需要using声明。)

二、标准库的string类型

1、string对象的定义和初始化

构造函数是一个特殊成员函数,定义如何初始化该类型的对象。

初始化string对象的方式:

(1)string s1;默认构造函数,s1为空串

(2)string s2;将s2初始化为s1的一个副本

(3)string s3(“value”);将s3初始化为一个字符串字面值副本

(4)string s4(n,‘c’);将s4初始化为字符‘c’的n个副本

2、string对象的读写

1、使用标准输入输出读写string对象

int main()
{
    string s;
    cin>>s;
    cout<<s<<endl;
    return 0;
}

 特点:

  • 读取并忽略开头所有的空白字符(空格,换行符,制表符)
  • 读取字符直到再次遇到空白字符,终止读取

例:输入 “   Hello World    ”   会输出“Hello”不含任何空格

改写:

string s1,s2;
cin>>s1>>s2;
cout<<s1<<s2<<endl;

 输入 “   Hello World    ”   会输出“HelloWorld”

读取未知数目的string对象(分单词读取):

int main()
{
    string word;
    while(cin>>word)
        cout<<word<<endl;
    return 0;
}

 若还未到达文件尾且未遇到无效输入,则执行while循环体。若到达了文件尾,则跳出while循环

2、用getline读取整行文本

getline函数接受两个参数:一个输入流对象和一个string对象

从输入流的下一行读取并保存读取的内容到string中,但不包含换行符

getline不忽略开头的换行符。只要getline遇到换行符,即使它是输入的第一个字符,也将停止读入并返回。如果第一个字符就是换行符,string参数将被置空。

例:分行读取

int main()
{
    string line;
    while(getline(cin,line))
        cout<<line<<endl;  //由于line不含换行符,若逐行输出需要自行添加endl
    return 0;
}

3、string对象的操作

1、string对象的长度是指string对象中字符的个数,可通过size操作获取

判断string对象是否为空:
if(st.size()==0)  //若为真则st为空
if(st.empty())  //若为真则st为空

2、 string::size_type类型

不要把size的返回值赋给int变量。因为string::size_type是unsigned类型,存储长度是int能存储的两倍,用int可能会溢出

为了避免溢出,保存string对象size的最安全的方法是使用标准库类型string::size_type

3、string关系操作符(==、<、>)

比较两个string对象时采用大小写敏感的字典排序策略

  • 如果两个string对象长度不同,且短的string对象与长的string对象前面的部分匹配(是其前缀),则短的string对象小于长的string对象。
  • 如果两个string对象字符不同,则比较第一个不匹配的字符

4、string对象的赋值

st1=st2;

先把st1占用的相关内存释放掉,然后分配给st1足够存放st2副本的内存空间,最后把st2中的所有字符复制到新分配的内存空间。

5、两个string对象相加

string s1("hello,   ");

string s2("world\n");

string s3 = s1 + s2;  //s3 is "hello,   world\n"

如果要把s2直接追加到s1末尾,可以使用+=操作符

s1 += s2;

6、和字符串字面值的连接

当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string类型的。

string s1 = "world";
string s2 = "hello" + ",";  //不合法,+两侧都是字符串类型
string s3 = s1 + "\n" //合法,有一侧是string类型
string s4 = s1 + "," + "yes";  //合法,从左到右计算,s1 + ","算完变成string类型
string s5 = "," + "yes" + s1;  //不合法,从左到右计算,两个字符串类型先计算

 7、从string对象获取字符

用下标分别取出string对象的每个字符,分行输出

string str("some string");
for(string::size_type ix = 0; ix != str.size(); ix++)
{
    cout << str[ix] << endl;
}

 8、计算下标值

str[int1*int2] = int3;

虽然整型数值都可以作为索引,但索引的实际数据类型是unsigned类型string::size_type

4、string对象中字符的处理

 可打印的字符是指那些可以显示表示的字符(包括空格,也是可显示表示的)。

 空白字符是空格、制表符、垂直制表符、回车符、换行符、进纸符中的任意一种。

 标点符号是除了数字、字母或(可打印的)空白字符(如空格)以外的其他可打印字符

 例1:输出一给定string对象中标点符号的个数

string s("Hello World!!!");
string::size_type punct = 0;
for(string::size_type index = 0; index != s.size(); ++index)
{
    if(ispunct(s[index]) ++punct;
}
cout<<punct<<endl;

//输出3

 例2:把string对象s中的字母改写为小写字母

string s("Hello World!!!");
for(string::size_type index = 0; index != s.size(); ++index)
    s[index] = tolower(s[index]);
cout << s << endl;

//输出hello world!!!

 cname头文件中定义的名字都定义在命名空间std内,而.h版本中的名字不是这样。

通常c++程序中应该采用cname这种头文件版本,这样标准库中的名字在命名空间std中保持一致。

string s;
cout << s[0] << endl;
//声明了一个字符串 s,但没有给它赋值。因此,它是一个空字符串。
//当你尝试访问 s[0] 时,你正在尝试访问空字符串的第一个字符,这是未定义的行为(undefined behavior)。
//在C++中,尝试访问空字符串或超出字符串长度的索引通常会导致程序崩溃或产生不可预测的结果。

三、标准库的vector类型

一个容器中所有对象都必须是同一种类型的。

vector是一个类模板,而不是一种数据类型。可用来定义任意多种数据类型。如vector<int>、vector<string> 都是数据类型。

1、vector对象的定义和初始化

 创建确定个数的元素:

vector<int> ivec(10,-1);
vector<string> svec(10,"hi!");

 值初始化:

如果没有指定元素的初始化式,标准库将自行提供一个元素的初始值进行值初始化。

具体值是什么取决于存储在vector中元素的数据类型。

vetcor<int> fvec(10);//10个元素,每个都初始化为0
vetcor<string> svec(10);//10个元素,每个都初始化为空串

 以上即,用各类型默认构造函数创建初始化式。

若元素类型是没有定义任何构造函数的类类型,标准库仍产生一个带初始值的对象,这个对象的每个成员进行值初始化。

2、vector对象的操作

 1、empty和size操作类似于string类型。size返回类型为相应vector类定义的size_type的值。

vector<int>::size_type  //ok

vector::size_type  //error

vector类型总是包括vector的元素类型

2、向vector中添加元素

string word;
vector<string> text;
while(cin>>word)
       text.push_back(word);

 3、vector的下标操作

for(vector<int>::size_type ix = 0; ix != ivec.size(); ++ix)
    ivec[ix] = 0;

 但是,只能用于已经有元素的vector,若vector不确定有没有元素,不能用下标赋值(可能会溢出)

只能用v = ix; ivec.push_back(v)的方式赋值并添加到vector中

例题:

读入一段文本到vector对象,每个单词存储为vector中的一个元素,把vector对象中每个单词转化为大写字母。输出vector对象转化后的元素,每八个单词为一行输出。

#include <iostream>
#include <fstream>
#include <vector>
#include <cassert>
#include <string>
#include <sstream>
using namespace std;
int main()
{
    ifstream in("1.txt"); //打开文件
    if(!in.is_open()) cout<<"open is error"<<endl; //确认是否打开
    //assert(in);
    string word;
    string line;
    vector<string> words;
    // 逐行读取文件内容  
    while (getline(in, line)) {  
        istringstream ss(line);  
        // 使用istringstream分割行到单词,并存入vector  
        while (ss >> word) {  
            words.push_back(word);  
        }  
    }
    // 关闭文件  
    in.close(); 
    int count=0; 
    for(vector<string>::size_type ix=0; ix != words.size(); ix++)
    {
        for(string::size_type j=0; j != words[ix].size(); j++)
        {
           words[ix][j] = toupper((unsigned char)words[ix][j]); //每个字母变大写
        }
        cout<<words[ix]<<" ";
        count++;
        if(count%8 == 0)  //满八个换一行
        {
            cout<<endl;
        }
    }
    if(count%8!=0) //最后一行若不满8个也换行
    {
        cout<<endl;
    }
    return 0;
}

 常用的简便输出vector的方法:

vector<string> words;
for (const auto& w : words) //const是指不改变w,auto指自动识别words里存的类型
{  
    std::cout << w << " ";  
}  

 关于<sstream>

sstream 是 C++ 标准库中的一个头文件,全称为 <sstream>。它提供了对字符串流(string stream)的支持,允许你以类似于文件流(file stream)或控制台流(console stream)的方式对字符串进行操作,用于字符串的解析和转换。sstream 头文件中定义了几个类,主要包括 istringstreamostringstream 和 stringstream

  • istringstream 类用于从字符串中读取数据,类似于输入文件流(ifstream)。
  • ostringstream 类用于将数据写入字符串,类似于输出文件流(ofstream)。
  • stringstream 类同时支持读取和写入字符串,类似于输入输出文件流(fstream

四、迭代器简介

1、简介

迭代器对所有容器都适用,c++程序更倾向于使用迭代器而不是下标操作访问容器元素。

每种容器都定义了自己的迭代器类型,如vector

vector<int>::iterator iter;

 2、begin和end操作

每种容器都定义了begin和end函数,用于返回迭代器。

begin返回迭代器指向的第一个元素

vector<int>::iterator iter = ivec.begin();

 end操作返回的迭代器指向vector末端元素的下一个元素,即指向了一个不存在的元素

如果vector为空,begin返回的迭代器与end返回的迭代器相同

3、vector迭代器的自增与解引用运算

迭代器类型可以使用解引用操作符(*)来访问迭代器所指向的元素

例:*iter = 0;++iter;

因为end操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作

4、==或!=操作符

用来比较两个迭代器,如果两个迭代器对象指向同一个元素,则它们相等,否则不相等。

5、应用

for(vector<int>::size_type ix = 0; ix != ivec.size(); ++ix)
    ivec[ix] = 0;  //将vector中元素循环赋值为0
for(vector<int>::iterator iter = ivec.begin(); iter != ivec.end(); ++iter)
    *iter = 0;  //用迭代器改写

如果vector为空,程序也是安全的。因为ivec为空的话,begin返回的迭代器不指向任何元素,从begin操作返回的迭代器和从end操作返回的迭代器值相同,因此for语句中测试条件立即失败。

6、const_iterator

每种容器类型还定义了一种名为const_iterator的类型,该类型只能用于读取容器内元素,但不能改变其值。

for(vector<int>::const_iterator iter = ivec.begin(); iter != ivec.end(); ++iter)
    cout<<*iter<<endl;  //只能用,不能改变其指向对象的值

 使用const_iterator类型时,迭代器自身的值可以变(可以自增或解引用),但不能改变其指向的元素的值。

不要把const_iterator和const的iterator混淆

const的iterator是指const类型的iterator迭代器。声明一个const迭代器时,必须初始化迭代器,且一旦初始化后,就不能改变它的值(不能自增或解引用,即不能让它指向其他元素),但可以改变它指向的元素的值。

vector<int> nums(10);
const vector<int>::iterator cit = nums.begin();
*cit = 1;//可以改变它指向的元素的值

7、迭代器的算术操作

iter + n      
iter - n
iter1 - iter2
vector<int>::iterator mid = vi.begin() + vi.size()/2; //比遍历到中间快

任何改变vector长度的操作都会使已存在的迭代器失效。比如调用push_back()后就不能再信赖指向vector迭代器的值了。 

五、标准库bitset类型

bitset类是一种类模板

与vector不同的是,bitset类型对象的区别仅在于长度,不在于类型。

定义bitset时,要明确bitset含有多少位,需要在尖括号内给出它的长度值。

bitset的构造函数:

 1、用unsigned值初始化bitset对象

在32位unsigned long的机器上,十六进制值0xffff表示为二进制位就是16个1和16个0

bitset<16> bitvec1(0xffff); //少于unsigned long的位数,初始值的高阶位被丢弃
//bits 0……15 are set to 1
bitset<32> bitvec2(0xffff); //与unsigned long的位数相同,正好放置初始值
//bits 0……15 are set to 1;16……31 are 0
bitset<128> bitvec3(0xffff); //长度大于32,31位以上的高阶位被置0
//bits 32 through 127 initialized to zero

 2、用string对象初始化bitset对象

string strval("1100");
bitset<32> bitvec4(strval);
//bitvec4的位模式中第2和第3的位置为1,其余位置为0.如果string对象的字符个数小于bitset类型的长度,则高阶位将置为0。

string对象和bitset对象之间是反向转化的。string对象最右边的字符(下标最大的字符)用来初始化bitset对象的低阶位(下标为0的位)

也可以只用string对象的子串作为bitset对象的初始值。

bitset<32> bitvec5(str,5,4); //从str[5]开始,往后4位
bitset<32> bitvec6(str, str.size() - 4); //最后4位

3、bitset对象上的操作

(1)count操作的返回类型是标准库中命名为size_t的类型。size_t类型定义在cstddef头文件中。该文件是C标准库的头文件stddef.h的C++版本。

(2)bitset的size操作返回bitset对象中二进制位的个数,返回值的类型是size_t

(3)访问bitset对象中的位可以用下标,也可以用下标测试某位的值或设置某位的值

for(int index = 0;index !=32; index += 2)
{
    bitvec[index] = 1;
}

(4)flip操作

bitvec.flip(0);//bit的第一位取反
bitvec[0].flip();//同上
bitvec.flip();//bit的所有位取反

(5)获取bitset对象的值

当bitset类型的长度<=unsigned long的长度时,才可以使用to_ulong操作。

bitset<32> bitvec2(0xffff);
unsigned long ulong = bitvec3.to_ulong();
cout << "ulong = " << ulong << endl;

输出 65535。

在十六进制数0x0000ffff中,每个十六进制位代表4个二进制位。则0x0000ffff的低16位都是1

转化为10进制:1 * 1 + 1 * 2 + 1 * 4 + 1 * 8 + 1 * 16 + 1 * 32 + 1 * 64 + 1 * 128 + 1 * 256 + 1 * 512 + 1 * 1024 + 1 * 2048 + 1 * 4096 + 1 * 8192 + 1 * 16384 + 1 * 32768 = 65535

(6)输出二进制位

bitset<32> bitvec2(0xffff);
cout << "bitvec2: " << bitvec2 <<end;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/433144.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里云ECS u1实例2核4G,5M固定带宽80G ESSD Entry盘价格199元一年

阿里云ECS u1实例2核4G&#xff0c;5M固定带宽 80G ESSD Entry盘199元一年&#xff0c;购买条件为企业用户&#xff0c;新用户和老用户都可以&#xff0c;但必须是企业用户&#xff0c;如果是个人实名认证&#xff0c;可以升级为企业认证再购买&#xff0c;ECS通用算力型u1实例…

顶顶通呼叫中心中间件-机器人话术如何实现在放音期间不接收按键信息

文章目录 前言联系我们实现方法 前言 场景&#xff1a;进入机器人话术时&#xff0c;在话术放音期间不接收用户的按键信息&#xff0c;等话术放音完成后才允许接收用户的按钮信息&#xff0c;然后根据用户的按钮信息执行相应的机器人话术流程。 联系我们 有意向了解呼叫中心中…

第一节 JDBC是什么?

JDBC代表Java数据库连接(Java Database Connectivity)&#xff0c;它是用于Java编程语言和数据库之间的数据库无关连接的标准Java API&#xff0c;换句话说&#xff1a;JDBC是用于在Java语言编程中与数据库连接的API。 JDBC库包括通常与数据库使用相关&#xff0c;如下面提到的…

史称GPT-4最强劲敌——Claude 3 大模型它来了【附体验教程】

Anthropic 的 Claude 3 Sonnet 模型现已在亚马逊云科技的 Amazon Bedrock 正式可用。 Amazon Bedrock 是目前 第一个 也是 唯一 一个提供 Claude 3 Sonnet 的托管服务 。 Claude 3 免费测试体验者福利&#x1f9e7;&#xff1a;https://mp.weixin.qq.com/s/hszLRa8B5zKsTDg2bmI…

C#,入门教程(06)——解决方案资源管理器,代码文件与文件夹的管理工具

上一篇&#xff1a; C#&#xff0c;入门教程(05)——Visual Studio 2022源程序&#xff08;源代码&#xff09;自动排版的功能动画图示https://blog.csdn.net/beijinghorn/article/details/124675293 大家平时都怎么管理源代码与文件夹呢&#xff1f;世界上最好的集成开发环境…

varchar类型字段为什么经常定义成255

MySQL | ver < 4.1&#xff1a; VARCHAR以字节为单位存储&#xff0c;所以假设全部为常用汉字&#xff08;UTF-8 3字节编码长度&#xff09;&#xff0c;则VARCHAR(255)共可存放约85个汉字&#xff1b; MySQL | ver > 4.1&#xff1a; VARCHAR以字符为单位存储&#x…

对于网络IO的理解

网络IO理解 首先服务端将本机地址和端口bind在listensock上&#xff0c;再用listen()去将listensock套接字设置为listen状态&#xff0c;然后调用accept&#xff0c;进入阻塞状态。如果此时有客户端请求连接&#xff0c;就是第一次握手的开始。 客户端会先调用connect来申请连…

牛客网 华为机试 提前不重复的整数

本题要求提取不重复的整数&#xff0c;然后倒序输出&#xff0c;我们可以采用hashset来存储结果&#xff0c;这样就能避免重复。 为了从右往左获取数字&#xff0c;我们可以把这个数对10取余&#xff0c;得到的余数就是其每一位的数。然后我们把得到的数字添加到hashset中&…

#QT(MP3播放器-部分界面)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a;制作一个mps播放器&#xff0c;界面可以实现鼠标拖动 3.记录&#xff1a; &#xff08;1&#xff09;network网络多线程 &#xff08;2&#xff09;Http &#xff08;3&#xff09;QJsonObject封装JSON对象 &#xff08;4&am…

c语言-大小写字母的转换

目录 方法一&#xff1a;库函数直接转换 1、toupper的测试代码 2、tolower的测试代码 方法二&#xff1a;通过修改ASCII码值转换 1、自己实现大写转小写 2、自己实现小写转大写 结语 前言&#xff1a; 在使用c语言写代码时&#xff0c;通常会遇到很多将大小写字母相互…

性能测试总结 —— 测试流程篇!

本文主要介绍下性能测试的基本流程&#xff0c;性能测试从实际执行层面来看&#xff0c;测试的过程一般分为这么几个阶段&#xff0c;如下图&#xff1a;       下面分别介绍下每个阶段具体需要做什么&#xff1a; 一、性能需求分析&#xff1a; 性能需求分析是整个性能…

从零学习Linux操作系统 第三十部分 部署Anisble

一、ansible实验环境的部署 主控机 更改服务器主机名 hostnamectl set-hostname westos_ansible.westos.org 主服务器需要能够实现上网 修改网卡使之能够上网 能ping通 代表可以连接外网 搭载本地软件仓库 并且挂载镜像 装载 dnf install httpd -y 让其开机启动并且…

C语言指针的初步认识--学习笔记(3)

1. 字符指针变量 在C语言中&#xff0c;字符串通常被视为字符数组&#xff0c;但它们可以有不同的表示方式。字符指针变量存储的是字符串的地址。这意味着&#xff0c;当你有一个字符串时&#xff0c;你可以通过改变字符指针的值来改变这个字符串&#xff0c;因为你实际上改变的…

C++_位图

目录 1、位图的使用 2、位图实现 3、位图与哈希表的区别 4、位图的应用 结语 前言&#xff1a; 位图采用的是哈希表的思想&#xff0c;哈希表的映射层面是在字节上&#xff0c;而位图的映射层面就是在bit位上。由于bit位所能展现的信息无非只有‘1’和‘0’&#xff0c;所…

LeetCode 热题 100 (尽量ACM模式刷) 持续更新!!!

LeetCode 热题 100 哈希hash 1 两数之和 /** 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出和为目标值target的那两个整数&#xff0c;并返回它们的数组下标。* 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案…

项目管理必备:进度报告撰写指南!

本文将探讨如何将进度报告写作整合到你的工作流程中&#xff0c;包括确定最适合的报告时间、编写方法和与团队一起构建报告结构的建议。最后&#xff0c;还会分享一些撰写进度报告的最佳做法&#xff0c;助你掌握这种对工作有巨大帮助的方法。 什么是进度报告&#xff1f; 它…

Python 应用程序编程接口库之pywin32使用详解

概要 在Python的世界里,有许多优秀的第三方库可以帮助开发者更轻松地处理各种任务。其中,pywin32库是一个特别引人注目的工具,它提供了对Windows API的完整访问,使得开发者能够利用Python来编写强大的Windows应用程序,从简单的脚本到复杂的桌面应用,pywin32都能胜任。 什…

算力调度和云计算有何区别

Canalys发布的研究报告显示&#xff0c;2023年第二季度&#xff0c;全球云基础设施服务支出增长16%&#xff0c;达到724亿美元。 此前云厂商们的高速增长&#xff0c;主要归功于大规模的企业数字化转型和上云。当前市场的增速放缓&#xff0c;除了上云普及带来的市场增量见顶&…

Dockerfile(3) - WORKDIR 指令详解

WORKDIR 切换到镜像中的指定路径&#xff0c;设置工作目录在 WORKDIR 中需要使用绝对路径&#xff0c;如果镜像中对应的路径不存在&#xff0c;会自动创建此目录一般用 WORKDIR 来替代 切换目录进行操作的指令 RUN cd <path> && <do something> WORKDIR…

【算法】顺时针打印矩阵(图文详解,代码详细注释

目录 题目 代码如下: 题目 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则打印出数字:1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10 这一道题乍一看,没有包含任何复杂的数据结构和…