最近在看《剑指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修饰普通变量
1 2 3 4 5
| int i=42; int &r1=i; const int &r2=i; r1=0; r2=0;
|
1 2 3 4 5
| int i=42; int &r1=i; const int &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; }
|
运行结果:
分析:
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流中的数据输入字符串到一个变量里,是以遇到空格跳到下一个字符串的这样的形式连续读取的。这在刷题过程中,会体现在使用循环的过程中。如下:
</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); Solution so1; string ans=so1.reverseWords(s); cout<<ans<<endl; return 0; }
|
运行结果:
over☕️~