AWDZ笔试复盘

文章目录

    • 填空
    • 编程题1:实现一个函数,参数为一个整型类型,返回值为该参数二进制表示中0的个数
    • 编程题2:实现一个函数,参数为乱序整数数组,将数组奇数放到数组前部,从小到大排列;将数组偶数位于后部,从大到小排列
    • 智力题

10道题/1hour,涉及填空、编程、逻辑

填空

  1. 计算程序的输出结果:

int a[10] = [1,2,3,4,5,6,7,8,9,0];
int* p = &a[1];
请问p[5] =(7)
【分析】int* p = &a[1];这句是将数组a中的第一个元素所在地址赋给了指针p,因此p就指向了a[1],p[5] = a[1+5] = a[6] = 7。
对于数组a[10],就是在内存中开辟了10个连续的、存放int类型整数的存储单元,并分别给其取代号a[0],a[1],a[2]…,a[9],这些代号所代表的存储单元中,分别有值1,2,3,等。所以p[5]也只是一个地址的代号而已,在数组中的元素存储单元是连续的,因此可以通过代号找到该位置处的值。

  1. 自定义用于获取X,Y中较大值的宏MIN(X,Y):#define MIN(X,Y) ((X)<=(Y)? (X):(Y))
    【宏定义】宏定义即用一个标识符来表示一个字符串。宏定义语法:#define 标识符 字符串
    考试时忘了加括号,好像还忘了写等于号!!!
// 不带参数的宏定义
#define MAX 10

/*带参宏定义*/
#define M(y) y*y+3*y

/*宏调用*/
k=M(5);

【宏定义优点】方便程序的修改、提高程序的运行效率
【宏定义缺点】不易调试、无法检查参数是否合法
【预处理】预处理命令可以改变程序的设计环境,提高编程效率,但它们并不是C语言本身的组成部分,不能直接对其进行编译,必须在程序编译之前先对程序进行预处理。预处理之后对源程序进行编译可得到供执行的目标代码。C语言中预处理功能有三种:宏定义、文件包含和条件编译。

  1. 程序的局部变量存在于(栈),全局变量存在于(全局区(静态区)),动态申请数据存在于(堆)。
    【程序的各种区以及存储的内容】
  • 栈区: 由编译器自动分配和释放的内存区域,用于存放函数的参数值,局部变量的值等。随着函数的调用和返回,栈区的数据将动态变化。
  • 堆区: 程序员向系统申请或释放(new、malloc等动态申请)。若程序员在程序结束时还没有释放,则可能由操作系统回收。
  • 全局区(静态区): 用来保存全局变量和静态变量。在进入程序时分配区域,程序结束后由系统释放。
  • 文字常量区:用于保存常量字符串的内存区域,程序结束后,由系统释放。
  • 程序代码区:用于保存函数体的二进制代码。
  1. linux下的32位C程序,计算sizeof的值:

char str[] = “Hello”;
char *p = str;
int n=10;
void func(char instr[100])
{
…;
}
struct test
{
char str;
byte flag;
int num;
short x;
};

其中,
sizeof(str) = 6 //字符串中包含了末尾的’\0’
sizeof§ = 4 //p是指针,地址的长度是和32位还是64位有关系,32位系统为4,64位系统值为8
sizeof(n) = 4 //int占用4个字节
sizeof(instr) = error //返回函数返回值类型大小 ,sizeof不能对返回值为空类型的函数求值
sizeof(test) = 16 //结构的的sizeof涉及到字节对齐问题,值为最大的占空大小乘以参数个数(byte占1个字节)
【C++中sizeof()的用法介绍】注意对于联合体union也涉及到字节对齐,但sizeof大小为最大的类型值,而不乘以参数个数

  1. 用变量a给出下面的定义:

1)一个有10个指针的数组,该指针是指向一个整型数的(int* a[10];)//a是一个数组,该数组的元素是指针,每个指针都指向一个int型
2)一个指向函数的指针,该函数有一个字符型参数并返回一个整型数(int (*a)(char)

【定义函数指针的方法】函数指针即指向函数的指针,定义语法:返回值类型 (*指针变量名) ([形参列表])
在C语言中,函数本身不是变量,但是可以定义指向函数的指针,也称作函数指针,函数指针指向函数的入口地址。这种类型的指针可以被赋值、放在数组中、传递给函数以及作为函数的返回值等。
函数指针的应用:

//函数指针的应用:
int func(int x);//定义一个函数
int (*a) (int x);//定义一个函数指针

f = func;//将func函数的首地址赋给指针f(func之前也可加&符号)

例如:

int add(int x,int y){
     
    return x+y;
}
int sub(int x,int y){
     
    return x-y;
}
//函数指针
int (*fun)(int x,int y);

int main(int argc, char *argv[])
{
     
    QApplication a(argc, argv);
    //第一种写法
    fun = add;
    qDebug() << "(*fun)(1,2) = " << (*fun)(1,2) ;
	//第二种写法
    fun = &sub;
    qDebug() << "(*fun)(5,3) = " << (*fun)(5,3)  << fun(5,3)return a.exec();
}


输出
(*fun)(1,2) = 3
(*fun)(5,2) = 2 2

【指针函数】本质是一个函数,与普通函数差不多,只不过返回的是一个指针:int* func(int x, int y)

编程题1:实现一个函数,参数为一个整型类型,返回值为该参数二进制表示中0的个数

  • 分析:

求二进制中0的个数有两种普遍方法:一个是将原数位取反~,然后再计算二进制中1的个数即可;另一个是直接计算

  • 代码:找出一个数的二进制为1的个数
int CountNumOf1(int num)
{
     
	int count=0;
	while(num)
	{
     
		num &= (num-1);
		count++;
	}
	return count;
}
  • 代码求二进制中0的个数:
//方法1
int CountNumOf0(int num)
{
     
	num = ~num;
	int count=0;
	while(num)
	{
     
		num &= (num-1);
		count++;
	}
	return count;
}

//方法2
//求二进制中0的个数:方法2
int CountNumOf0(int num)
{
     
	int count=0;
	while(num+1)
	{
     
		num |= (num+1);//每走一步都将num二进制中最后一个0变为1,直至最终num=-1为止,这个时候再与0一与就成0了,while循环终止
		count++;
	}
	return count;
}

编程题2:实现一个函数,参数为乱序整数数组,将数组奇数放到数组前部,从小到大排列;将数组偶数位于后部,从大到小排列

  • 分析:

方法类似于快排:
while循环内部是碰见奇数,头指针向右移动,碰见偶数尾指针向左移动
当头指针指向偶数,尾指针指向奇数时,进行交换

  • 代码:
#include
#include
#include
using namespace std;

vector<int> ReorderArr(vector<int> arr)
{
     
	
	int len = arr.size();
	vector<int> result(len);
	if(arr.empty())
		return result;

	int a=0,b=len-1;
	while(a<b)
	{
     
		while(arr[a]&1 == 1 && a<b)
			a++;
		while(arr[b]&1 != 1 && a<b)
			b--;
		if(a<b)
		{
     
			swap(arr[a],arr[b]);
			a++;
			b--;
		}
	}
	sort(arr.begin(),arr.begin()+a);//奇数从小到大排序
	sort(arr.begin()+a, arr.end());//偶数先从小到大排序
	int x = len;
	for(int i=0;i<len;i++)
	{
     
		if(i<a)
		{
     
			result[i] = arr[i];//奇数返回时从左向右入到结果数组
		}
		else
		{
     
			result[i] = arr[--x];//偶数返回的时候从右向左入到结果数组
		}
	}
	return result;
}


int main()
{
     
	//测试输入数组:1 2 3 4 5,预计输出: 1  3  5  2  4
	vector<int> arr(5);
	for(int i=0;i<5;i++)
		arr[i] = i+1;
	vector<int> r = ReorderArr(arr);
	for(int i=0;i<5;i++)
		cout<<r[i]<<" ";
	return 0;
}

输出:在这里插入图片描述

智力题

  1. 文具店,红绿蓝3种颜色铅笔各100根,每个文具盒需要配相同颜色4根铅笔,如果在眼睛蒙着的情况下,最少要拿几根铅笔,才能保证配好3套文具?
    答:蒙着眼睛的情况下,最差的情况就是前200次只取出了2种颜色的全部铅笔,之后再取出1根必定是第三种颜色,所以至少要取200+4 = 204根笔,才能保证配好3套文具。
  1. 建筑物高100层,若从第N层或更高的楼层扔玻璃球,玻璃球就会破掉;若从第N层以下的楼层扔下来则不会破掉。给你2个玻璃球,找出N。需满足最差情况下尝试次数最少。
    答:
    from:博客园

你可能感兴趣的:(笔试题,C++)