该系列都是以考题的模式进行的,希望大家先别看答案,自己做答,再核对下分析,记录下自己的不足。

因为时间的关系,某志不会将每个答案进行详细分析,只会对自己的错误和经典问题进行说明,如您查看时有任何问题不清楚,欢迎留言提出,某志一定知无不言,言无不尽,呵呵~

当然某志也这么做^ ^V好吧,我们来一起努力。


Q1:What does the following program print?

#include <iostream>
using namespace std;
int main()
{
  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;
  return 0;
}

笃志猜测答案:10,0,1,1,3,1,7

标准答案: 10,10,1,3,1,7,1

T T错误原因:第二个最后值是0,但是x的值还是10。后面的位与运算”&“和与运算”&&“弄混淆了。


Q2: What does the following program print?

#include <iostream>
using namespace std;
int Vac = 3;
int main()
{
  int Vac = 10;
  ::Vac++;
  cout << ::Vac << endl;
  cout << Vac << endl;
  return 0;
}

笃志猜测答案:4,10

标准答案: 4,10

^ ^V:考察全局变量和局域变量对比的问题。


Q3:What will be the output of the following code?

int i = 3,j = 4;
i? i++: ++j;
printf( "%d %d\n", i, j );

笃志猜测答案:4,4

标准答案: 4,4

^ ^V:考察三元运算符的


Q4:What will be the output of the following code?

int i = 1,j = 2;
int k = i+++j;
cout << k << endl;

笃志猜测答案:3

标准答案: 3

^ ^V :i+++j是考察运算符优先级,应当是i++后再+j,但由于i++是先拿i进行运算,后再自增,所以结果是3


Q4:x = x + 1;x += 1;x++;这三条语句,哪条效率最高,为什么?

笃志猜测答案:x++最高,x+=1次之,x=x+1效率最低。

标准答案:x++最高,x+=1次之,x=x+1效率最低。

^ ^V:原因我们可以分步解释:

  • x++使用了两步,1,读取x的地址,2,x自增
  • x+=1使用了三步,1,读取x的地址,2,x+1,3,将得到的值传给x
  • x=x+1使用了4步,1,读取右x的地址,2,x+1,3,读取左x的地址,4,将得到的x+1值传到左边x处。

Q5:What will be the output of the following C code?

#define product (x) (x*x)
int main()
{
  int i = 3, j, k;
  j = product( i++ );
  k = product( ++i );
  printf( "j = %d, k = %d", j, k );
  return 0;
}

笃志猜测答案:9,25

标准答案: 9,49

T T错误原因:忘记了在第一步中i已经自加了“两”次,第二步中i也自加了“两”次,一直认为是一次。。

本题考察的是宏定义以及前自增,后自增运算。


Q6:If there are “int a = 5, b = 3;”,the values of a and b are ___ and ___ after execute”!a&&b++;” .

笃志猜测答案:5,4

标准答案: 5,3

T T错误原因:因为上次错误的教训,某志这次没有将题目的运算结果为0写出,但是却忘记了一个问题,在“!a”运算出为0假时,由于&&号,之后的运算编译器都将不再进行,直接无视。所以后面无论是++b,还是b++或是其他的代码,都会完全无效。


Q7:We have two pieces of code,which one do you prefer,and tell why?

A: Code 1:

  if( 'A' == a )
  {
      a++;
  }

Code 2:

  if( a == 'A' )
  {
      a++;
  }

B: Code 1:

  for( i=0; i<8; i++ )
  {
     X = i + Y + J * 7;
     printf( "%d", x );
  }

Code 2:

  S = Y + J * 7;
  for( i=0; i<8; i++ )
  {
     printf( "%d", i+S );
  }

笃志猜测答案:A–Code1,B–Code2。

标准答案: A–Code1,B–Code2。

^ ^V:原因是,A中第一种模式,可以避免我们将“==”写成“=”而造成编译出错。B中第二种模式是将部分加法运算放到循环外,可以减少重复运算,提高效率。缺点是不够简洁。


Q8:What will be the output of the following code?

char Fun( void )
{
  unsigned int a = 6;
  int b = -20;
  char c;
  ( a + b > 6 )?( c = 1 ):( c = 0 );
  return c;
}

笃志猜测答案:0

标准答案: 1

T T错误原因:原来这是个考察类型转换的题目,其中a+b的结果不是-14。因为无符号整型和整型计算后,会自动转换为无符号整型,得到结果是一个极大的无符号整型4294967382,再三元运算,结果自然是1了。呜呜。。


Q9:

21 22 ……
20  7  8  9 10
19  6  1  2 11
18  5  4  3 12
17 16 15 14 13

看清楚上列数字的排列规律,我们假设1所在的坐标是(0,0),x向右为正,y方向向下为正,如此时7的坐标是(-1,-1),我们现在编程实现,当我们输入任意一点的坐标(x,y),输出该坐标对应的数字。

笃志先哭,规律是找到了,可是T T怎么写却完全没有头绪了。不过,似乎(0,0)(1,-1)(2,-2)都是连续奇数的平方,1,9,25。。。恩,算不算切入点?当x>0且x==(-y)时,(x,y)处的值为(2x+1)*(2x+1),再一个控制行判断,一个控制列判断,啊,有点乱,明天继续分析。

标准答案:呵呵,和某志切入点类似,之后也是加了个行列控制,看来思想还是一致,大家看看代码吧。

#include <stdio.h>
#define max(a,b) ((a)<(b)?(b):(a))
#define abs(a) ((a)>0?(a):-(a))
//两个宏定义,一个取大值,一个取绝对值
int foo(int x, int y)
{
  int t = max(abs(x), abs(y));
  int u = t + t;
  int v = u - 1;
  v = v * v + u;
  if( x == -t )
     v += u + t - y;
  else if( y == -t )
     v += 3 * u + x - t;
  else if( y == t )
     v += t - x;
  else v += y - t;
  return v;
}
int main()
{
  int x, y;
  for( y = -4; y <= 4; y++ )
  {
    for( x = -4; x <= 4; x++ )
    {
       printf( "%5d", foo(x, y) );
    }
    printf( "\n" );
  }
  while( scanf("%d%d", &x, &y)==2 )
    printf( "%d\n", foo( x, y ) );
  return 0;
}

Q10:There are two int variables: a and b,don’t use “if”,“?:“,“switch”or other judgement statements,find out the biggest one of the two numbers?

笃志猜测答案:不会T T

标准答案:int max = ((a + b) + abs(a - b)) / 2

T T:这东西确实不好想啊。。某志领教。


Q11:如何将a,b的值进行互换,并且不使用中间变量。

笃志猜测答案: a = a + b; b = a - b; a = a - b;

标准答案: a = a ^ b; b = a ^ b; b = a ^ b;

答案说明:汗,某志的方法有问题,原因是当a,b两个值过大时,a+b就可能出现超过int界限的问题,居然用异或……好办法。


Q12:在C++程序中调用被C编译器处理过的函数,为什么要加上extern “C”?

笃志猜测答案:C和C++编译器不同,编译后的文件名和函数名都按照一定规则进行修改,加上这句为了编译器识别。

标准答案:C++语言支持函数重载,C语言不支持函数重载。函数在被两者编译后的名字不同,例如fun(int a)函数被C编译器编译后在库中名字为_fun,而在C++编译后将名为类似_fun_int之类的名字,C++提供了交换指定符号extern “C”解决名称匹配问题。

答案分析:某志仅仅记住了表面,却没有清晰其原因实质“重载性”导致的述说不明白。


Q13:头文件中ifndef/define/endif是干什么用的?

笃志猜测答案:防止重复预编译。

标准答案: 防止该头文件被重复使用。


Q14:#include “filename.h”和#include 有什么区别?

笃志猜测答案:”“包含的头文件,系统将优先从用户自定义的文件夹开始寻找,查找不到则到系统文件夹寻找,<>包含的头文件,编译器将直接到系统文件夹中寻找。

标准答案:<>编译器将从标准库路径开始搜索,“”编译器将从用户的工作路径开始搜索。


Q15:如何判断一段程序是使用C编译程序还是使用C++编译程序?

笃志猜测答案:呃,看包含头文件的方式吧,还有标准输入输出函数的名称。

标准答案:C++编译时定义了_cplusplus.C编译时定义了STDC

答案说明:呜,完全没听说过啊。>_<开始背记,整理下回来问问。。


Q16:在main主函数执行完毕之后,是否可以再执行一段代码?给出说明。

笃志猜测答案:不可能。除非仅仅将某函数的定义在main之下,但其使用必须在main函数之内才会调用,main函数结束之后,任何代码不可执行。

标准答案:可以使用atexit()函数注册一个函数,代码如下:

#include <stdlib.h>
int atexit( void ("function")(void));
#include <stdlib.h>
#include <stdio.h>
void fn1( void ),void fn2( void );
int main( void )
{
  atexit( fn1 );
  atexit( fn2 );
}
void fn1()
{
  printf("Hello");
}
void fn2()
{
  printf("World");
}

答案分析:说真的,实在不知道还有这方法,不过某志在拿去编译后也根本无法正常运行。怀疑是代码有误或是很过时的一种方法,无论如何,明天去问问高手,暂时有个印象就好