<span style="font-family: Arial, Helvetica, sans-serif;">一.//以下代码输出什么____. </span>
<span style="font-family: Arial, Helvetica, sans-serif;">main()</span>
{
int a[5]={1,2,3,4,5};
int *p=(int *)(&a+1);
printf("%d",*(p-1));
}
二.
struct A{
void foo(){printf("foo");}
virtual void bar(){printf("bar");}
A(){bar();}
};
struct B:A{
void foo(){printf("b_foo");}
void bar(){printf("b_bar");}
};
那么
A *p=new B;
p->foo();
p->bar();
输出为:
barfoob_bar
1.只有用virtual修饰的函数才能动态绑定
2.如果在构造函数或析构函数中调用虚函数,则运行的是为构造函数或析构函数本人类型定义的版本(c++prime 中文版第四版 p497)
因为在构造子类的时候,首先回去调用父类的默认构造函数,此时子类还是未初始化的,所以不可能调用子类函数
一个类的成员被定义为virtual,就意味着它在告诉自己的子类:我准备了一笔遗产,你可以全盘接受,也可以完全拒绝或者修改我的遗嘱。显然,虚方法授予子类的权利甚至大于抽象方法。子类面对抽象方法只有重写(override)的权利,而对于虚方法,它还可以选择完全继承。
三.
线程和进程的区别联系:
1,进程:子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。
2,线程:相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
两者都可以提高程序的并发度,提高程序运行效率和响应时间。
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。
根本区别就一点:用多进程每个进程有自己的地址空间(address space),线程则共享地址空间。所有其它区别都是由此而来的:
1、速度:线程产生的速度快,线程间的通讯快、切换快等,因为他们在同一个地址空间内。
2、资源利用率:线程的资源利用率比较好也是因为他们在同一个地址空间内。
3、同步问题:线程使用公共变量/内存时需要使用同步机制还是因22 34 55 77 89 93 99 102 120 140
0 1 2 3 4 5 6 7 8 9
假设低下标用low表示,高下标用high表示。
查找77:
开始low = 0, high = 9
第一次查找,找到中心的下标为(0+9)/2 = 4,即89,由于89大于77,所以,调整low = 0,high = 3(注意:由于知道下标为4的元素比77大,所以不会让high等于4)
第二次查找,找到中心的下标为(0+3)/2 = 1,即34,由于34小于77,所以,调整low = 2,high = 3
第三次查找,找到中心的下标为(2+3)/2 = 2,即55,由于55小于77,所以,调整low = 3,high = 3
第四次查找,找到中心的下标为(3+3)/2 = 3,即77,找到所要找的元素为他们在同一个地址空间内,线程最大的问题,公有变量的互斥访问
四、二分查找
22 34 55 77 89 93 99 102 120 140
0 1 2 3 4 5 6 7 8 9
假设低下标用low表示,高下标用high表示。
查找77:
开始low = 0, high = 9
第一次查找,找到中心的下标为(0+9)/2 = 4,即89,由于89大于77,所以,调整low = 0,high = 3(注意:由于知道下标为4的元素比77大,所以不会让high等于4,会有+1-1操作!)
第二次查找,找到中心的下标为(0+3)/2 = 1,即34,由于34小于77,所以,调整low = 2,high = 3
第三次查找,找到中心的下标为(2+3)/2 = 2,即55,由于55小于77,所以,调整low = 3,high = 3
第四次查找,找到中心的下标为(3+3)/2 = 3,即77,找到所要找的元素