C++小题(十)

/*
设x、y、t均为int型变量,则执行语句:t=3; x=y=2; t=x++||++y; 后,变量t和y的值分别为____
t=1 y=2
*/
////////////////////////////////////////////////////////////////////
/*
C++中,下面四个表达式中错误的一项是()
正确答案: C   

a+=(a++)
a+=(++a)
(a++)+=a
(++a)+=(a++)

A: a+=(a++)    先计算a++ ,因为a为后++,a左边是左值不会报错 ;
B: a+=(++a)    先计算++a,因为a为前++, a左边是左值不会报错 ;
C::(a++) += a  这个是错误的。因为左值只能是变量,不能是表达式,(a++)是后++, 所以a不会先计算a++,是表达式,。所以会报错。
D:(++a) +=(a++) 先计算++a,然后再去计算a +=(a++) ,所以左边也是左值 ;   
*/
////////////////////////////////////////////////////////////////////
/*
以下程序的输出结果是:
#include <iostream.h>
void main() {
    int x=3,y=3;
    switch(x%2) {
        case 1:
            switch (y) {
        		case 0:cout<<"first";
        		case 1:cout<<"second";break;
        		default: cout<<"hello";
    		}
    	case 2:cout<<"third";
    }
}
正确答案: D   

second third
hello
first second
hellothird

case语句后面没有break,顺序执行。
*/
////////////////////////////////////////////////////////////////////
/*
下列说法错误的有( )
正确答案: A C D   你的答案: C D (错误)

A在类方法中可用this来调用本类的类方法
B在类方法中调用本类的类方法时可直接调用
C在类方法中只能调用本类中的类方法
D在类方法中绝对不能调用实例方法

成员方法又称为实例方法
静态方法又称为类方法
其次:
A:类方法是指类中被static修饰的方法,无this指针。
C:类方法是可以调用其他类的static方法的。
D:可以在类方法中生成实例对象再调用实例方法。
*/
////////////////////////////////////////////////////////////////////
/*
switch()中不允许的数据类型有?
正确答案: B C   你的答案: B (错误)

A整型
B浮点型
C字符串
D布尔

C++
1. char、short、int、long、bool 基本类型都可以用于switch语句。
2. float、double都不能用于switch语句。
3. enum类型,即枚举类型可以用于switch语句。
4. 所有类型的对象都不能用于switch语句。
5. 字符串也不能用于switch语句
*/
////////////////////////////////////////////////////////////////////
/*
请选择下列程序的运行结果
#include<iostream>
using namespace std;
class B0//基类BO声明
{
public://外部接口
virtual void display0//虚成员函数
{
    cout<<"B0::display0"<<endl;}
};
class B1:public B0//公有派生
{
public:
    void display() { cout<<"B1::display0"<<endl; }
};
class D1: public B1//公有派生
{
public:
    void display(){ cout<<"D1::display0"<<endl; }
};
void fun(B0 ptr)//普通函数
{   
    ptr.display();  
}
int main()//主函数
{ 
    B0 b0;//声明基类对象和指针
    B1 b1;//声明派生类对象
    D1 d1;//声明派生类对象
    fun(b0);//调用基类B0函数成员
    fun(b1);//调用派生类B1函数成员
    fun(d1);//调用派生类D1函数成员
}
正确答案: A   你的答案: A (正确)

B0::display() B0::display() B0::display()
B0::display() B0::display() D1::display()
B0::display() B1::display() D1::display()
B0::display() B1::display() B1::display()
虚函数的动态绑定仅在基类指针或引用绑定派生类对象时发生,fun的形参不是指针,所以调用哪个版本的函数编译时就已经确定,
根据形参静态类型确定调用B0的成员。
*/
////////////////////////////////////////////////////////////////////
/*
用户双击鼠标时产生的消息序列,下面正确的是()
正确答案: D   你的答案: D (正确)

WM_LBUTTONDOWN,WM_LBUTTONUP,WM_LBUTTONDOWN,WM_LBUTTONUP
WM_LBUTTONDOWN,WM_LBUTTONUP,WM_LBUTTONUP,WM_LBUTTONDBLCLK
WM_LBUTTONDOWN,WM_LBUTTONUP,WM_LBUTTONDOWN,WM_LBUTTONDBLCLK
WM_LBUTTONDOWN,WM_LBUTTONUP,WM_LBUTTONDBLCLK,WM_LBUTTONUP

双击即点击左键两下,第一次触发LBUTTONDOWN和LBUTTONUP,第二次点击时触发双击事件LBUTTONDBLCLK(doubleclick),放掉再触发LBUTTONUP
打开一个文件夹,当第二次DOWN时暂时不要UP,文件夹也可以打开
*/
////////////////////////////////////////////////////////////////////
/*
以下代码的输出结果是?
#define a 10
 
void foo(); 
main(){
 
  printf("%d..",a);
   foo();
   printf("%d",a);
}
void foo(){
   #undef a
   #define a 50
}

正确答案: A   你的答案: A (正确)

10..10
10..50
Error
0

define在预处理阶段就把main中的a全部替换为10了.
另外,不管是在某个函数内,还是在函数外,define都是从定义开始直到文件结尾,
所以如果把foo函数放到main上面的话,则结果会是50 ,50.   #undef 指令作用是取消以前定义的宏定义
*/
////////////////////////////////////////////////////////////////////
/*
#include<iostream>
using namespace std;
#pragma pack(2)
class A{
	int i;
	union U{
		char buff[13];
		int j;
	}u;
	void foo(){}
	typedef char* (*f)(void*);
	enum{
		red,blue,white
	}color;
};
int main(){
	cout<<sizeof(A);
}
枚举变量的取值为花括号内的任意一个值(有且只能有其中一个值),而这个值是int型的,
在X86系统中,int型的数据占内存4个字节。所以枚举变量的内存大小为4。
因为#pragma pack(2),所以答案为4+14+4=22 
去掉#pragma pack(2),答案为4+16+4=24
不定义u和color,答案为 4.
*/
////////////////////////////////////////////////////////////////////
/*
求输出结果 
int a[2][2][3]= { {{1,2,3},{4,5,6}},{{7,8,9},{10,11,12}}};
int *ptr=(int *)(&a+1);
printf(“%d %d”, *(int*)(a+1), *(ptr-1));

正确答案: A   

7 12
1 6
1 3
7 9

*(int*)(a+1) 指向数组 a[2] 的第二个元素中的第一个,也就是内部第二层大括号的第一个元素
*(ptr-1)整个数组的最后一个元素,因为 (int *)(&a+1); 指向整个数组的下一个位置
*/
////////////////////////////////////////////////////////////////////
/*
#include<iostream>
using namespace std;
 
class Base
{
public:
    virtual int foo(int x)
    {
        return x * 10;
    }
 
    int foo(char x[14])
    {
        return sizeof(x) + 10;
    }
};
 
class Derived: public Base
{
    int foo(int x)
    {
        return x * 20;
    }
 
    virtual int foo(char x[10])
    {
        return sizeof(x) + 20;
    }
} ;
 
int main()
{
    Derived stDerived;
    Base *pstBase = &stDerived;
 
    char x[10];
    printf("%d\n", pstBase->foo(100) + pstBase->foo(x));
 
    return 0;
}
在32位环境下,以上程序的输出结果是?
正确答案: C   

2000
2004
2014
2024

pstBase->foo(100) + pstBase->foo(x)
pstBase->foo(100)  调用继承的函数,因为父函数有virtual修饰,被子类的同名函数覆盖。
pstBase->foo(x)     调用父类函数,因为 父函数没有有virtual修饰。int foo(char x[14]) 参数传的是指针,指针是4个字节。  
所以结果是2014。
*/
////////////////////////////////////////////////////////////////////
/*
有哪几种情况只能用intialization list 而不能用assignment?
正确答案: A B C   你的答案: A C (错误)

A当类中含有const成员变量
B基类无默认构造函数时,有参的构造函数都需要初始化表。
C当类中含有reference成员变量
D当类中含有static成员变量

因为const对象以及引用只能初始化而不能赋值,所以只能使用成员初始化列表。
对于非内置类型,在进入函数体之前,如果没有提供显式初始化,会调用默认构造函数进行初始化。
若没有默认构造函数,则编译器尝试调用默认构造函数将会失败,所以如果没有默认构造函数,则必须在初始化列表中显式的调用构造函数。
static 成员在执行构造函数前就已经构造好了,即使不存在类对象,也可以被使用,不需要初始化列表
*/
////////////////////////////////////////////////////////////////////
/*
在重载运算符函数时,下面()运算符必须重载为类成员函数形式()
正确答案: D   你的答案: D (正确)

+
-
++
->

只能使用成员函数重载的运算符有:=、()、[]、->、new、delete。 
*/
////////////////////////////////////////////////////////////////////
/*
关于以下代码,哪个说法是正确的?
myClass::foo(){
    delete this;
}
..
void func(){
    myClass *a = new myClass();
    a->foo();
}
正确答案: B   你的答案: B (正确)

它会引起栈溢出
都不正确
它不能编译
它会引起段错误

在delete this之后进行的其他任何函数调用,只要不涉及到this指针的内容,都能够正常运行。
一旦涉及到this指针,如操作数据成员,调用虚函数等,就会出现不可预期的问题
但是,假如析构函数中调用delete this,delete this会去调用本对象的析构函数,将会导致形成无限递归,造成堆栈溢出
http://blog.sina.com.cn/s/blog_4b4cf2af0100ywgv.html

*/
////////////////////////////////////////////////////////////////////
/*
给定3个int类型的正整数x,y,z,对如下4组表达式判断正确的选项()
int a1=x+y-z; int b1=x*y/z;
int a2=x-z+y; int b2=x/z*y;
int c1=x<<y>>z; int d1=x&y|z;
int c2=x>>z<<y; int d2=x|z&y;
正确答案: A   你的答案: A (正确)

a1一定等于a2
b1一定等于b2
c1一定等于c2
d1一定等于d2

A选项x+y有溢出的可能,但是通过-z又可以得到正确的结果,因为,当溢出的时候,是在int的表示范围内循环轮转。
如用char来模拟int,127 + 1 = -128,-128 + 1 = -127,-128 - 1 = 127,说明了是在char的表示范围内循环轮转。
*/
////////////////////////////////////////////////////////////////////
/*
非静态成员类内初始化只能在C++11中实现,而且要用int var=1;不能用int var(1); 
*/
////////////////////////////////////////////////////////////////////
/*
有以下程序
#include <stdio.h>
main(){
    int i=0;
    i=~i;
    printf("%d\n",i);
}
程序运行后的输出结果是?
正确答案: D   
8
0
1
-1

unsigned int a=0;
cout<<~a; 输出4294967295

int a=0;
cout<<~a; 输出-1 
*/
////////////////////////////////////////////////////////////////////
/*
有如下程序段:
#include "stdio.h"
 
class A
{
public:
    int _a;
    A()
    {
        _a = 1;
    }
    void print()
    {
        printf("%d", _a);
    }
};
class B: public A
{
public:
    int _a;
    B()
    {
        _a = 2;
    }
};
int main()
{
    B b;
    b.print();
    printf("%d", b._a);
}
请问程序输出:
正确答案: D   你的答案: D (正确)

22
11
21
12

因为在继承的时候,允许子类存在与父类同名的成员变量,但是并不覆盖父类的成员变量,他们同时存在。 
因为给孩子类中没有定义print函数,所以会按照就近原则去寻找父类中是否有print函数。
恰好父类中有这个函数,于是调用父类的print函数b.print(),而这个函数会调用父类的a变量
*/
////////////////////////////////////////////////////////////////////
/*
unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
请问p1+5= 什么?
p2+5= 什么?
正确答案: C   

801005   810005
801010   810014
801005   810014
801010  810015

1代表的是一个单位量  
p1+5=p1+5*1=p1+5*sizeof(unsigned char)=p1+5*1=0x801000+ox5=0x801005  
p2+5=p2+5*1=p2+5*sizeof(unsigned long)=p1+5*4=0x810000+20=0x810000+0x14=0x810014 
*/
////////////////////////////////////////////////////////////////////
/*
下面有关函数模板和类模板的说法正确的有?
正确答案: A B C D   

A函数模板的实例化是由编译程序在处理函数调用时自动完成的
B类模板的实例化必须由程序员在程序中显式地指定
C函数模板针对仅参数类型不同的函数
D类模板针对仅数据成员和成员函数类型不同的类


   模板(Template)是一种强大的C++软件复用特性,通常有两种形式:函数模板和类模板。
函数模板针对仅参数类型不同的函数(答案C ok);类模板针对仅数据成员和成员函数类型不同的类(答案D ok)。
函数模板和类模板可以是程序员只需制定一个单独的代码段,
就可表示一整套称为函数模板特化的相关(重载)函数或是表示一整套称为类模板特化的相关的类。
这种技术称为泛型程序设计(generic programming)。
使用模板的好处在于,可以使程序员编写与类型无关的代码。

模板是一个类家族的抽象,它只是对类的描述,编译程序不为类模板(包括成员函数定义)创建程序代码,
但是通过对类模板的实例化可以生成一个具体的类以及该具体类的对象。
与函数模板不同的是:函数模板的实例化是由编译程序在处理函数调用时自动完成的(答案A正确),
而类模板的实例化必须由程序员在程序中显式地指定(答案B正确)
*/
////////////////////////////////////////////////////////////////////
/*
以下程序输出的结果是()
#include<stdio.h>
int main(){
   int x=10,y=10;
   printf("%d %d",x--,--y);
}
正确答案: D   

10 10
9  9
9  10
10 9
*/
////////////////////////////////////////////////////////////////////
/*
#include<iostream>
using namespace std;
 
int main()
{
    int a[] = {2, 4, 6, 8, 10}, *p, **k;
    p = a;
    k = &p;
    printf(" % d", *(p++));
    printf(" % d\n", **k);   
    return 0;
}

正确答案: B   

A 4 4
B 2 4
C 2 2
D 4 6
*/
////////////////////////////////////////////////////////////////////
/*
函数调用exec((vl,v2),(v3,v4),v5,v6);中,实参的个数是:
正确答案: B   你的答案: B (正确)

3
4
5
6

函数原型exec((vl,v2),(v3,v4),v5,v6);
用括号括起来的两个形参组成是一个逗号运算符组成的表达式
C语言中逗号运算符返回最后一个参数作为表达式的值
所以(vl,v2)和(v3,v4)是两个逗号表达式,相当于两个实参
所以一共4个实参
*/
////////////////////////////////////////////////////////////////////
/*
下面哪个操作符不能重载()
正确答案: C   你的答案: C (正确)

=
<
sizeof
%

除了. ,.* ,:: ,? : ,sizeof,typeid这6个运算符不能被重载,其他运算符都能被重载
*/
////////////////////////////////////////////////////////////////////
/*
如果要实现一个多线程(非MFC)程序, 选择多线程CRT, 创建线程的时候应该用CreateThread还是_beginthreadex()?
正确答案: B  

CreateThread
_beginthreadex
一样
和具体机器配置相关

 _beginthreadex()比较于 CreateThread()有更高的线程安全性,不会造成多个线程共用同一个全局变量的情况

*/
////////////////////////////////////////////////////////////////////
/*
#include <stdio.h>
#include <stdlib.h>
void fun ( double *pl,double *p2,double *s)
{
    s = ( double*) calloc ( 1,sizeof(double));
    *s = *pl + *(p2+l);
}
main( )
{
    double a [2] = {1.1,2.2},b [2] = {10.0,20.0}, *s = a;
    fun (a,b,s);
    printf ( "%5.2f\n",* s) ;
}
程序的输出结果是?
正确答案: D  

21.10
11.10
12.10
1.10

编译器编译时给指针参数提供临时副本 _p,使得_p=p。如果函数体内的程序修改了_p指向的内容,
就导致参数p指向的内容也被做了相应的修改,因为他们指向同一内存空间。在本例中,_p 申请了新的内存,
只是把_p 所指的内存地址改变了,但是p 丝毫未变(即修改了p本身的值而不是_p指向的对象)
*/
////////////////////////////////////////////////////////////////////
/*
char* getMem(void) {     
      char p[] = “hello world ”;
       p[5] = 0x0;
       return p;
 }
 void test(void) {     
      char *s = 0x0;
       s = getMem();
       printf(s);
 }

正确答案: D   

hello
无输出
Hello0world
不确定

warning: function returns address of local variable
*/
////////////////////////////////////////////////////////////////////
/*
#include <stdio.h>
char fun(char *c)
{
     if(*c<=`Z`&& *c>=`A`)
        *c-=`A`-`a`;
     return *c;
}
main()
{
    char s[81],*p=s;
    gets(s);
    while(*p)
    {
        *p = fun(p);
        putchar( *p);
        p++;
    }
    printf("\n");
}
若运行时从键盘上输入OPEN THE DOOR<回车>,程序的输出结果是?
正确答案: C  

OPEN THE DOOR
oPEN tHE dOOR
open the door
Open The Door

gets()函数用来从标准输入设备(键盘)读取字符串直到回车结束, 但回车符
不属于这个字符串。其调用格式为:
		gets(s);
    其中s为字符串变量(字符串数组名或字符串指针)。
    gets(s)函数与scanf("%s", s)相似, 但不完全相同, 使用scanf("%s", s)
函数输入字符串时存在一个问题, 就是如果输入了空格会认为输入字符串结束,
空格后的字符将作为下一个输入项处理, 但gets() 函数将接收输入的整个字符
串直到回车为止。
*/
////////////////////////////////////////////////////////////////////
/*
全局对象在main退出后,程序结束前析构吗?
正确答案: A   你的答案: A (正确)

是
错

全局对象的生命周期跨越整个程序运行时间,全局对象是在main函数调用之前创建的,析构在main函数之后,程序结束之前
*/
////////////////////////////////////////////////////////////////////
/*
4.void swap_int(int a , int b)
5.{
6.    int temp = a;
7.    a = b;
8.    b = temp;
9.}
10.
11.void swap_str(char*a , char*b)
12.{
13.    char*temp = a;
14.    a = b;
15.    b = temp;
16.}
17.
18.int main(void)
19.{
20.    int a = 10;
21.    int b = 5;
22.    char*str_a = "hello world";
23.    char*str_b = "world hello";
24.    swap_int(a , b);.
25.    swap_str(str_a , str_b);
26.    printf("%d %d %s %s\n",a,b,str_a,str_b);
27.
28.    return 0;
29.}
正确答案: A   

A 10 5 hello world world hello
B 10 5 world hello hello world
C 5 10 hello world world hello
D 5 10 world hello hello world

swap_int(a, b)将实参10,5传递给了形参,在被调用函数中交换了10和5,但是调用结束,函数释放变量,实参中并没有交换;
swap_str(str_a, str_b)将实参的地址传递给了形参,其实跟上面的类似,并没有改变实参str_a、str_b的指向,实参没有交换。
*/
////////////////////////////////////////////////////////////////////
/*
引用与指针有什么区别?
正确答案: A C D   

A指针是一个实体,而引用仅是个别名
B指针没有 const,引用有 const;
C引用不能为空,指针可以为空;
D“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;
E从内存分配上看:程序为引用变量分配内存区域,而指针不需要分配内存区域
F指针和引用的自增(++)运算,意义一样

1. 指针是一个实体,而引用仅是个别名;
2. 引用使用时无需解引用(*),指针需要解引用;
3. 引用只能在定义时被初始化一次,之后不可变;指针可变;
5. 引用不能为空,指针可以为空;
6. “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;
7. 指针和引用的自增(++)运算意义不一样;
8.从内存分配上看:程序为指针变量分配内存区域,而引用不需要分配内存区域。
*/
////////////////////////////////////////////////////////////////////
/*
关于struct和class,下列说法正确的是()
正确答案: A C   你的答案: A C (正确)

struct的成员默认是public,class的成员默认是private
struct不能继承,class可以继承
struct可以有无参构造函数
struct的成员变量只能是public


1.不同点
                    	struct	class
默认继承权限			public	private
默认数据访问控制		public	private
模板参数			不能定义	可以用于定义模板参数

2.相同点
可以有数据成员,方法,构造函数等。
*/

你可能感兴趣的:(C++小题(十))