目录
3.4 string类型支持的运算符 : + 、&、关系运算
思维导图:
学习内容:
1. 面向对象
1.1. 概念
面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式。
将实现同一事物的所有的属性(成员变量)和行为(成员方法)都集中在一起,我们称之为类(class),并向外部提供相关接口,用户可以使用这些接口来实现对该类实例化出的对象的操作,进而对整个进程进行服务。
1.2. 所谓面向对象编程
程序由两部分组成:分别是类的定义和类的使用。
1.3. 面向过程与面向对象
面向过程的思想:
以电脑为例:先购买主板,显卡,cpu。。。。。。 所有零件全部整出来后,进行组装成一台电脑供后期程序使用
面向对象的思想:
以电脑为例:直接购买一台电脑。
2. 命名空间
2.1 为何引入命名空间
当多人协同开发一个项目时,可能会出现每个人对标识符的命名没有问题,但是整合到一起时,会出现命名污染问题。
此时就需要引入一个空间,让每个人所用到的名字都放入到自己的空间种,使用时,在标识符前面加上对应命名空间即可。
2.2 程序中的标识符
变量名、函数名、结构体名、共用体名、指针名、数组名 。。。
2.3 系统提供的命名空间 std
1. C++中每个头文件,都会提供一个名为std的命名空间,表示该文件提供的系统的名字,都放入到该命名空间中
2. std名字空间的使用方式有三种
1、单独使用:使用名字时,需要将命名空间和名字一起使用
2、先声明某个名字,后期在使用该名字时,直接使用即可,无需加命名空间名和作用域限定符,但是没有声明的不能直接用
3、使用using namespace 将整个命名空间全部声明,后期该命名空间中的名字可以直接使用
#include <iostream>
int main()
{
//使用方式1:标识符和命名空间名一起使用,中间使用作用域限定符连接
std::cout<<"hello world"<<std::endl;
//使用方式2:将某个名字使用using进行声明,没有声明的名字不能直接使用
using std::cout; //声明cout这个名字
cout<<"hello world"<<std::endl;
//使用方式3:将整个命名空间进行声明
using namespace std;
cout<<"hello world"<<endl;
return 0;
}
2.4 自定义命名空间
2.4.1 定义格式
namespace 命名空间名
{
类型 名字1;
}
#include <iostream>
using namespace std;
//定义属于自己的命名空间
namespace a
{
char name[20] = "aaa";
int age = 20;
void fun()
{
cout<<"name = "<<name<<" age = "<<age<<endl;
}
}
int main()
{
//使用方式1:连名带姓使用
cout << "name = "<<a::name<<endl;
//使用方式2:将某个名字声明
using a::age;
cout << "age = "<<age<<endl; //20
//使用方式3:将整个命名空间进行声明
using namespace a;
fun();
return 0;
}
2.4.2 多个命名
同一个作用域下可以定义多个同名的命名空间,但是,这多个命名空间在编译时会合成一个命名空间,所以要求命名空间中的名字不能重复
//定义属于自己的命名空间
namespace a
{
char name[20] = "aaa";
int age = 20;
void fun()
{
cout<<"name = "<<name<<" age = "<<age<<endl;
}
}
//定义新的命名空间
namespace a
{
int value = 1314;
double key = 3.14;
//double age = 666.66; //不能在命名空间中定义重复的名字
}
2.4.3 命名空间嵌套定义
使用时,如果使用的是最里层的名字,则需要使用作用域限定符一级一级找到最里层
2.4.4 命名空间中函数
一般是进行命名空间内声明,命名空间外定义
#include <iostream>
using namespace std;
//定义属于自己的命名空间
namespace a
{
char name[20] = "aaa";
int age = 20;
void fun(); //命名空间内容进行函数的声明
}
//定义新的命名空间
namespace a
{
int value = 1314;
double key = 3.14;
//double age = 666.66; //不能在命名空间中定义重复的名字
//定义一个命名空间
namespace MySon
{
int value = 999;
double key = 1010;
}
}
//命名空间外进行函数定义
void a::fun()
{
cout<<"name = "<<name<<" age = "<<age<<endl;
}
int main()
{
//使用方式1:连名带姓使用
cout << "name = "<<a::name<<endl;
//使用方式2:将某个名字声明
using a::age;
cout << "age = "<<age<<endl; //20
//使用方式3:将整个命名空间进行声明
using namespace a;
fun();
//使用MySon中的value
cout<<a::MySon::value<<endl; //999
return 0;
}
2.5 命名空间冲突问题
1> 多个命名空间中,出现相同名字时,并且每个命名空间都整体声明了:此时如果使用冲突的名字时,需要加上命名空间名和作用域限定符进行区分
2> 命名空间中的名字和全局变量同名时:全局变量会自动放入全局命名空间中,要使用该命名空间中的名字,只需在名字前加作用域限定符即可。
3> 命名空间中的名字和局部变量同名时:优先使用局部变量,如果非要使用命名空间中的名字,需要加上命名空间名和作用域限定符
#include <iostream>
using namespace std;
//zhangsan的命名空间
namespace ZhangSan
{
int num = 520;
double key = 1314;
}
//定义sili的命名空间
namespace LiSi
{
int age = 20;
int num = 999;
}
//同时声明两个命名空间
using namespace ZhangSan;
using namespace LiSi;
//定义全局变量:key
int key = 55555555;
int main()
{
//定义局部变量age
int age = 100;
cout<<"key = "<<::key<<endl; //此时使用的是全局变量的key
cout<<"key = "<<ZhangSan::key<<endl; //使用的是ZhangSan命名空间中的数据
cout<<"age = "<<age<<endl; //此时使用的是局部变量,局部优先原则
cout<<"age = "<<LiSi::age<<endl; //此时使用的是LiSi命名空间中的名字
cout << "num = "<< ZhangSan::num << endl; //?
cout << "num = "<< LiSi::num << endl;
cout << "Hello World!" << endl;
return 0;
}
3. C++中的字符串
3.1 C++支持的字符串
1> C++支持两种风格的字符串:分别是C语言的字符串,以'\0'作为结尾的字符串
也支持 string 类型的字符串,本质上是一个类对象
2> 要是有C++风格的字符串,需要引入头文件 string
#include<string>
3.2 string类型的字符串初始化和赋值
3.2.1 单个变量的初始化和赋值
#include <iostream>
#include<string> //字符串类所在的头文件
using namespace std;
int main()
{
string s1; //定义了一个字符串变量,没有初始化,调用了类的无参构造
cout<<"s1 = "<<s1<<endl; //此时得到的是一个空串
string s2 = "hello world"; //定义一个字符串并对其进行初始化, 调用了拷贝构造函数
cout<<"s2 = "<<s2<<endl; //"hello world"
string s3("ni hao"); //定义一个字符串并对其进行初始化, 调用了有参构造函数
cout<<"s3 = "<<s3<<endl; //ni hao
string s4(5,'A'); //定义一个字符串,并且用5个A进行初始化, 调用了有参构造
cout<<"s4 = "<<s4<<endl; //AAAAA
string s5 = {"lalalalalala"}; //定义一个字符串并对其进行初始化,调用了拷贝构造函数
cout<<"s5 = "<<s5<<endl; //lalalalalala
s1 = "dududududud"; //C++中可以直接使用等号给字符串变量赋值, 调用了拷贝赋值函数
cout<<"s1 = "<<s1<<endl;
return 0;
}
3.2.2 多个字符串之间的初始化和赋值
#include <iostream>
#include<string>
using namespace std;
int main()
{
string s1 = "hello world"; //定义一个字符串并且初始化
string s2 = s1; //定义一个字符串,用其他字符串进行初始化 调用拷贝构造函数
cout<<"s2 = "<<s2<<endl; //hello world
string s3(s1); //定义一个字符串,用其他字符串进行初始化 调用有参构造函数
cout<<"s3 = "<<s3<<endl; //hello world
string s4 = s1 + s2; //将s2连接到s1后面,并将结果给s4初始化,调用后s1和s2不变
cout<<"s4 = "<<s4<<endl; //hello worldhello world
string s5 = s1 + "lalalalalal";
cout<<"s5 = "<<s5<<endl; //hello worldlalalallala
string s6 = "lalalalalal" + s1;
cout<<"s6 = "<<s6<<endl; //lalalallalahello world
//string s7 = "hello " + "world"; //不可用
s1 = s6; //使用一个字符串给另一个字符串赋值 调用拷贝赋值函数
cout<<"s1 = "<<s1<<endl;
return 0;
}
3.3 字符串的常用函数
1> c_str()、data()函数:将C++风格的字符串向C语言风格的字符串进行转换
#include <iostream>
#include<cstring>
using namespace std;
int main()
{
char str1[50] = "hello world"; //c风格的字符串
string str2; //C++风格的字符串
//c语言风格字符串向C++风格字符串转换
str2 = str1;
cout<<"str2 =" <<str2<<endl;
str2 = "nihao";
//C++风格字符串向C语言风格字符串转换
//str1 = str2; //不可以
//strcpy(str1, str2); //不可以,因为strcpy要的两个参数都是char*类型,而str2是string类型
strcpy(str1, str2.data());
strcpy(str1, str2.c_str());
//str2.data() str2.c_str() //将C++风格的字符串转换为C风格
cout << "str1 = "<<str1<<endl; //输出C风格的字符串 nihao
return 0;
}
2>求长度函数 size()、length() 、判空函数 empty() 、 清空函数 clear()
#include <iostream>
using namespace std;
int main()
{
string str = "hello world";
//判断是否为空
if(str.empty())
{
cout<<"字符串为空"<<endl;
}else
{
cout<<"字符串非空"<<endl;
}
//求字符串长度
int len = str.length();
cout<<"len = "<<len<<endl; //11
//将字符串清空
str.clear();
//判断是否为空
if(str.empty())
{
cout<<"字符串为空"<<endl;
}else
{
cout<<"字符串非空"<<endl;
}
len = str.length(); //再次求长度
cout<<"len = "<<len<<endl; //0
//向字符串中放入字符
str.push_back('H');
str.push_back('e');
str.push_back('l');
str.push_back('l');
str.push_back('o');
cout<<"str = "<<str<<endl; //hello
//调用交换函数
string str2 = "I love China";
str.swap(str2);
cout<<"str = "<<str<<endl; //I love China
cout<<"str2 = "<<str2<<endl; //Hello
return 0;
}
3.4 string类型支持的运算符 : + 、&、关系运算
#include <iostream>
using namespace std;
int main()
{
string str1 = "hello world";
string str2 = "I love China";
//判断两个字符串的大小 //取代了strcmp
if(str1 > str2)
{
cout<<str1<<"大"<<endl;
}else if(str1 < str2)
{
cout<<str2<<"大"<<endl;
}else
{
cout<<"一样大"<<endl;
}
cout<<&str1<<endl; //输出str1的地址
cout<<str1+str2<<endl; //将两个字符串进行加法运算 取代了strcat
str1 = str2; //将两个字符串之间互相赋值 取代了strcpy
return 0;
}
3.5 字符串的输入
1> 当输入的字符串中没有空格时,可以直接使用 cin 即可
2> 当输入的字符串中包含空格时,就不能使用cin了,需要使用一个全局函数 getline
#include <iostream>
using namespace std;
int main()
{
string str1;
string str2;
cout<<"请输入第一个字符串:";
cin >> str1; //只能输入不包含空格的字符串
cout<<"str1 = "<<str1<<endl;
getchar();
cout<<"请输入第二个字符串:";
getline(cin, str2); //调用全局函数,输入带空格的字符串
cout<<"str2 = "<<str2<<endl;
return 0;
}
课外作业:
提示并输入一个字符串,统计该字符串中字母个数、数字个数、空格个数、其他字符的个数
#include <iostream>
#include<cstring>
using namespace std;
// 主函数
int main()
{
// 提示用户输入一个字符串
cout << "请输入一个字符串:" << endl;
// 定义一个string类型的变量,用于存储用户输入的字符串
string stl;
// 从标准输入流中读取一行字符串,存储到stl变量中
getline(cin, stl);
// 定义一个字符数组,用于存储用户输入的字符串,初始值为0
char str[100] = {0};
// 将string类型的字符串转换为字符数组
strcpy(str, stl.data());
// 初始化计数器
int zimu = 0; // 字母计数
int digit = 0; // 数字计数
int other = 0; // 其他字符计数
int space = 0; // 空格计数
// 遍历字符数组,统计各类字符的数量
for (int i = 0; str[i] != '\0'; i++) {
// 如果字符为字母,则字母计数加1
if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z')) {
zimu++;
}
// 如果字符为数字,则数字计数加1
else if (str[i] >= '0' && str[i] <= '9') {
digit++;
}
// 如果字符为空格,则空格计数加1
else if (str[i] == ' ') {
space++;
}
// 否则,其他字符计数加1
else {
other++;
}
}
// 输出各类字符的数量
cout << "字母有" << zimu << "个" << "数字有" << digit << "个" << "空格有" << space << "个" << "其他有" << other << "个" << endl;
return 0;
}