练习(三)

1、 以下程序的输出是
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Base {
     public :
     Base( int j): i(j)  {}
     virtual ~Base() {}
     void func1() {
         i *= 10;
         func2();
     }
     int getValue() {
         return   i;
     }
     protected :
     virtual void func2() {
         i++;
     }
     protected :
     int i;
};
class Child:  public Base {
     public :
     Child( int j): Base(j) {}
     void func1() {
         i *= 100;
         func2();
     }
     protected :
     void func2() {
         i += 2;
     }
};
int main() {
     Base * pb =  new Child(1);
     pb->func1();
     cout << pb->getValue() << endl;  delete pb; }


11
101
12
102
2、 针对以下代码,
1
2
3
4
const char str1[]=”abc”;
const char str2[]=”abc”;
const char *p1 = “abc”;
const char *p2 = “abc”;
判断下列说法哪个是正确的(注意是地址):______。

str1和str2地址不同,P1和P2地址相同。
str1和str2地址相同,P1和P2地址相同。
str1和str2地址不同,P1和P2地址不同。
str1和str2地址相同,P1和P2地址不同。
3、 下列C程序执行后c输出结果为( )
1
2
3
4
5
6
7
8
9
#include<stdio.h>
#include<stdlib.h>
void main()
{
   int a = -3;
  unsigned  int b = 2;
   long c = a + b;
   printf ( "%ld\n" ,c);
}
-1
4294967295
0x7FFFFFFF
0xFFFFFFFF

4、
Which of the following statements are true?
We can create a binary tree from given inorder and preorder traversal sequences.
We can create a binary tree from given preorder and postorder traversal sequences.
For an almost sorted array, insertion sort can be more effective than Quicksort.
Suppose T(n) is the runtime of resolving a problem with n elements, T(n) = Θ(1) if n = 1; T(n) = 2T(n/2) + Θ(n) if > 1; so T(n) is Θ(n log n).
None of the above.
5、
1
2
3
4
5
6
#define F(X,Y)   (X)--, (Y)++, (X)*(Y);
int i, a = 3, b = 4;
for ( i = 0; i<5; i++)
     F(a,b) ;
printf (“%d, %d”, a, b);
输出结果是

 
3, 4
3, 5
-2, 5
-2, 9
6、 下列代码的运行结果是()

 

gstrin
string
srting
stirng
7、
() 的作用是将源程序文件进行处理,生成一个中间文件,编译系统将对此中间文件进行编译并生成目标代码。

编译预处理
汇编
生成安装文件
编译
8、 对于下面的代码,说法正确的是____。
1
2
3
4
5
6
char * s1 =  "Hello world" ;
char s2[] =  "Hello world" ;
s1[2] =  'E' ;      // 1
s2[2] =  'E' ;      // 2
*(s1 + 2) =  'E' ;   // 3
*(s2 + 2) =  'E' ;   // 4
语句2、4是非法的
语句3、4是非法的
语句1、3是非法的
仅语句1是非法的
仅语句2是非法的
语句1~4都是合法的

9、 以下代码实现了从表中删除重复项的功能,请选择其中空白行应填入的正确代码()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template < typename T>
void removeDuplicates(list<T> &aList)
{
     T curValue;
     list<T>::iterator cur, p;
     cur = aList.begin();
     while (cur != aList.end())
     {
         curValue = *cur;
         //空白行
         while (p != aList.end())
         {
             if (*p == curValue)
             {
                 //空白行
             }
             else
             {
                 p++;
             }
         }
     }
}
p=curr+1;aList.erase(p++);
p=++curr;aList.erase(p++);
p=curr+1;aList.erase(p);
p=++curr;aList.erase(p);

10、 以下代码是否完全正确,执行可能得到的结果是____。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A{
    int i;
};
class B{
    A *p;
public :
    B(){p= new A;}
    ~B(){ delete p;}
};
void sayHello(B b){
}
int main(){
    B b;
    sayHello(b);
}
程序正常运行
程序编译错误
程序崩溃
程序死循环
11、 在下列排序算法中,哪几个算法的时间复杂度与初始排序无关()
插入排序
堆排序
冒泡排序
归并排序
选择排序
12、 关于引用与指针的区别,下面叙述错误的是:
引用必须被初始化,指针不必。
指针初始化以后不能被改变,引用可以改变所指的对象。
删除空指针是无害的,不能删除引用。
不存在指向空值的引用,但是存在指向空值的指针。
13、 有如下C++代码:
1
2
3
4
5
6
7
8
9
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" );}
};
那么 
1
2
3
A *p= new B;
p->foo();
p->bar();
输出为:  
barfoob_bar
foobarb_bar
barfoob_foo
foobarb_fpp

14、 词法分析器用于识别()
句子
句型
单词
生产式
15、 对于派生类的构造函数,在定义对象时构造函数的执行顺序为?
1:成员对象的构造函数
2:基类的构造函数
3:派生类本身的构造函数

123
231
321
213
16、 哪个操作符不能被重载?
, (逗号)
()
. (点)
[]
->

17、 如果A,B,C为布尔型变量,“^”和“v”分别代表布尔类型的“与”和“或”,下面那一项是正确的()
I.A^(BvC)=(A^B)v(A^C)
II.Av(B^C)=(AvB)^(AvC)
III.(B^A)vC=Cv(A^B)
只有I
只有II
只有I和II
I,II,III;
18、 下列 C 代码中,不属于未定义行为的有___

int i=0;i=(i++);
char *p=”hello”;p[1]=’E’;
char *p=”hello”;char ch=*p++;
int i=0;printf(“%d%d\n”,i++,i--);
都是未定义行为
都不是未定义行为
19、 关于struct和class,下列说法正确的是()

struct的成员默认是public,class的成员默认是private
struct不能继承,class可以继承
struct可以有无参构造函数
struct的成员变量只能是public
20、 下面程序的输出结果是
1
2
3
char *p1= “123”, *p2 = “ABC”, str[50]=  "xyz" ;
strcpy (str+2, strcat (p1,p2));
cout << str;
xyz123ABC
z123ABC
xy123ABC
出错
21、 以下代码输出什么____.  
1
2
3
4
5
6
main()
{
    int a[5]={1,2,3,4,5};
    int *p=( int *)(&a+1);
    printf ( "%d" ,*(p-1));
}
1
2
5
出现错误
22、 由多个源文件组成的C程序,经过编辑、预处理、编译,链接等阶段会生成最终的可执行程序。下面哪个阶段可以发现被调用的函数未定义?
预处理
编译
链接
执行
23、 若要重载+、=、<<、=和[]运算符,则必须作为类成员重载的运算符是
+和=
=和<<
==和<<
=和[]

解析:
1、
类的指针指向派生类的对象
基类指针调用其虚成员函数,则会调用其真正指向对象的成员函数,而不是基类中定义的成员函数,若不是虚函数,则不管基类指针指向的是哪个派生对象,调用的都是基类中定义的那个函数   
2、
  1. str1和str2毫无干系,他们都是字符常量数组,恰巧存储的值相同而已。"abc"和str1 str2都存储在常量区。str1 str2的地址就是str1[0] str2[0]的地址,即数组首元素所在的地址。
  2. 后面的两个“abc”存储在常量区,因为他们是字面值(常量),但是p1 p2存储在栈中。其中p1和p2的值不同,但是他们指向同一块静态存储区域。也就是"abc"的地址。
3、
无符号和有符号整数进行运算时,有符号整数会被提升为无符号整数。
-3对应的二进制表示是0xfffffffd,和2相加表示0xffffffff。
输出结果取决于long是32位,还是64位。这个取决于编译器和机器。
long是有符号的整型。
如果是32位,0xfffffff在补码表示法(最高位是负数位)下是等于-1.
如果是64位,0xfffffff是属于long的正整数范围(负数位在第64位),等于 4294967295。
(如果你的编译出来是32位的long,你可以用longlong测试一下就能得到这个数。因为 long long 无论在32位机器或者64位机器都是占用8个字节64位)
4、
常见算法
折半搜索 情形二(k = 0)
二叉树遍历 情形一
归并排序 情形二(k = 0)


在算法分析中,主定理(英语:master theorem)提供了用渐近符号表示许多由 分治法 得到的 递推 关系式的方法。此方法经由经典算法教科书《算法导论》而为人熟知。不过,并非所有递推关系式都可应用主定理。该定理的推广形式包括Akra-Bazzi定理。

假设有递推关系式
 ,其中  为问题规模,  为 递推 的子问题数量,  为每个子问题的规模(假设每个子问题的规模基本一样),  为 递推 以外进行的计算工作。
a≥1,b>1为常数,f(n) 为函数,T(n) 为 非负整数 。则有以下结果:
(1)若  那么
(2)若  那么
(3)若  且对于某个常数  和所有 充分大 
 有  那么


这里是情况2,且a=b,所以有T(n) = O(n logn)
5、
使用宏定义F(x,y) -> #define F(X,Y)   (X)--, (Y)++, (X)*(Y)
展开后如下:
inti, a = 3, b = 4;
for( i = 0; i<5; i++)
    (a)--,(b)++,(a)*(b);
printf(“%d, %d”, a, b);
(a)--,(b)++,(a)*(b);
是逗号表达式,按从左往右逐个计算表达式,整个表达式最终结果(a)*(b)的值(这部分对a和b值无影响)
计算 了5次for循环的(a)--和(b)++ 的到a=-2,b = 9;
6、
根据栈操作
POP(s,x)是出栈 ,把栈S中出栈一个元素给到x。
Push(s,r)是进栈,让r进入s栈。
栈服从先进后出原则。
7、
这题目有问题!详见 http://m.blog.csdn.net/article/details?id=16820035
8、
指针指向字符串时,字符串是常量,存储在常量区,而指针存储在栈区,不能对其操作修改。
9、
当使用一个容器的insert或者erase函数通过迭代器插入或删除元素"可能"会导致迭代器失效
iterator失效主要有两种情况:
1、iterator变量已经变成了“野指针”,对它进行*,++,--都会引起程序内存操作异常;
2、iterator所指向的变量已经不是你所以为的那个变量了。
不同的容器,他们erase()的返回值的内容是不同的,有的会返回被删除元素的下一个的iterator,有的则会返回删除元素的个数。
对于非结点类,如数组类的容器 vector,string,deque 容器标准写法是这样:
1
2
3
4
5
6
7
8
9
10
  //vector<int> m_vector;
  for (vector< int >::iterator iter = m_vector.begin(); iter != m_vector.end();)
{
     if (需要删除)
     {
         iter=m_vector.erase(iter);
     }
     else
         ++iter;
}
数组型数据结构:该数据结构的元素是分配在连续的内存中,insert和erase操作,都会使得删除点和插入点之后的元素挪位置,所以,插入点和删除掉之后的迭代器全部失效,也就是说insert(*iter)(或erase(*iter)),然后在iter++,是没有意义的。解决方法:erase(*iter)的返回值是下一个有效迭代器的值。 iter =cont.erase(iter);

对于结点类容器(如:list,map,set)是这样:
1
2
3
4
5
6
7
8
9
10
  //map<int,int> m_map;
for (map< int , int >::iterator iter = m_map.begin(); iter != m_map.end(); )
{
     if (需要删除)
     {
         m_map.erase(iter++);
     }
     else
         ++iter;
}
链表型数据结构:对于list型的数据结构,使用了不连续分配的内存,删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.解决办法 两种,erase(*iter)会返回下一个有效迭代器的值,或者erase(iter++).

树形数据结构: 使用红黑树来存储数据,插入不会使得任何迭代器失效;删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以采用erase(iter++)。
10、
默认的拷贝构造函数是浅拷贝,直接把指针的值复制了一份。
调用sayHello,离开作用域,调用析构函数delete了一次。main函数中,又delete了一次。因此程序崩溃
11、 选快希堆不稳(是不稳定的排序),
        堆归选基均不变(运行时间不发生变化,与初始状态无关)
12、
指针在建立后会被分配一块空间,用于存储其所指向的地址,因为指针是有对应内存空间的,因此指针值(指向的内存空间)是可以改变的;而引用则不行,引用没有内存空间,仅仅是被引对象内存空间的别名,改变引用如&a=4实际上等价于a=4,改变的是被引对象的值,不改变该引用所指的内存空间;
指向空值的引用是没有意义的(因为引用对象不能改变,也就是这个引用永远指向null,那这个引用根本就没有存在的必要);指向空值的指针是有意义的,尤其在指针被删除后,如果不对指针进行赋值,则指针的值将会由系统随机指定,这样后续如果有对指针的操作的话,将会带来很大的风险。因此指针被删除后必须赋值为null;
因为引用无法改变,因此不进行初始化的引用没有意义;因为指针可以改变,因此指针可以不进行初始化,可以在后续程序中动态改变;

总结一下引用和指针的区别:
  1、引用是直接访问,指针是间接访问
  2、引用是变量的别名,本身不单独分配自己的内存空间。指针有自己的内存空间。
  3、引用一旦初始化,不能再引用其他变量。而指针可以!

13、
A *p=newB;// A类指针指向一个实例化对象B, B类继承A类,先调用父类的无参构造函数,bar()输出bar,B类没有自己显示定义的构造函数。
p->foo();//执行B类里的foo()函数,因为foo不是虚函数,所以直接调用父类的foo函数,输出foo
p->bar();//执行B类的bar()函数, 该函数为虚函数,调用子类的实现,输出b_bar
14、
词法分析器的工作是低级别的分析:将字符或者字符序列转化成记号.。在谈论词法分析时,使用术语“词法记号”(简称记号)、“模式”和“词法单元”表示特定的含义。
在分析时,一是把词法分析器当成语法分析的一部分,另一种是把词法分析器当成编译程序的独立部分。在前一种情况下,词法分析器不断地被语法分析器调用,每调用一次词法分析器将从源程序的字符序列拼出一个单词,并将其Token值返回给语法分析器。后一种情况则不同,词法分析器不是被语法分析器不断地调用,而是一次扫描全部单词完成编译器的独立一遍任务。

15、 理解:1.类的构造函数可能使用类的对象成员,因此类的对象成员→类的构造函数
        2.派生类的构造函数可能使用父类的对象成员,因此基类的构造函数→派生类的构造函数
        3.析构和构造刚好相反~

16、 c++不能重载的运算符有.(点号),::(域解析符),?:(条件语句运算符),sizeof(求字节运算符),typeid,static_cast,dynamic_cast,interpret_cast(三类类型转换符)。
17.

18.
C语言中的未定义行为(Undefined Behavior)是指C语言标准未做规定的行为。同时,标准也从没要求编译器判断未定义行为,所以这些行为有编译器自行处理,在不同的编译器可能会产生不同的结果,又或者如果程序调用未定义的行为,可能会成功编译,甚至一开始运行时没有错误,只会在另一个系统上,甚至是在另一个日期运行失败。当一个未定义行为的实例发生时,正如语言标准所说,“什么事情都可能发生”,也许什么都没有发生。

所以,避免未定义行为,是个明智的决定。本文将介绍几种未定义行为,同时欢迎读者纠错和补充。

1.同一运算符中多个操作数的计算顺序(&&、||、?和,运算符除外)

例如:x = f()+g(); //错误

f()和g()谁先计算由编译器决定,如果函数f或g改变了另一个函数所使用变量的值,那么x的结果可能依赖于这两个函数的计算顺序。

参考: 《C程序设计语言(第2版)》 P43

2.函数各参数的求值顺序

例如: printf("%d,%d\n",++n,power(2,n)); //错误

在不同的编译器可能产生不同的结果,这取决于n的自增运算和power调用谁在前谁在后。

需要注意的是,不要和逗号表达式弄混,都好表达式可以参考这篇文章:c语言中逗号运算符和逗号表达式

参考: 《C程序设计语言(第2版)》 P43

3.通过指针直接修改 const 常量的值

直接通过赋值修改const变量的值,编译器会报错,但通过指针修改则不会,例如:



a输出值也由编译器决定。

19、
1.不同点
  struct class
默认继承权限 public private
默认数据访问控制 public private
模板参数 不能定义 可以用于定义模板参数
2.相同点
可以有数据成员,方法,构造函数等。

20、
char* strcat(char *,const char*)//第一个参数所指向的内容必须可以修改,可以赋值为在栈上分配的数组
strcat(p1,p2)试图修改p1的内容,p1指向文字常量区,其指向的内容无法修改
21、 选择c,&a表示一个指向大小为5数组的指针,那么&a+1就是表示一个指向大小为5的下一个数组的指针,也就是数组a最后一个元素的下一个位置,那么int *p=(int *)(&a+1)进行强制类型转换,将指向数组的指针转换为指向第二个数组中首元素的指针,所以p-1则是指向第一个数组中最后一个元素的指针,所以输出是5。p定义是int *,p+i或者p-i编译器按p+i*4或p-i*4来算。 &a的类型是 int [5],指向五个int空间的指针,所以a+1编译器做 a地址+4*5来算,那么p-1最后指向a[4]   
22、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//预处理:处理#include、宏替换和条件编译
//编译:生成目标文件(.cpp->.o)
//链接:链接多个目标文件
//例子:
//main.cpp
int main(){
     fun();
}
//编译不可通过,提示函数fun()未声明
void fun();
int main(){
     fun();
}
//编译可通过,链接不可通过,提示函数fun()未定义

23、
(1)只能使用成员函数重载的运算符有:=、()、[]、->、new、delete。
          (2)单目运算符最好重载为成员函数。  
          (3) 对于复合的赋值运算符如+=、-=、*=、/=、&=、!=、~=、%=、>>=、<<=建议重载为成员函数。  
          (4) 对于其它运算符,建议重载为友元函数。

运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的。运算符重载实质上是函数的重载。重载运算符的函数一般格式如下:

          函数类型 operator 运算符名称 (形参表列)
          { 
          对运算符的重载处理
          }

重载为类成员函数时参数个数=原操作数个数-1(后置++、--除外)
重载为友元函数时 参数个数=原操作数个数,且至少应该有一个自定义类型的形参

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HySmiley

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值