1、要对绝对地址0x100000赋值,我们可以用(unsigned int*)0x100000 = 1234;那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?
答案:*((void (*)( ))0x100000 ) ( );
首先要将0x100000强制转换成函数指针,即:(void (*)())0x100000
然后再调用它:*((void (*)())0x100000)();
用typedef可以看得更直观些: typedef void(*)() voidFuncPtr; *((voidFuncPtr)0x100000)();
2、下面的输出结果
unsigned short A = 10;
printf("~A = %u\n", ~A); // 0xfffa = 4294967285 (无符号) -11(有符号)
char c=128;
printf("c=%d\n",c); // 0x80 = -128
3、指针加法
struct BBB { long num; char *name; short int data; char ha; short ba[5]; }*p; int main(int argc, char* argv[]) { p=(struct BBB*)0x1000000; //sizeof(struct BBB)=24 cout<<hex<<p+0x200<<endl; //p+0x200*24 = 0x01003000 p指向的是结构体类型 cout<<hex<<(unsigned long)p+0x200<<endl; //p+0x200 = 1000200 p被强制转换为长整型 cout<<hex<<(unsigned long*)p+0x200<<endl;; //p+0x200*4 = 0x01000800 p指向的是指针类型 return 0; }
4、什么是预编译,何时需要预编译?
答:预编译就是指程序执行之前的一些预处理工作,预编译头文件的作用是提高编译速度,有了它你没有必要每次都编译那些不需要经常改变的代码,编译性能当然就提高了。
何时需要预编译:
1)、总是使用不经常改动的大型代码体。
2)、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。
5、编写一个病毒
while (1) { int *p = new int[10000000]; }
6、int x=35; char str[10]; 问:strlen(str)和 sizeof(str)的值分别是多少?
答:strlen(str) 值不确定,strlen 根据'\0'确定字符串是否结束。sizeof(str)=10
如进行下列操作:strcpy(str,"www.it315.org"/*共 13个字母*/),问:此时 x 和 strlen(str)的值分别是多少?
进行strcpy操作,出现内存越界访问,x 值变为未知数,strlen(str)=13。
7、关键字volatile有什么含意?
答案:Volatile关键字表明,即使程序代码没有对内存单元进行修改,其值也可能发生变化。下面是volatile变量的几个例子:
1)并行设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量
3) 多线程应用中被几个任务共享的变量
8、列举几种进程的同步机制。
答案:原子操作 信号量机制 自旋锁 管程,会合,分布式系统
9、进程之间通信的途径。
答案:共享内存,消息,管道。
10、进程死锁的原因。
答案:资源竞争及进程推进顺序非法。
11、死锁的4个必要条件。
答案:互斥、请求保持、不可剥夺、环路。
12、死锁的处理方法有哪些?
答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁。
13、操作系统中进程调度策略有哪几种?
答案:FCFS(先来先服务),优先级,时间片轮转,多级反馈 。
14、数组和链表的区别。
答案:数组:数据顺序存储,固定大小,查找复杂度为O(1);链表:数据随机存储,大小可动态改变,插入删除复杂度为O(1) 。
15、C++类 A 和 类B,在哪几种情况下B能隐式转化为A?
a. class B : public A { ……} // B公有继承自A,可以是间接继承的
b. class B { operator A( ); } // B实现了隐式转化为A的转化
c. class A { A( const B& ); } // A实现了non-explicit的参数为B构造函数
d. class A { A& operator= ( const B& ); } // 赋值操作
16、下面代码输出什么
struct CLS { int m_i; CLS(int i) : m_i(i) {} //含参构造函数 CLS() { CLS(0); //默认构造函数,调用含参构造函数创建了一个CLS的对象CLS(0),这个对象与obj不一样 } }; CLS obj; //调用默认构造函数创建了CLS的一个对象obj cout << obj.m_i << endl; //所有输出为未知数
17、编写一个函数,完成内存之间的拷贝,注意有重叠内存区域时的拷贝。
//将起始地址为src处的count大小的内存拷贝到起始地址为dest处 void* mymemcpy( void *dest, const void *src, size_t count ) //void指针 { char* pdest = static_cast<char*>( dest ); //类型强制转换 const char* psrc = static_cast<const char*>( src ); //类型强制转换 if( pdest>psrc && pdest<psrc+count ) //判断拷贝的内存是否有重叠区 { for( size_t i=count-1; i!=-1; --i) pdest[i] = psrc[i]; //反向拷贝,防止元素重叠 } else { for( size_t i=0; i<count; ++i ) //不存在重叠区域时,直接拷贝 pdest[i] = psrc[i]; } return dest; }