1、10、10、4、4四个数,怎么算出24点?
(10*10-4)/4=24
2、下列表达式在32位机器编译环境下的值()
A、1、4、84、82
B、4、4、82、84 C、4、4、84、82 D、1、4、82、82
3、以下程序在32位机器下运行的结果是()
A、12 12 B、12 4
C、16 4
D、16 12 E、16 1
4、以下表达式result的值是()
A、-2
B、1
C、0 D、2
5、请写出以下程序的输出(5分)
输出结果:
a = 100 , b = 200
a = 200 , b = 100
a = 100 , b = 200
6、下面的程序是否有问题,如有问题,请重构代码(5分)
修改如下:
7、请指出以下程序有什么问题(5分)
应该修改为 delete[]p; p指向的是一个字符型的数组空间,原来的代码只是简单的释放了指向申请空间的指针,并没有释放申请的空间,容易造成内存崩溃。
回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。
8、以下程序有什么问题,请指出。
GetMem函数中的p是一个在栈上的局部变量,当函数运行结束的时候,栈上的内容会自动释放的,此处返回的值有可能会成为一个野指针,会出现一个意想不到的结果。
9、请写出strcpy 和 memcpy 的区别(5分)
答:strcpy和memcpy都是标准C库函数,它们有下面的特点。
strcpy提供了字符串的复制。即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符。
strcpy函数的原型是:char* strcpy(char* dest, const char* src);
memcpy提供了一般内存的复制。即memcpy对于需要复制的内容没有限制,因此用途更广。
memcpy函数的原型是:void *memcpy( void *dest, const void *src, size_t count );
strcpy和memcpy主要有以下3方面的区别。
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy。
10、请写出以下程序的输出结果
输出结果:
I am Base()
I am Base()
I am Derived()
I am Base()
I am Derived()
Hello Base
World Base
Hello Derived
World Base
Hello Derived
World Derived
I am ~Derived()
I am ~Base()
I am ~Derived()
I am ~Base()
I am ~Base()
11、阅读以下程序并给出执行结果
输出结果:
0
5
0
5
12、如何减少频繁分配内存(malloc或者new)造成的内存碎片?(10分)
内存池(Memory Pool)是一种内存分配方式。 通常我们习惯直接使用new、malloc等API申请分配内存,这样做的缺点在于:由于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性能。内存池则是在真正使用内存之前,先申请分配一定数量的、大小相等(一般情况下)的内存块留作备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存。这样做的一个显著优点是尽量避免了内存碎片,使得内存分配效率得到提升。
(1)针对特殊情况,例如需要频繁分配释放固定大小的内存对象时,不需要复杂的分配算法和多线程保护。也不需要维护内存空闲表的额外开销,从而获得较高的性能。
(2)由于开辟一定数量的连续内存空间作为内存池块,因而一定程度上提高了程序局部性,提升了程序性能。
(3)比较容易控制页边界对齐和内存字节对齐,没有内存碎片的问题。
(4)当需要分配管理的内存在100M一下的时候,采用内存池会节省大量的时间,否则会耗费更多的时间。
(5)内存池可以防止更多的内存碎片的产生
(6)更方便于管理内存
13、请写出strchr的实现(10分)
函数功能:找出在字符串str中第一次出现字符ch的位置,找到就返回该字符位置的指针(也就是返回该字符在字符串中的地址的位置),找不到就返回空指针(就是NULL)
char *strchr(const char *s,char c);
(10*10-4)/4=24
2、下列表达式在32位机器编译环境下的值()
- class A
- {
- };
- class B
- {
- public:
- B();
- virtual ~B();
- };
- class C
- {
- private:
- #pragma pack(4)
- int i;
- short j;
- float k;
- char l[64];
- long m;
- char *p;
- #pragma pack()
- };
- class D
- {
- private:
- #pragma pack(1)
- int i;
- short j;
- float k;
- char l[64];
- long m;
- char *p;
- #pragma pack()
- };
- int main(void)
- {
- printf("%d\n",sizeof(A));
- printf("%d\n",sizeof(B));
- printf("%d\n",sizeof(C));
- printf("%d\n",sizeof(D));
- return 0;
- }
3、以下程序在32位机器下运行的结果是()
- #pragma pack(4)
- struct info_t
- {
- unsigned char version;
- unsigned char padding;
- unsigned char extension;
- unsigned char count;
- unsigned char marker;
- unsigned char payload;
- unsigned short sequence;
- unsigned int timestamp;
- unsigned int ssrc;
- };
- union info_u
- {
- unsigned char version;
- unsigned char padding;
- unsigned char extension;
- unsigned char count;
- unsigned char marker;
- unsigned char payload;
- unsigned short sequence;
- unsigned int timestamp;
- unsigned int ssrc;
- };
- #pragma pack()
- int main(void)
- {
- printf("%d\n",sizeof(info_t));
- printf("%d\n",sizeof(info_u));
- return 0;
- }
4、以下表达式result的值是()
- #define VAL1(a,b) a*b
- #define VAL2(a,b) a/b--
- #define VAL3(a,b) ++a%b
- int a = 1;
- int b = 2;
- int c = 3;
- int d = 3;
- int e = 5;
- int result = VAL2(a,b)/VAL1(e,b)+VAL3(c,d);
5、请写出以下程序的输出(5分)
- void swap_1(int a , int b)
- {
- int c;
- c = a;
- a = b;
- b = c;
- return ;
- }
- void swap_2(int &a , int &b)
- {
- int c;
- c = a;
- a = b;
- b = c;
- return ;
- }
- void swap_3(int *a , int *b)
- {
- int c;
- c = *a;
- *a = *b;
- *b = c;
- return ;
- }
- int main(void)
- {
- int a = 100;
- int b = 200;
- swap_1(a , b);
- printf("a = %d , b = %d\n",a , b);
- swap_2(a , b);
- printf("a = %d , b = %d\n",a , b);
- swap_3(&a , &b);
- printf("a = %d , b = %d\n",a , b);
- return 0;
- }
a = 100 , b = 200
a = 200 , b = 100
a = 100 , b = 200
6、下面的程序是否有问题,如有问题,请重构代码(5分)
- void test_type(bool b , const char *p , float f)
- {
- if(!b)
- {
- return ;
- }
- else if(!p)
- {
- return ;
- }
- else if(!f)
- {
- return ;
- }
- }
- void test_type(bool b , const char *p , float f)
- {
- if(!b)
- {
- return ;
- }
- else if(!p)
- {
- return ;
- }
- else if(f > -1e-10 && f < 1e-10)
- {
- return ;
- }
- }
- void test_mem()
- {
- char *p = new char[64];
- delete p;
- p = NULL;
- return ;
- }
回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。
8、以下程序有什么问题,请指出。
- char* GetMem()
- {
- char p[] = "hello";
- return p;
- }
- void test_get_mem()
- {
- char *p = GetMem();
- printf(p);
- return ;
- }
9、请写出strcpy 和 memcpy 的区别(5分)
答:strcpy和memcpy都是标准C库函数,它们有下面的特点。
strcpy提供了字符串的复制。即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符。
strcpy函数的原型是:char* strcpy(char* dest, const char* src);
memcpy提供了一般内存的复制。即memcpy对于需要复制的内容没有限制,因此用途更广。
memcpy函数的原型是:void *memcpy( void *dest, const void *src, size_t count );
strcpy和memcpy主要有以下3方面的区别。
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy。
10、请写出以下程序的输出结果
- class Base
- {
- public:
- Base()
- {
- printf("I am Base()\n");
- }
- virtual ~Base()
- {
- printf("I am ~Base()\n");
- }
- public:
- virtual void SayHello()
- {
- printf("Hello Base\n");
- }
- void SayWorld()
- {
- printf("World Base\n");
- }
- };
- class Derived : public Base
- {
- public:
- Derived()
- {
- printf("I am Derived()\n");
- }
- virtual ~Derived()
- {
- printf("I am ~Derived()\n");
- }
- public:
- void SayHello();
- void SayWorld();
- };
- void Derived::SayHello()
- {
- printf("Hello Derived\n");
- }
- void Derived::SayWorld()
- {
- printf("World Derived\n");
- }
- int main(void)
- {
- Base *b1 = new Base;
- Base *b2 = new Derived;
- Derived *d = new Derived;
- b1->SayHello();
- b1->SayWorld();
- b2->SayHello();
- b2->SayWorld();
- d->SayHello();
- d->SayWorld();
- delete d;
- delete b2;
- delete b1;
- d= NULL;
- b2 = NULL;
- b1 = NULL;
- return 0;
- }
I am Base()
I am Base()
I am Derived()
I am Base()
I am Derived()
Hello Base
World Base
Hello Derived
World Base
Hello Derived
World Derived
I am ~Derived()
I am ~Base()
I am ~Derived()
I am ~Base()
I am ~Base()
11、阅读以下程序并给出执行结果
- class Bclass
- {
- public:
- Bclass(int i , int j)
- {
- x = i;
- y = j;
- }
- virtual int fun()
- {
- return 0;
- }
- protected:
- int x , y;
- };
- class lclass : public Bclass
- {
- public:
- lclass(int i , int j , int k) : Bclass(i , j)
- {
- z = k;
- }
- int fun()
- {
- return (x+y+z)/3;
- }
- private:
- int z;
- };
- int main(void)
- {
- lclass obj(2,4,10);
- Bclass p1 = obj;
- cout<<p1.fun()<<endl;
- Bclass &p2 = obj;
- cout<<p2.fun()<<endl;
- cout<<p2.Bclass::fun()<<endl;
- Bclass *p3 = &obj;
- cout<<p3->fun()<<endl;
- return 0;
- }
0
5
0
5
12、如何减少频繁分配内存(malloc或者new)造成的内存碎片?(10分)
内存池(Memory Pool)是一种内存分配方式。 通常我们习惯直接使用new、malloc等API申请分配内存,这样做的缺点在于:由于所申请内存块的大小不定,当频繁使用时会造成大量的内存碎片并进而降低性能。内存池则是在真正使用内存之前,先申请分配一定数量的、大小相等(一般情况下)的内存块留作备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存。这样做的一个显著优点是尽量避免了内存碎片,使得内存分配效率得到提升。
(1)针对特殊情况,例如需要频繁分配释放固定大小的内存对象时,不需要复杂的分配算法和多线程保护。也不需要维护内存空闲表的额外开销,从而获得较高的性能。
(2)由于开辟一定数量的连续内存空间作为内存池块,因而一定程度上提高了程序局部性,提升了程序性能。
(3)比较容易控制页边界对齐和内存字节对齐,没有内存碎片的问题。
(4)当需要分配管理的内存在100M一下的时候,采用内存池会节省大量的时间,否则会耗费更多的时间。
(5)内存池可以防止更多的内存碎片的产生
(6)更方便于管理内存
13、请写出strchr的实现(10分)
函数功能:找出在字符串str中第一次出现字符ch的位置,找到就返回该字符位置的指针(也就是返回该字符在字符串中的地址的位置),找不到就返回空指针(就是NULL)
char *strchr(const char *s,char c);
char *strchr(const char* str,char ch)
{
if(str==NULL)
{
return NULL;
}
while(*str!='\0')
{
if(*str==ch)
{
return (char*)str;
}
str++;
}
return NULL;
}
14、请写出冒泡排序法算法(20分)
void BubbleSort(int r[] , int n);
- void BubbleSort(int r[] , int n)
- {
- int i , j , temp;
- for(i = 0 ; i < n - 1 ; ++i)
- {
- for(j = 0 ; j < n-i-1 ; ++j)
- {
- if(r[j] > r[j + 1])
- {
- temp = r[j];
- r[j] = r[j + 1];
- r[j + 1] = temp;
- }
- }
- }
- }