程序员面试宝典第五章 程序设计基本概念

赋值语句


#include<iostream>
using namespace std;
int i=1;
int main()
{
	int i=i;  //后面的i为main()函数定义的i,未定义值
	cout<<i;  
}
输出:  i  =   2025146132 


2.

#include<iostream>
using namespace std;
int main()
{
	int x=2,y ,z;
	x *=(y=z=5); cout<<x<<endl;    //x *=y;
	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  7 1

3.

#include<iostream>
using namespace std;
int func(int x)  //返回x转化为二进制后1的数量
{
	int count=0;
	while(x)
	{
		count ++;
		x = x &(x-1);
		cout<<x<<endl;
	}
	return count;
}
int main()
{	
	cout<<func(9999);  //10 0111 0000 1111
}
输出 :  8


 i++

1.

#include<iostream>
using namespace std;
int main()
{
         float a = 1.0f;
         cout << (int)a << endl;
         cout << &a << endl;
         cout << (int&)a <<endl;
         cout << boolalpha << ((int)a == (int&)a ) << endl; //false
 
         float b = 0.0f;
         cout << (int)b << endl;
         cout << &b << endl;
         cout << (int&)b <<endl;
         cout << boolalpha << ((int)b == (int&)b ) << endl; //true
         return 0;
}

2.

#include<iostream>
using namespace std;
int main()
{
    unsigned int a = 0xfffffff7;
    unsigned char i = (unsigned char)a;
    char *b = (char *)&a;
    printf("%08x,%08x\n",i,*b);//000000f7,fffffff7
}

在32位机器上,不管指针指向的是什么类型的对象,指针统一大小为4字节(sizeof(int*)==sizeof(char*)==sizeof(string*)==4)。

unsigned char i = (unsigned char)a;//此行代码的意思是,把unsigned int类型的a转换为unsigned char类型,发生截断。

char *= (char *)&a;//此行代码的意思是:把&a即unsigned int *类型的指针转换为char *类型的指针,指的是指针类型的转换,大小是一样的,不发生截断,所以b指向的还是a.   *b值为a的值


运算符问题

1.

#include <iostream>
#include<vector>
using namespace std;

int main(int argc, char* argv[])
{	
   unsigned char	a = 0xA5;     // ~优先级高于>>和+,而 +高于>> ,所以为  (~a)>>(4+1) 
   unsigned char	b =~a>>4+1;   // 类型转换,char 提升为4个字节的int ,  为0000 0000 1010 0101 
   printf("b=%d",b);                 // 取反为1111 1111 0101 1010
				      // 右移5位为0000 0111 1111 1010
				      // 类型转换为char,截取8位,  1111 1010        250
    return 0;
}

输出    :  250


2.

判断一个数X是否是次方(2,4,8,16,…),不可用循环语句

解析:2,4,8,16,… 这样的数转化成二进制是10、100、1000、10000。如果X减1后与X做与运算,答案若是0,则X是次方

答案:!(X & (X-1) )


3.

int  f(int x,int y)

{

return ( (x&y)+(x^y))>>1;
}

f(729,271)= __;

解析:x&y是取相同的位,x^y是取不同的位,右移1位为除2,取两个数的平均值

(729+271)/2=500;


4.

利用位运算实现两个整数的加法运算。 

int Add(int a,int b)
{
         if(b==0)    //直到进位为0
              return a;
         int sum ,carry;
         sum= a^b;    //实现不进位的加法
         carry= (a&b)<<1;   //进位的数据
         return Add(sum,carry);  //两个相加
}


a、b交换与比较

1. 

有两个变量,不用?、if、switch或其他判断语句,找出两个数中间较大的

1int max=((a+b)+abs(a-b))/2; //a>b,(a+b+a-b)/2=a;

                                                  //a<b,(a+b+b-a)/2=b;

2int a=700,b=600;

     int c=a-b;

         c= unsigned(c)>>(sizeof(int)*8-1);//只取符号位,为1则负,为0则正

2. 

给三个整数a、b、c,函数实现取三个数的中间值,不可以用sort,整数操作尽可能少?

解析: int max(int a,intb){returna>b?a:b;}

int min(int a,int b){return a<b?a:b;}

inlint intmedium(int a,int b,int c)

{

int t1 =max(a,b);

intt2 = max(b,c);

int t3=max(a,c);

return min(t1,min(t2,t3));

}


3.

如果将a、b的值进行交换,并且不使用任何中间变量
解法:(1) a=a+b;          //容易溢出

b=a-b;

a=a+b;

(2) a=a^b;          //a=9 ,b=5  a=0000 1001 ^ 0000 0101 = 0000 1100

b=a^b;      // b= 0000 1100 ^ 0000 0101 = 0000 1001   ,  b=9;

a=a^b;    //  a= 0000 1100 ^ 0000 1001 = 0000 0101     ,  a=5;

 

C和C++的关系

1.

如果C++调用一个C语言编写的.DLL时,当包括.DLL的头文件或声明接口函数时,应加extern"C" { }。extern "C"实现C++与C及其它语言的混合编程

void foo( int x,int y ); 该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字, _foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的.

 未加extern "C"声明时的连接方式

#ifndef MODULE_A_H// 模块A头文件 moduleA.h

#define MODULE_A_H

intfoo( int x, int y );

#endif  

#include"moduleA.h"// 模块B实现文件 moduleB.cpp在模块B中引用该函数:

foo(2,3);

在连接阶段,连接器会从模块A生成的目标文件moduleA.obj中寻找_foo_int_int这样的符号!

  加extern"C"声明后的编译和连接方式

#ifndef MODULE_A_H // 模块A头文件 moduleA.h

#define MODULE_A_H

extern"C" int foo( int x, int y );

#endif

  在模块B的实现文件中仍然调用foo( 2,3 ),其结果是:

  (1)模块A编译生成foo的目标代码时,没有对其名字进行特殊处理,采用了C语言的方式;

  (2)连接器在为模块B的目标代码寻找foo(2,3)调用时,寻找的是未经修改的符号名_foo。

  

程序设计的其他问题

2.

题目:选秀节目打分,分为专家评委和大众评委,score[] 数组里面存储每个评委打的分数,judge_type[] 里存储与 score[] 数组对应的评委类别,judge_type == 1,表示专家评委,judge_type == 2,表示大众评委,n表示评委总数。打分规则如下:专家评委和大众评委的分数先分别取一个平均分(平均分取整),然后,总分 = 专家评委平均分  * 0.6 + 大众评委 * 0.4,总分取整。如果没有大众评委,则 总分 = 专家评委平均分,总分取整。函数最终返回选手得分。
函数接口   int cal_score(int score[], int judge_type[], int n) 

int cal_score(int score[],int judge_type[],int N)
{
	int sum=0,n=0,m=0;
	double sum1=0,sum2=0;      //double
        if(score && judge_type && N)
	{
		for(int i=0;i<N;i++)
		{
			switch(judge_type[i])
			{
				case 1: sum1	+=score[i];
							++n;
							break;
				case 2: sum2<span style="white-space:pre">	</span>+=score[i];
							++m;
							break;
			}
		}

		if(n)
		<span style="white-space:pre">	</span>sum1= sum1/n;
		if(m)
			sum2 = sum2/m;

		sum=m? sum1*0.6+sum2*0.4:sum1;
	}
	return sum;
}


 


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值