0%

C++|一些知识点总结

最近在看《剑指offer》,也一直在用C++刷题,总是会遇到一些易混的地方,记录一下,以便以后翻阅。

this指针

参考链接:

https://blog.csdn.net/xiaohaijiejie/article/details/51787351

https://blog.csdn.net/qq_40354578/article/details/88088048

this指针是指向实例本身,主要在运行对象自身的函数对函数数据成员重名的情况有用。

下面我们设置重名的函数数据成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
using namespace std;
class Array
{
public:
Array(int len)//有参构造函数
{
len=len;
}
~Array()//析构函数
{

}
void setLen(int len)
{
len=len;
}
int getLen()
{
return len;
}
void printInfo()//打印值
{
cout<<"len="<<len<<endl;
}
private:
int len;
};
int main()
{
Array arr1(10);
arr1.printInfo();
system("pause");
return 0;
}

运行结果如下:

我们可以发现结果错误。接下来,我们使用this指针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<stdio.h>
#include<string.h>
#include<string>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;

class Array{
private:
int len;

public:
Array(int len){
this->len=len;
}

~Array(){}

void setLen(int len){
this->len=len;
}

int getLen(){
return this->len;
}

void PrintInfo(){
cout<<"len:"<<this->len<<endl;
}
};

int main(){
Array a(10);
int b =a.getLen();
a.PrintInfo();
return 0;

}

运行结果:

运行成功。

const的使用

const修饰普通变量
  • const修饰普通变量的时候,必须初始化;
1
const int a=14;
  • 不能通过修改常量的引用来修改绑定的对象;
1
2
3
4
5
int i=42;
int &r1=i;
const int &r2=i;//r2也绑定了对象i,但不允许通过r2修改i的值
r1=0; //正确
r2=0; //错误,r2是一个常量引用
  • 不能将非常量引用指向一个常量对象;
1
2
3
4
5
int i=42;
int &r1=i;
const int &r2=i;//r2也绑定了对象i,但不允许通过r2修改i的值
const int ci=1024;
int &r2=ci;//错误
const修饰函数的返回类型
1
2
3
const void func();
void const func();
//两种写法等价
const修饰函数的形参变量
1
2
3
void func(const int val);
void func(int const val);
//两种写法等价

值得注意的是,有时候会遇到这种情况:void func(const int &val).const被用来修饰函数参数,它的作用是:防止传入的参数内容在函数体内被改变,但是仅对指针和引用有用。因为如果是按值传递,传给参数的仅仅是实参的副本,即使在函数体内改变了形参,实参也不会得到影响。

1
2
3
void fun(const int i){
i = 10;
}

在函数体中,是不能改变i的值的。

1
2
3
4
void h(const A & a){
…………
…………
}

传递进来的参数a是实参对象的副本,要调用构造函数来构造这个副本,而且函数结束后要调用析构函数来释放这个副本,在空间和时间上都造成了浪费,所以函数参数为类对象的情况,推荐用引用。但按引用传递,造成了安全隐患,通过函数参数的引用可以修改实参的内部数据成员,所以用const来保护实参。

&引用

在函数参数中,使用&会避免大量的数据开销,提高性能。因为对引用的修改,就是对原值的修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using namespace std;
//交换两个值
void swap (int& x, int& y)
{
int temp;
temp = x;
x= y;
y =temp;
}

int main(int argc, char *argv[])
{
int a = 1;
int b = 2;
swap(a,b);
cout <<a <<" " <<b<<endl;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

using namespace std;

void foo(int val)//按值传递参数
{
val = 10;
}
void bar(int& val)//按引用传递参数
{
val = 10;
}
void zoo(int *pval)//按指针传递参数
{
*pval = 10;
}
int main(int argc, char *argv[])
{
int a = 1;
int b = 1;
int c = 1;
foo(a);
bar(b);
zoo(&c);
cout <<a <<" " <<b<<" "<<c <<endl;
return 0;
}

运行结果:

分析:

  • foo函数是按值传递,执行foo函数的执行,相当于对a的副本进行修改。在调用完foo函数后,a的值还是1,不会改变。

  • bar中value的传递是引用,对引用的修改和对原值修改是一样的。

  • zoo中value的传递是指针,指针对值得修改,原值也会修改。

stringstream

1.声明一个stringstream对象

1
2
3
#include<sstream>
using namespace std;
stringstream ss;

2.常用函数

2.1.ss.str()

str()函数的作用是:将ss中的对象转换成字符串输出。ss.str("")这段代码表示的是将ss流清零。

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
stringstream ss;
ss << "hello ";
ss << "world!";
cout<<ss.str()<<endl;
return 0;
}

此外,stringstream最值得注意的是:从stringstream流中的数据输入字符串到一个变量里,是以遇到空格跳到下一个字符串的这样的形式连续读取的。这在刷题过程中,会体现在使用循环的过程中。如下:

151. 翻转字符串里的单词

</br>

给定一个字符串,逐个翻转字符串中的每个单词。

示例 1:

输入: “the sky is blue”
输出: “blue is sky the”

示例 2:

输入: “ hello world! “
输出: “world! hello”
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。

示例 3:

输入: “a good example”
输出: “example good a”
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

AC代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<stdio.h>
#include<string.h>
#include<string>
#include<vector>
#include<sstream>
#include<iostream>
using namespace std;

class Solution{
public:
string reverseWords(string s) {
stringstream ss;
ss<<s;
string ans="";
string temp;
while(ss>>temp){
ans=" "+temp+ans;
}
if(ans!=""){
ans.erase(ans.begin());
}
return ans;
}
};

int main(){
string s;
getline(cin,s);//cin遇到空格就会终止输入,索引需要使用getline函数。
Solution so1;
string ans=so1.reverseWords(s);
cout<<ans<<endl;
return 0;
}

运行结果:

over☕️~

Would you like to buy me a cup of coffee☕️~