C++学习(64)

来源:互联网 发布:linux ssh连接数限制 编辑:程序博客网 时间:2024/06/07 01:31

1 分析下列程序:

#include<stdio.h>int main() {int i=3;printf("%d,%d\n",++i,++i);int j=3;printf("%d,%d\n",j+=2,j*=3);}

分析:函数的参数是从右向左压栈的,输出时从栈顶开始,相当于: int i = 3; ++i; ++i; printf("%d,%d",i,i);所以是 55

再举一个例子,int i = 1; printf("%d,%d", i +=2, i *= 3); 在输出i之前先进行了i *= 3和 i += 2;最终i = 5;所以结果是5,5;

 

为什么不是54?压入栈的是45,出栈却是55

分析:这跟编译器有关系,所以题目强调了在gcc编译下。一般编译器对i++++i的处理是不一样的(存储上不一样,这里不是强调语法上的不同)。我的理解是如果参数是i++这种的,其实入栈的不是i的值,而是i++这个表达式的值,是通过寄存器进行的压栈;如果参数是++i这样的那么入栈的就是i的值,i的值以最终结果为准。例如int i = 8; printf(“%d,%d,%d,%d\n”, ++i, --i, i++, i--);其过程是先把i--这一表达式的值通过寄存器压栈(理解成一个中间变量的值为i--然后入栈),i--的值仍为8,之后i++的值通过寄存器入栈(此时i--的减1效果完成,所以i++表达式的值为7),之后--i入栈和++i入栈,这两个压入的都是i的值(可以理解成变量i的内存地址对应的值,只需关注最终i的值,最终i的值仍为8);输出时从栈顶输出,结果为:8,8,7,8。

#include<stdio.h>int main() {int i=3;printf("%d,%d\n",++i,++i);int j=8;printf("%d,%d,%d,%d\n",++j,--j,j++,j--);}


 

2.分析下列程序:

#include<stdio.h>print(char *s) {if(*s) {print(++s);printf("%c",*s);}}int main() {char str[]="Geneius";print (str);}

分析:主要有两个知识点,一个是递归,相当于栈是FILO,另一个考察点是print(++s),指针先移动然后调用函数。

printf是从右往左输出的。

 

严谨的说这题没有正确答案。++后才进行递归,应该输出的是'\0'suiene。答案前面应该加上一个空

if只是判断当前指针指向的是否为'\0',进入if后s++,,指针后移了,所以if并不能避免输出'\0'

 

3.如何捕获异常可以使得代码通过编译?

class A{

       public:

       A(){}

};

void foo(){

       throw  new A;

}

A catch(A &&x)            Bcatch(A*x)          C catch(A &x)  D都对

分析:题目中问的是能否通过编译,只有B会捕获到异常,进行异常处理,而A和C由于和throw抛出的异常类型不匹配,导致这个异常不被捕获,从而成为未捕获的异常,调用terminate函数结束程序。

 

throw new A; throw出的是A *类型的指针所以catch(A * x);

new的返回类型是指向动态分配内存看throw首地址的指针,故catch这个throw时也是捕获指针类型,不是左右值引用。

 

A是右值引用,但是newA返回的并不是右值,而是可以修改的左值,所以A无法通过。

C中是对A类对象的引用,故也无法通过编译。

原创粉丝点击