第五章 程序设计基本概念
1. 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是否相等, x不变
x=(y==z); cout <<x<<endl; //布尔运算
x=(y&z); cout <<x<<endl; //按位与
2=(y&&z); cout <<x<<endl; //与运算
return 0;
}
2. what does the following program print?
#include <iostream>
using namespace std;
int Vac =3;
int main()
{
int Vac=10;
::Vac ++;
cout <<::Vac<<endl; //4 全局变量
cout <<Vac <<endl; //10 局部变量
return 0;
}
3. x=x+1 X+=1, x++哪个效率高
x=x+1最低, 执行如下:
(1) 读取右边x的地址
(2) x+1
(3) 读取左边x的地址
(4) 将右边的值赋给左边的x (编译器不认为左右两边的x的地址相同)
X+=1次之, 执行如下:
(1) 读取x的地址
(2) x+1
(3) 将得到的值传给x (x的地址已经读出)
x++最高, 执行如下:
(1) 读取x的地址
(2) x自增1
4. what does the following program print?
#include <iostream>
using namespace std;
#define product (x) (x*x)
int main()
{
int i=3,j,k;
j=product (i++); //j=9
k=product (++i); //j=7*7
}
5. 下列哪个编程风格好
A //a 是个变量
1.if ('A' ==a) a++; //这个好, 万一"=="错写成"=", 编译器不允许为常量赋值, 所以可以报错
2.if ( a=='A') a++;
B
1. for (i=0;i <8; i++)
{
X=i+Y+J*7;
printf("%d",x);
}
2 S=Y+J*7; //这个好, 将部分加法放到循环外面, 提高了效率, 缺点是程序不够简洁
for (i=0;i <8; i++)
{
printf("%d",S+i);
}
6. what does the following program print?
#include <iostream>
using namespace std;
int main()
{
unsigned int a = 6;
int b = -20;
char c;
( a + b > 6 ) ? ( c = 1 ) : ( c = 0 );
cout << int ( c ) << endl; //1
cout << a + b; //4294967282
return 0;
}
//解析: unsigned int 类型的数据与int 类型的数据相运算后,自动转化成 unsigned int 类型,因此-20
//变成了一个非常大的正整数。因此 a+b 的值不是-14, 而是一个unsigned int 类型的数 4294967282, 因此c=1. 与实际我们想要
//得到的结果不同。
//类推:当表达式中存在有符号int long 类型和无符号int long 类型的时,所有的操作数都自动转换为无符号类型。
//理由: 算数转换的一般原色是尽可能多的保留类型表达式中涉及到的值的精度,这正是通过把不同的类型提升到当前出现的最宽的类型来实
现
//解决:可以定义一个int 类型的数接收 a+b 的值, 如int c=a+b. 或者是对相加结果进行强制类型转换
//如 int (a+b)
7.螺旋对垒
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), 2的坐标为(0,1), 3 的坐标为(1,1). 编成实现输入任意一点坐标
(x,y), 输出所对应的数字。
#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;
}
8. 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.
答案1 int max = ((a+b)+abs (a-b))/2;
答案2 int c= a-b;
char * strs[2]= {"a bigger", "b bigger"};
c= unsigned (c)>> (sizeof (int)*8-1);
8. 如何将a,b的值交换,并且不使用任何中间变量?
如果采用
a=a+b;
b=a-b;
a=a-b;
这样的缺点是如果a,b都是比较大的数,a=a+b时就会越界
而采用按位异或:
a=a^b;
b=a^b;
a=a^b;
无需担心越界问题,这样比较好。
9. 在C++程序中调用被C编译器编译过的函数, 为什么要加extern "C"?
C++支持函数重载, C语言不支持。 函数被C++编译后在库中的名字与C语言不同。
假设某个函数的原型为:void foo(int x, int y). 该函数被C编译器编译后在库中的名字
为_foo, 而C++ 编译器则会产生象_foo_int之类的名字。
C++提供了C连接交换指定符号extern "C"解决名字匹配问题
10 头文件中的 ifndef/define/endif 是干什么用的?
防止该头文件被重复引用
11 #include <filename.h> 和#include "filename.h"有什么区别?
#include <filename.h> 编译器从标准库路径开始搜索
#include "filename.h" 编译器从用户的工作路径开始搜索
12. 如何判断一段程序是由C编译程序还是由C++编译程序编译的?
C++编译时定义了_cplusplus
C编译时定义了_STDC_
13. main 函数执行完毕后, 是否可能再执行一段代码?
答:如果需要加入一段在main 退出之后执行的代码, 可以使用atexit()注册一个函数
#include <stdlib.h>
int atexit (void (*function)(void));
#include <stdio.h>
void fn1 (void), fn2 (void), fn3 (void), fn4 (void);
int main(void)
{
atexit (fn1);
atexit (fn2);
atexit (fn3);
atexit (fn4);
printf("This is executed first/n");
return 0;
}
void fn1()
{
printf("next /n");
}
void fn2()
{
printf("executed /n");
}
void fn3()
{
printf("is /n");
}
void fn4()
{
printf("this /n");
}