上一节写了一篇不负责任的博文,被踩了呢,导致有点失落呢。
其实纯问问题,的确是不好,因为看博文很大一个优势就是为了更直接看到想看的东西。
好啦,回归整题。
1.你脑海中的运算符有哪些,按优先级排个序?
这个问题明显没有标准答案,但是最基本的还是要有吧。
比如+ ,- ,* ,/ ,%, 前++/--,后++/--,=,<, >, << ,>>,(),&,^,|,~以及逗号","域名符"::",&&,||等等等等。
其优先级麻,这个可能会稍微麻烦一点,但是自己简单试验肯定可以做出来的。
所谓的优先级顺序可以看博文最后的表。
2 .malloc/free 和 new/delete的区别?(我没有跑题?!)
从功能上两者都是申请/释放动态的数组但是,malloc/free是stdlib的函数,需要加头文件stdlib,而new/delete是运算符。
1、malloc/free是C/C++中的方法(函数),new/delete是C++中的操作符。
2、malloc/free使用的内存空间为堆区,new/delete是free store区。
3、free需要判断非空,非空才能释放,但是delete是不需要的
4、另外在使用new/delete是调用构造函数/析构函数,而malloc/free仅仅是对内存分配,也因此不能满足非内部数据。
3.让你来写一个重载函数++i,i++,你怎么写?
这个是基本功
/*********************************************************** > OS : Linux 3.11.10-301.fc20.x86_64 Fedora20 > Author : yaolong > Mail : dengyaolong@yeah.net > Time : 2014年07月17日 星期四 09时02分44秒 **********************************************************/ #include<iostream> #include<cstdio> #include<string> #include<cstring> using namespace std; class A{ public: int x; A(int x=0){ this->x=x; } A operator ++(int ){ //i++,先返回复制品,再搞原对象 A tmp=*this ; this->x++; return tmp; } A operator ++(){//++i,直接修改对象 this->x++; return *this; } }; int main(){ A a1(3); A a2=a1++; cout<<a2.x<<endl;; //3 cout<<a1.x<<endl; //4 A a3=++a2; cout<<a3.x<<endl; //4 cout<<a2.x<<endl; //4 }
4.来看个程序
#include<iostream> using namespace std; int main(){ int x=3; cout<<x+x%2==1<<endl; return 0; }
这个程序是不能正常运行的,编译错误,根据优先级看来是% , + , <<, ==
所以整个式子解释应该是
x%2 -> 1
x+ 1 -> 4
1<<endl 出错了
下面假如式子变成这样,
cout<<(x+x%2==1<<2)<<endl;
这样整个式子的解释是这样的
因为()优先级最高(在这个式子中),所以先解释()内的
x%2 -> 1
x+1 ->4
1<<2 -> 4
4 ==4 得到1
之后到运算符<<
而<<是从左到右的,故cout<<1 之后再输出转行
输出的为
1
当我们这样写
int y=x+x%2==1<<2;
cout<<y<<endl;
这时候就没有错,为什么?因为=号的优先级很低,只有逗号比其更低了,就只有一个
我们不是经常这么做吗?
int x=3,y;
5.再来看一个?跟你想的又一样不一样?
#include<iostream> using namespace std; int main(){ int x=3; cout<<((x+x%2)==1)<<endl; cout<<(x+(x%2==1))<<endl; return 0; }这个用上面的分析,很容易就知道了
第一个先执行最里层括号
(x+x%2)
而%比+优先,所以就是
x%2 ->1
x+1 -> 4
之后外层括号
4==1 -> 0(false)
第一个输出为0
第二个非常容易知道
x%2->1
1==1 -> 1(true)
x+1 -> 4
第二个输出4
6.来个难一点的,感觉一下逗号和括号的恶心?
#include<iostream> using namespace std; void fun0(int x,int y ,int z){ cout<<x<<" "<<y<<" "<<z<<endl; int a=2,b=3,c=7; x=a*b,c; y=(a*b+z,z=c); cout<<x<<" "<<y<<" "<<z<<endl; } void fun1(int x,int y,int z){ cout<<x<<" "<<y<<" "<<z<<endl; int a=2,b=3,c=7; y=(x=a+b+z),(z=b+c); cout<<x<<" "<<y<<" "<<z<<endl; } void fun2(int x,int y,int z){ cout<<x<<" "<<y<<" "<<z<<endl; int a=2,b=3,c=7; y=((x=a+b+z),(z=b+c)); cout<<x<<" "<<y<<" "<<z<<endl; } int main(){ int x,y,z; fun0(x,y,z); fun1(x,y,z); fun2(x,y,z); }
这个题目是相对过分的,因为手写根本写不出正确答案,不同编译器输出结果页不一样。
看fun0(x,y,z)
因为x,y,z没有初始值,所以每个函数的第一个输出x,y,z都是编译器默认的。
int a=2,b=3,c=7; x=a*b,c; y=(a*b+z,z=c);这个,先声明了a=2,b=3,c=7
x=a*b,c
因为逗号比=优先级低,前面说过,=号是倒数第二低,逗号是倒数第一,x=6,c没有任何改变
y=(a*b+z,z=c)
先运行括号的东西
(a*b+z,z=c)
,号是从左到右运行,如果感兴趣的朋友可以试验一下(p=a*b+c,z=c),把p数出来就知道了
所以先执行表达式
a*b+z,得到2*3 +z(z是一个乱七八糟的数,我的GCC编译出来的是32767),
再执行z=c,而(表达式1,表达式2,表达式……)最后返回的是最后一个表达式
所以y=z=c,y=7,z=7
第一个fun0在我这里输出为
0 0 32767 6 7 7对于fun1,2也是通=,的优先级来判断
非常容易就可以推断出来其结果
最后总的输出为
0 0 32767 32773 6 7 7 0 0 32767 32772 32772 10 0 0 32767 32772 10 10下面再附带一个fun3,用于测试上述到的逗号的从左到右执行
void fun3(int x,int y ,int z){ cout<<x<<" "<<y<<" "<<z<<endl; int a=2,b=3,c=7,p; x=a*b,c; y=(p=a*b+z,z=c); cout<<p<<endl; cout<<x<<" "<<y<<" "<<z<<endl; }
7.我们用%来做余运算,%只能应用于正整数对吗?
这个问题自己测试就可以拉,是可以对非0的整数进行操作,但是不能对浮点型等操作。
8.域运算符::我们常常用到,请问::可以重载吗?
不可以的,运算符有一些是不能重载的。比如本题的::和.等等。在文章最后会有提到可否重载。
9.运算符重载作为非成员函数重载时必须定义为友元函数?
不是的,当操作的成员为公开的时候不一定要定义友元函数。
10. 运算符必须是符号吗?(即只能是+,-,*,/,::之类的吗?)
不是的,文章一开始就提到了,new/delete是运算符。还有sizeof,和强制转换操作符等。