C++
1、下列程序的运算结果是
int x = 2,y,z;
x *=(y=z=5);cout << x << endl;
z = 3;
x == (y = z); cout << x << endl;
x = (y == z);cout << x << endl;
x = (y & z);cout << x << endl;
x = (y && z); cout << x << endl;
y = 4;
x = (y|z); cout << x << endl;
x = (y||z);cout << x << endl;
答案
10,10,1,3,1,7,1
解析
- :y = 5 , z = 5 , x= 10;
- :y = 3 , z =3 , x= 10 ;
- : (3==3) = 1 , x =1;
- : y=0011 , z = 0011 , x = 0011 =3;
- : y=3 , z =3 , x = 1;
- : y =0011 , z =0011, x=0011 = 3;
- : y = 3, z =3 , x =1;
- : 1;
2、下列程序的运算结果是
int Vec = 3;
int main()
{
int Vac = 10;
::Vac++;
cout << ::Vac << endl;
cout << Vac << endl;
return 0;
}
答案
4,10
解析
可以通过::
来访问全局变量
3、下列程序的运算结果是
int i = 3,j = 4;
i ? i++ : ++j;
printf("%d,%d\n",i,j);
答案
4,4
解析
自己去了解三目运算符用法
4、下列程序的运算结果是
int i = 1,j=2;
int k = i+++j;
cout << k << endl;
答案
3
解析
C/C++编译器在遇到符号时,总是一直将相邻的下一个操作符纳入当前解释的表达式中,除非新加入的操作符会使原本成立的表达式变成非法结果(贪婪性),例如这一例中,在读取i之后会读取第一个加号,此时一个加号是合法的,所以会继续读取下一个加号,之后判断发现两个加号也是合法的,所以继续读取第三个加号,此时发现三个加号的操作符是不合法的,不存在这样的操作符,于是不读取第三个加号,将i与前两个加号结合生成了i++的运算,第三个加号和后面的j则参与普通的加法运算。
5、x = x+1 ,x+=1 ,x++;哪个效率更高?为什么?
解析
x = x+1效率最低,因为执行过程是读取右边x的地址,然后x+1,然后读取左边x地址,最后把右边的值传给左边的x(编译器不会认为左右x的地址是相同的)
x+=1:读取左x的地址,执行x+1,将值传给x(x的地址已经读出)
x++效率最高,读取右x的地址,x自增1;
6、下列程序输出的是啥
#define product(x) (x*x)
int mian()
{
int i = 3,j,k;
j = product(i++);
k = product(++i);
printf("j = %d,k = %d",j,k);
return 0;
}
答案
9,49
解析
j = (i++)*(i++) = 3 * 3 = 9;
当前 i = 5;
前缀自增自减运算符 的 优先级比乘法高
k = ( ++i ) * (++ i) = 7 * 7 = 49;
7、int a =5,b = 3;执行!a && b++
后a和b的值分别是
答案
5,3
解析
!a = 0; 没有进行赋值运算所有a还是5
&& 运算符在左边不成立的情况下不会运行右边
扩展
只有四种运算符明确规定了运算对象的求值顺序
“&&
” , “||
” , “?
: ”, “,
”
8、下列哪种写法更好,为什么
if('A' == a)
{
a++;
}
if(a == 'A' )
{
a++;
}
解析
第一种的写法更好,因为如果不小心把==写成=,编译器不允许常量被赋值,所以可以检查错误。
for(int i = 0;i < 8;i++)
{
X = i+Y+J*7;
printf("%d",x);
}
S = Y+J*7;
for(int i = 0;i < 8;i++)
{
printf("%d",i+S);
}
解析
第二种写法更好,将部分加法运算放到循环体外面,提高了效率,缺点是程序不够简洁。
9、下列运算结果是?
char foo(void)
{
unsigned int a = 6;
int b = -20;
char c;
(a + b > 6)?(c=1):(c=0);
reuturn c;
}
扩展
术语 foobar , foo , bar , baz 和 qux 经常在计算机编程或计算机相关的文档中被用作 占位符
的名字。当变量,函数,或命令本身不太重要的时候, foobar , foo , bar ,baz 和 qux
就被用来充当这些实体的名字,这样做的目的仅仅是阐述一个概念,说明一个想法。这些术语本身相对于使用的场景来说没有任何意义。
解析
<所以取模究竟怎么算>
unsigned int b = -20 对 4294967296 取模后的余数 = 4294967276;
a + b = 4294967282;
unsigned int 类型的数据在与int类型数据运算后,会自动转化为unsigned int类型,所以a+b的值并不是-14,而是unsigned int类型的数4294967282,所以返回值是1.
解决办法,进行类型转换,或者用一个int类型接收。
10螺旋队列
21 22 23 24 25 26
20 7 8 9 10 27
19 6 1 2 11
18 5 4 3 12
17 16 15 1
看清以上数字的排列规律,设1点的坐标是(0,0),x方向向右为正,y方向向下为正。列入7的坐标是(-1,-1),2的坐标为(0,1),3的坐标为(1,1),编程实现任意一点的坐标(x,y)输出对应的数字。
解析
解析来源
/**
* 打印螺旋数列
*
*
*/
public class SpiralSeq {
public static void main(String[] args) {
for (int y = -5; y <= 5; ++y) {
for (int x = -5; x <= 5; ++x) {
System.out.printf("%5d", spiral(x, y));
}
System.out.println();
}
}
private static Object spiral(int x, int y) {
int c = max(abs(x), abs(y));// 当前坐标所在圈
int max = (c * 2 + 1) * (c * 2 + 1);// 当前圈上最大值
if (y == -c) { // 上边
return max + (x + y);
} else if (x == -c) {// 左边
return max + (3 * x - y);
} else if (y == c) {// 下边
return max + (-x - 5 * y);
} else {// 右边
return max + (-7 * x + y);
}
}
private static int max(int n1, int n2) {
return n1 > n2 ? n1 : n2;
}
private static int abs(int x) {
return x > 0 ? x : -x;
}
}