答案:虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组.而对象的隐藏成员--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是实现多态的关键.
答案:可以,可以用_onexit注册一个函数,它会在main之后执行;
如果你需要加入一段在main退出后执行的代码,可以使用atexit()函数,注册一个函数。
语法:
#include<stdlib.h>
intatexit(void(*function")(void));
#include<stdlib.h>
#include<stdio.h>
voidfn1(void),fn2(void),fn3(void),fn4(void);
intmain(void)
{
atexit(fn1);
atexit(fn2);
atexit(fn3);
atexit(fn4);
printf("Thisisexecutedfirst.\n");
}
voidfn1()
{
printf("next.\n");
}
voidfn2()
{
printf("executed");
}
voidfn3()
{
printf("is");
}
voidfn4()
{
printf("This");
}
结果:
Thisisexecutedfirst.
Thisisexecutednext.
答案:只要基类在定义成员函数时已经声明了virtue关键字,在派生类实现的时候覆盖该函数时,virtue关键字可加可不加,不影响多态的实现。子类的空间里有父类的所有变量(static除外)。
如果有多个答案就返回第一个了
像:ababcdcd,输出是就是ab了
复杂度分析:
i=1
for(itoN)
{
for(0toN-i)
{
k=i
for(0toi)/*字符串copy*/
}
}
O(N^3)
#include<iostream>
#include<string>
#include<map>
#include<algorithm>
usingnamespacestd;
intmain()
{
stringstr,tmp,buf;
inti,j,k,index,len,max;
map<string,int>my_map;
cout<<"Enterastring:"<<endl;
cin>>str;
len=str.size();
for(k=1;k<=len;k++)/*长度为K的字符串*/
{
cout<<"串长为"<<k<<":"<<endl;
for(i=0;i<len-k+1;i++)/*串长为K的字符串的开头*/
{
index=k;
tmp="";
j=i;
while(index--)/*串长为j的*/
{
tmp+=str[j++];
}
my_map[tmp]++;/*收集*/
cout<<tmp<<"";
}
cout<<endl;
}
len=str.size();
max=-1;
buf="";
for(k=1;k<=len;k++)/*长度为K的字符串*/
{
for(i=0;i<len-k+1;i++)/*串长为K的字符串的开头*/
{
index=k;
tmp="";
j=i;
while(index--)/*串长为j的*/
{
tmp+=str[j++];
}
if((max==-1&&my_map[tmp]>1)/*mY_map[tmp]>1:连续重复*/
||(my_map[tmp]>1&&max<tmp.size()))/*max<~.size()且最长*/
{
buf=tmp;
max=tmp.size();
}
}
}
cout<<endl<<"应该返回的串是:\n"<<buf<<endl;
system("pause");
}
1#include<iostream>
2usingnamespacestd;
3
4voidGetPrimeNum(intk)
5{
6inta=1,b=2,c=2;
7boolbcheck=true;
8while(c<k)
9{
10for(inti=2;i<c;i++)
11{
12if(c%i==0&&c!=2)
13bcheck=false;
14}
15if(bcheck)
16{
17cout<<c<<"";
18}
19c=a+b;
20a=b;
21b=c;
22bcheck=true;
23}
24cout<<endl;
25}
26intmain(intargc,char*argv[])
27{
28intk;
29cout<<"请输入一个数,获取比此数小的所有Fab..质数:"<<endl;
30cin>>k;
31cout<<"比"<<k<<"小的所有Fab..质数为:"<<endl;
32GetPrimeNum(k);
33return0;
34}
复制代码
方法1:
把硬币分成50,50,1。
称50与50,如果平衡,则这两堆为真币,剩下的1为假币。再用这个假币和真币称一下得结论。
若不平衡,则1为真币,接着判断假币在哪个堆里面。
取轻的1堆,分成25,25,称重。若平衡则假币在另一堆里面,假币重。
若不平衡,则假币在这一堆中,假币轻。
方法2:
把硬币分成33,33,34。
称33与33,如果平衡,则这两堆为真币,假币在第三堆中。从66中取出34与第三堆进行称,第三堆所在的天平的那一端的轻重就是假币的轻重情况。
若不平衡,则假币在这两堆中。取下轻的一堆,从34里面取出33替换,称量。如果平衡,代表取下的那一堆中有假币,假币是轻的。如果不平衡,代表取下的那一堆是真币,假币是重的。
答案:这些函数的区别在于实现功能以及操作对象不同。
1.strcpy函数操作的对象是字符串,完成从源字符串到目的字符串的拷贝功能。
2.snprintf函数操作的对象不限于字符串:虽然目的对象是字符串,但是源对象可以是字符串、也可以是任意基本类型的数据。这个函数主要用来实现(字符串或基本数据类型)向字符串的转换功能。如果源对象是字符串,并且指定%s格式符,也可实现字符串拷贝功能。
3.memcpy函数顾名思义就是内存拷贝,实现将一个内存块的内容复制到另一个内存块这一功能。内存块由其首地址以及长度确定。程序中出现的实体对象,不论是什么类型,其最终表现就是在内存中占据一席之地(一个内存区间或块)。因此,memcpy的操作对象不局限于某一类数据类型,或者说可适用于任意数据类型,只要能给出对象的起始地址和内存长度信息、并且对象具有可操作性即可。鉴于memcpy函数等长拷贝的特点以及数据类型代表的物理意义,memcpy函数通常限于同种类型数据或对象之间的拷贝,其中当然也包括字符串拷贝以及基本数据类型的拷贝。
对于字符串拷贝来说,用上述三个函数都可以实现,但是其实现的效率和使用的方便程度不同:
·strcpy无疑是最合适的选择:效率高且调用方便。
·sprintf要额外指定格式符并且进行格式转化,麻烦且效率不高。
·memcpy虽然高效,但是需要额外提供拷贝的内存长度这一参数,易错且使用不便;并且如果长度指定过大的话(最优长度是源字符串长度+1),还会带来性能的下降。其实strcpy函数一般是在内部调用memcpy函数或者用汇编直接实现的,以达到高效的目的。因此,使用memcpy和strcpy拷贝字符串在性能上应该没有什么大的差别。
对于非字符串类型的数据的复制来说,strcpy和snprintf一般就无能为力了,可是对memcpy却没有什么影响。但是,对于基本数据类型来说,尽管可以用memcpy进行拷贝,由于有赋值运算符可以方便且高效地进行同种或兼容类型的数据之间的拷贝,所以这种情况下memcpy几乎不被使用。memcpy的长处是用来实现(通常是内部实现居多)对结构或者数组的拷贝,其目的是或者高效,或者使用方便,甚或两者兼有。
9.变量的声明和定义有什么区别?
10.请写出下面代码在32位平台上的运行结果,并说明sizeof的性质:
#include<stdio.h>
#include<stdlib.h>
intmain(void)
{
chara[30];
char*b=(char*)malloc(20*sizeof(char));printf("%d\n",sizeof(a));