C++基础(1)
C++基础(2)
C++基础(3)
目录
1. 字符串
1.1. 命名空间using声明
std::cin //意思就是要使用命名空间std::中的名字cin。
- 头文件中不应包含using声明。
1.2. 标准类库string
直接初始化和拷贝初始化
- 使用等号初始化一个变量,实际上执行的是拷贝初始化,编译器把等号右侧的初始值拷贝到新建的对象中。
- 如果不使用等号,则执行的是直接初始化。
string s5=yige";///单个用拷贝初始化
string s6(10,'c');//多个的话,用直接初始化
1.2.1 string对象上的操作
一个类除了要规定初始化对象的方式外,还要定义对象上所能执行的操作。
- 字面值和string对象相加,必须确保”+“两侧至少有一个是string
- string s1="hello",s2="world"; string s3=s1+","+s2; //正确,
- string s3 = "sssss" + "," + "aaaa";// 错误,不能全部是字面值
- string s3 = "," + "s2" + s ; //错误,先是两个字面值相加,是不可的。相当于("," + "s2") + s .
- string s3 = s+ "," + "s2" ;//可以,先是string+“”,就是string对象,然后再加一个“”。相当于(s+ "," )+ "s2" .
- 字符串中的字面值和string 是不同的类型。也就是"常量"和string 常量,不一样。
1.2.2 处理string中的字符
- 头文件 cctype
- isalnum(c) 当c是字母或数字时为真。
- 。。。。。。。。
- 来遍历字符串string或数字中的每一个字符。不能修改
for (auto c:longstr)
{
cout << c << endl;
}
-
- 要想改变字符串中的值,必须把循环变量定义成引用类型。每次迭代后,c将引用string对象s的下一个字符。
for (auto &c:longstr)
{
if (ispunct(c))
{
c = '8';
}
cout << c << endl;
}
1.2 标准类库vector
标准类库vector表示对象的集合,其中所有对象的类型都相同。集合中的每个对象都有一个与之对应的索引,索引用于访问对象。vector也称为容器。想使用vector必须包含适当的头文件<vector>
- 使用:
- vector<int> ivec; //由vector生成的类型,必须包含vector中的元素类型,<int>
- vector<> 可以是绝大多数类型的对象作为其元素,但因为引用不是对象,所以不包含在vector中。
- 定义和初始化vector
- 初始化的方法有很多。不同的版本也会有新的初始化方法。
- 在多数情况下,这些不同的初始化是可以相互等价使用。但也有例外:
- 其一:使用拷贝初始化时(=),只能提供一个初始值。
- 其二:如果提供的是一个类内初始值,则只能使用拷贝初始化或使用花括号的形式初始化。
- 初始化的方法有很多。不同的版本也会有新的初始化方法。
- 列表初始值和元素数量
- vector <int> v1(10); //v1有10个元素,每个元素值都是0
- vector <int> v2{10} ; //v2有1个元素,该元素的值是10;
- 使用圆括号是提供的值是用来构造vector对象的。
- 使用花括号,列表初始化。如果要想列表初始化值必须与元素的初始值相同。
1.2.1 向vector对象中添加元素
创建一个容器,并不清楚实际所需的元素个数。
- V2.push_back(value);//把value放到V2的尾端。
- 如果循环体内部包含有向vector 对象添加元素的语句,则不能使用范围for循环。
- 遍历的话,不需要引用。
1.3 迭代器
已经知道可以用下标运算符来访问string对象的字符或vector对象的元素,还有另外一种更通用的机制,也可以实现同样的目的,这就是迭代器。所有的标准库容器都可以使用迭代器。
- v.end 是一个指向容器尾元素的下一位置的迭代器,返回的是一个容器根本不存在的”尾后“元素。
- s.bengin()!=s.end():确保s非空。
1.3.1 迭代器类型
- iterator 的对象可读可写。
- const_iterator和常量指针差不多,能读但不能修改。
1.3.2 begin和end运算符
begin和end返回的具体类型由对象是否是常量决定,如果对象是常量,则返回const_itertor。如果对象不是常量,返回iterator。
1.4 迭代器运算
2. 数组
- 不允许一个数组初始化另一个数组:
- int a[]={0,1,2};int a2=a;//错误,
- 不能将一个数组直接赋值给另一个。
2.1 理解复杂的数组声明
1,2从右向左依次绑定。3,4从内向外阅读比较好,先看*Parray是个指针,接下来观察右边,可知道Parray是个指向大小为10的数组指针。
- int *ptrs[10]; //
- int &refs[10] ;//错误 不存在引用的数组。
- int (*Parray)[10]=&arr; //Parray指向一个含有10个整数的数组。
- int (&arrRef)[10]=arr; //arrRef 引用一个含有10个整数的数组。
- int *(&arry)[10]=ptrs; //arry是数组的引用,该数组含有10个指针。先看arry是一个引用,观察右边知道arry引用的对象是一个大小为10的数组,最后观察左边知道,数组元素类型是指向int的指针。
2.2 访问数组元素
- 访问数组下标的时候,通常定义为size_t类型,size_t是一种机器相关的无符号类型,他被设计足够大以便能表示内存中任意的大小。
2.3 指针和数组
2.4 C风格字符串
- 使用strcpy(largetStr," ");要注意largetStr的大小,这样代码充满了风险而且经常导致严重的安全泄露。
- 在使用C风格的字符串时,不能使用string类型初始化,要用转换下,列如:
- char *str=s;//错误,s是string对象初始化。
3. 表达式
表达式由一个或多个运算符对象组成,对表达式求值将得到一个结果。字面值和变量是一个简单的表达式。
3. 1 类型转换
3. 1.1 隐式转换
3. 1.2 算术转换
4. 语句
4.1 try语句块和异常处理
典型的一场包括失去数据库连接以及遇见意外输入等。
异常处理机制为程序中异常检测和异常处理两部分提供支持。
- 异常处理包括:
- throw:
- try:
- try中抛出的异常通常会被某个catch结束。
- 一套异常类:
- 用在throw表达式和相关的catch子句之间传递异常的具体信息。
4.1.2 try 语句块
- try快之后是一个或多个catch子句。catch子句包括三部分:关键字catch、括号内一个对象的声明以及一个块。
- 当选中某个catch子句异常后,执行与之对应的块。
cin >> a >> b;
try
{
if (a == b)
{
//抛出异常
throw runtime_error("Data 输入错误");
}
cout << a + b;
}
catch (runtime_error e)
{
cout << "不能输入一样";
}
- 执行try catch后,便继续执行。如果只有throw,则在抛出之后,便停止运行了。
while (cin >> a >> b)
{
cout << "执行到这里6" << endl;
try
{
if (a == b)
{
//抛出异常
throw runtime_error("Data 输入错误");
}
cout << a + b;
cout << "执行到这里" << endl;
}
catch (runtime_error e)
{
cout << "重新输入";
int c;
cin >> c;
if (!c)
{
break;
cout << "执行到这里3" << endl;
}
cout << "执行到这里8" << endl;
}
}
cout << "执行到这里" << endl;
4.1.2.1 函数在寻找处理代码的过程中退出
- try内嵌套的话,如果在try内发生异常,首先搜索抛出异常的函数,如果没有找到匹配的catch则终止该函数,并在调用该函数继续寻找,如果还是没有找到匹配的catch子句,这个新的函数也被终止,以此类推。
4.1.3 标准异常
C++标准库定义了一组类,用于报告标准库函数遇到的问题。
- exception 通用的异常类,它只报告异常的发生,不提供任何额外的信息。
5.函数
5.1参数传递
5.1.1引用传递
int n=0,i=42; int &r=n;//r绑定了n(即 r是n的另一个名字)
5.1.1.1 使用引用避免拷贝
- 如果拷贝大的类类型对象或者容器对象比较低效,甚至有些类不支持拷贝操作。当某种类型不支持拷贝操作时,函数只能通过引用形参访问该类型的对象。
- 例如:
- 函数比较两个string对象的长度,因为string对象可能非常长,所以要避免直接拷贝他们,这时引用参数比较明智。因为比较长度无需改变string对象内容。
bool isShorter(const string &s1,const &s2)
{
return s1.size()<s2.size();
}
5.1.1.2 使用引用形参返回额外信息
一个函数只能返回一个值,然而有时函数需要同时返回多个值。
5.1.2 const形参和实参
当形参有顶层const时,传给他常量对象或者非常量对象都是可以的。
5.1.3 数组引用形参
void print(int (&arr)[10])
{
for(auto elem:arr)
cout<<elem<<endl;
}
- 其中f(int &arr[10])//错误:将arr声明成了引用的数组
- f(int (&arr)[10]) //正确:arr是具有10个整数的整型数组
int i=0; j[2]={0,1}
int k[10]={0,1,2,3,4,5,6,7,8,9};
print(&i);print(j);//错误实参不含有10个整数的数组。 print(k);//正确,实参是含有10个整数的数组
- void print(int matrix[][10],int rowSize);//相当于 int (*matrix)[10]
5.2 函数重载
- 一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开来。