-
类
- 关键字:class、struct。
- 类体右侧的表示结束的花括号后必须写一个分号,这是因为类体后面可以紧跟变量名以示对该类型对象的定义,所以分号必不可少。
- 一般来说,最好不要把对象的定义和类的定义放在一起。
- 类内初始值进行初始化时,不能使用圆括号。
- 没有成员函数的 struct 还是称作“结构”;有成员函数的 struct 就是类。
- 使用 class 和 struct 定义类唯一的区别就是默认的访问权限:当我们希望定义的类的所有成员是 public 时,使用struct;反之,如果希望成员是 private ,使用 class。
//推荐这样写
struct Person {
std::string name;//默认值:空字符串
int age;//默认值:0
};
Person p1, p2;
//不推荐这样写
struct Person {
std::string name;
int age;
}p1, p2;
-
头文件:
- 头文件通常包含那些只能被定义一次的实体,如类、 const 和 constexpr 变量(常量表达式)等。
- 头文件一旦改变,相关的源文件必须重新编译以获取更新过的声明。
- 确保头文件多次包含仍能安全工作的常用技术是预处理器。
- # define:把一个名字设定为预处理变量;
- # ifdef:检查某个指定的预处理变量是否已经定义,当且仅当变量已定义时为真;
- # ifndef :检查某个指定的预处理变量是否未被定义,当且仅当变量未定义时为真。
- 整个程序中的预处理变量包括头文件保护符必须唯一,通常的做法是基于头文件中类的名字来构建保护符的名字,以确保其唯一性。为了避免与程序中的其他实体发生名字冲突,一般把预处理变量的名字全部大写,前后加上下划线,并将.也替换成下划线。
#ifndef _PERSON_H_//如果没有定义过预处理变量_PERSON_H_
#define _PERSON_H_
... //头文件内容
#endif
-
using 声明
- 运用using声明便可以使用到命名空间的成员,也就无需使用专门的前缀(::)也可以使用所需的名字了。
- using声明形式:using [namespace]::[name];或者using namespace [namespace];
#include <iostream>
using std::cin;
int main()
{
int num;
cin >> num;
cout << num << endl;//错误,cout与endl没有对应的using声明
std::cout << num << std::endl;//正确
}
#include <iostream>
using namespace std;
int main()
{
int num;
cin >> num;
cout << num << endl;//正确
}
-
标准库类型string #include <string>;
- 标准库类型string表示可变长的字符序列;
- 初始化string对象有多种方式:
- 如果使用等号初始化一个变量,实际上执行的是拷贝初始化,编译器把等号右侧的初始值拷贝到新创建的对象中去;与之相反,如果不使用等号,则执行的是直接初始化。
- 在执行读取操作时,string对象会自动忽略开头的空白(空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇见下一处空白为止。
string str;
cin >> str;//输入hello world
cout << str << endl;//输出hello
return 0;
-
getline
- 得到的字符串中保留输入时的空格符、制表符;
- getline函数的参数是一个输入流和一个 string 对象,函数从给定的输入流中读入内容,直到遇到换行符为止(注意换行符也被读进来了 ) ,然后把所读的内容存入到那个 string 对象中去(注意不存换行符 );
- getline 只要一遇到换行符就结束读取操作并返回结果,哪怕输入的一开始就是换行符也是如此。如果输入真的一开始就是换行符,那么所得的结果是个空 string 。
string str;
getline(cin, str);//输入hello world换行符
cout << str ;//输出hello world
-
string加法运算
- C++:
- 当把 string 对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符( + )的两侧的运算对象至少有一个是 string;
- C++语言中字符串字面值并不是标准库类型string的对象,即:字符串字面值与string是不同的类型。
string str = "hello" + "world";//错误;
string str1 = "hello";
string str2 = str1 + "," + "world";//正确,等同于string str2 = (str1 + "," )+ "world";
- C#:两个字符字面值可以相加。
-
处理string对象中的字符
- 在cctype头文件中定义了一组标准库函数,这些函数可以获取或改变某个字符的特性。
- 处理每个字符,需要用到基于范围的for语句,即范围for语句。
- str.size()返回的类型是string::size_type类型,它是一个无符号类型(大于等于0)的值,而且能存下任何string对象的大小。
- 下标运算符[ ]接收的输入参数是string::size_type 类型的值,参数从0开始;返回值是该位置上字符的引用。
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
string str1 = "hello";
string str2 = str1 + "," + "world";
decltype(str2.size()) punctCount = 0;
for (auto s : str2)
{
if (islower(s))//小写字母
{
cout << s << endl;
}
if (isspace(s))//空格、回车、换行符时
{
cout << s << endl;
}
if (ispunct(s))//标点符号
{
cout << s << endl;
punctCount++;
}
}
cout << punctCount << " punctution characters in " << str2;
//转换成大写形式
for (auto &s : str2)//注意需要是引用
{
if (islower(s))
{
s = toupper(s);
}
}
cout << str2 << endl;
}
string str1 = "hello";
string str2 = str1 + "," + " world";
//依次处理 str2 中的字符直至我们处理完全部字符或者遇到一个空白
for (string::size_type i = 0; i != str2.size() && !isspace(str2[i]) && islower(str2[i]); i++)
{
str2[i] = toupper(str2[i]);
}
cout << str2;//HELLO, world
-
标准库类型vector #include <vector>
- 对象(引用不是对象)的集合,其中所有对象的类型都相同。集合中的每个对象都有一个与之对应的索引,索引用于访问对象。
- 因为vector"容纳着"其他对象,所以也被称作为容器。
- vector是一个类模板,不是类型。
- 模板本身不是类或者函数,相反可以将模板看作为编译器生成类或函数编写的一份说明。编译器根据模板创建类或函数的过程称为实例化。当使用模板时,需要指出编译器应把类或函数实例化成何种类型。
- 我们需要提供信息来指定模板到底实例化成什么类型,提供哪些信息由木板决定,格式为:模板名字<信息>
- vector需要的信息是存放对象的类型。
vector<int> intVec;
vector<Person> personVec;
vector<vector<int>> vVec;
-
初始化
- 默认初始化,创建一个指定类型的空vector。
- 使用列表初始化{}:用花括号括起来0个或多个初始元素值来进行初始化,注意类型必须相同。
- 创建指定数量的元素():用vector对象容纳的元素数量和所有元素的统一初始值来初始化vector对象。当没有指定初始值时,库会创建一个值初始化的元素初值,并把它赋给容器中的所有元素。这个初值由vector对象中元素的类型决定。
//默认初始化
vector<int> intVec;//初始状态为空,intVec不含任何元素
//在定义对象时指定初始值,类型需要相同
intVec.push_back(10);
vector<int> intVec2(intVec);//把intVec的元素拷贝给intVec2;
vector<int> intVec3 = intVec;//把intVec的元素拷贝给intVec3;
//创建指定数量的元素
vector<int> intVec4(5, 10);//{10,10,10,10,10}
//值初始化
vector<int> intVec5(5);//{0,0,0,0,0}
vector<int> intVec8( 1, 2, 3, 4, 5 );//错误
//列表初始化
vector<int> intVec6{ 5,10};//{5,10}
vector<int> intVec7{ 5 };//{5}
vector<int> intVec9 = {5,10 };
//列表初始化需要注意类型
vector<string> strVec{ "" };//{""}
vector<string> strVec{ 5 };//{"","","","",""}
vector<int> intVec6{ 5,10};//{5,10}
vector<int> intVec7{5};//{5}
for (auto a : intVec7)
{
cout << a << endl;
}
*列表初始化:初始化过程会尽可能地把花括号内的值当成是元素初始值的列表来处理 , 只有在无法执行列表初始化时才会考虑其他初始化方式。
- vector相关操作:
- push_back():向队尾添加元素;
- size():获取vector对象中元素个数。返回值的类型是由vector定义的size_type类型。要使用size_type,需指定它是由哪种类型定义的。
- vector对象(以及string对象)的下标运算符可用于访问或者修改已经存在的元素,即只能对确知已存在的元素执行下标操作。
vector<int>::size_type //正确
vector::size_type //错误