星辉游戏笔试复盘
若1个CPU的寻址能力为8KB,那么它的地址总线的宽度为13根,2^13=8192,一根线控制1/0
#include <bits/stdc++.h>
using namespace std;
int main(){//总结:全部看成是二维指针即可,如果后面带有的[x]低维表示这个指针+1是后移x个字符
char str[][9] = { "GuanZhou", "XingHui", "YouXi", "XiaoYuan", "ZhaoPin" };
char *p = (char*)str; printf("%s\n",p); //GuanZhou,p指向第一个字符,即使str是二维p也不是指第一维
p += 5; printf("%s\n",p); //hou,p后移5个位
char **q = (char**)p; printf("%c %s\n",*q,q); //h hou,q是二维指针
q += 1; printf("%c %s\n",*q,q); //X XingHui,q进四个字符
q -= 1; printf("%c %s\n",*q,q); //h hou,q退四个字符
q -= 1; printf("%c %s\n",*q,q); //u uanZhou,q退四个字符
q += 1; printf("%c %s\n",*q,q); //h hou,q进四个字符
q += 1; printf("%c %s\n",*q,q); //X XingHui,q进四个字符
char(*o)[6]=(char(*)[6])p; printf("%s\n",o); //hou,o是一维指针(但二维固定长为6),或者理解为是二维指针,但是一步走六个字节
o += 1; printf("%s\n",o); //ngHui,o进六个字符
getchar();
return 0;
}
按照从大到小的顺序,打印出小于等于1792,且二进制位中1的个数为3的正整数,要求复杂度小于 O(N)
整体思路:先找到1792下最大的符合条件的数,读出三个1的位置下标指针,不断后移计数
#include <bits/stdc++.h>
using namespace std;
bool check(int x){
int cnt=0;
while(x>0){
cnt++;
if(cnt>3)return false;
x=x&(x-1);
}
if(cnt==3)return true;
else return false;
}
int main(){
int x=1792;//0111 0000 0000
while(!check(x))x=x&(x-1);
int tmp=x,pos[4]={-1,-1,-1,-1},id=1;
for(int offset=0;tmp>0;offset++){
if(tmp&(1<<offset)){
pos[id++]=offset;
tmp=tmp&(tmp-1);
}
}
cout<<pos[1]<<' '<<pos[2]<<' '<<pos[3]<<endl;//8 9 10
int ans=0;
for(int j=pos[2];j>-1;j--)//此处是有限制的情况下低两位的移动
for(int k=j-1;k>-1;k--)
ans++;
for(int i=pos[3]-1;i>-1;i--)//下面的计算可以用组合数来实现,C(10,3)
for(int j=i-1;j>-1;j--)
for(int k=j-1;k>-1;k--)
ans++;
cout<<ans<<endl;
return 0;
}
数组是有序的,寻找K个值最接近N的元素 Input: [1,2,3,4,5], k=4, N=3 Output: [1,2,3,4]
思路一:二分出最接近N值的位置指针并初始化左右指针,然后左右贪心(距离N较近者)地移动指针直至够K个max(ok,ologn)
思路二:直接开一个K长的区间,控制左右界尺取一遍on,或者先二分出中间值,以中间值为右界再尺取max(ok,ologn)
下面关于多态性的描述,错误的是C
A.C++语言的多态性分为编译时的多态性和运行时的多态性
B.编译时的多态性可通过函数重载实现
C.运行时的多态性可通过模板和虚函数实现(模板是静态)
D.实现运行时多态性的机制称为动态绑定
用a代表默认构造函数,用b代表拷贝构造函数,用c代表赋值运算符,用d代表析构函数
这个问题我已发贴,等更新
A f(A& a){return a; }
int main(int, char**){
A a;
A b = f(a);
return 0;
}
A.abdd
B.acdd
C.abbddd
D.abcddd
动态链接库与静态链接库
库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。 windows上对应的是.lib .dll linux上对应的是.a .so
静态库:
与汇编生成的目标文件一起链接为可执行文件,那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件(.o/.obj文件)的集合,即很多目标文件经过压缩打包后形成的一个文件。静态库对函数库的链接是放在编译时期完成的。
gcc -c 编译器编译源代码但不执行链接,输出结果为对象文件。文件默认名与源码文件名相同,只是将其后缀变为 .o
ar -crv libstaticmath.a StaticMath.o 然后通过ar工具将目标文件.o打包成.a静态库文件,生成静态库libstaticmath.a。
缺点:
不同的程序调用同一个库函数都要加载到内存,不能复用。
这个库是用来与对程序的更新、部署和发布页会带来麻烦。如果静态库liba.a更新了,所以使用它的应用程序都需要重新编译、发布给用户(对于玩家来说,可能是一个很小的改动,却导致整个程序重新下载,全量更新)。
浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
优点:
程序在运行时与函数库再无瓜葛,移植方便。
动态库:
在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,把对一些库函数的链接载入推迟到程序运行的时期。
优点:
不同的应用程序如果调用相同的库,在内存里只需要有一份该共享库实例,规避空间浪费问题。(因此动态库也称为共享库)
动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可,增量更新。程序升级变得简单,可以真正做到链接载入完全由程序员在程序代码中控制(显示调用)
输入:g++ -fPIC -shared -o libadd.so add.cpp 这样就生成了一个libadd.so的动态库。
输入:g++ -o test test.cpp -L . -ladd 动态链接的方式编译test.cpp。
注意-l后面接的是lib与so中间的库名称。
STL容器的线程安全
线程安全的情况
多线程可以同时读取一个容器的内容。
在读取时不能有任何写入者操作这个容器。
对不同容器的多个写入者是安全的。
多线程可以同时写不同的容器。
线程不安全,即要锁定的情况
在对同一个容器进行多线程的读写、写操作时。
在每次调用容器的成员函数期间都要锁定该容器。
在每个容器返回的迭代器(例如通过调用begin或end)的生存期之内都要锁定该容器。
在每个在容器上调用的算法执行期间锁定该容器。
下面四个cast函数的作用:
static_cast可将基类转换为子类,基本数据类型之间的转换(包括空void),但不可以将子类转换为基类,否则编译报错
dynamic_cast只能将指向基类的指针或引用转换为指向子类的指针或引用,转换失败时返回NULL或抛出异常
const_cast剥离一个对象的const属性,也就是说允许你对常量进行修改。
reinterpret_cast用在任意指针或引用类型之间的转换,但不能通过转换去除const修饰符