C++面试题(四)

来源:互联网 发布:登录阿里云 编辑:程序博客网 时间:2024/04/29 10:25

const相关: 
1.总结const的应用和作用? 
答:(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了; 
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const; 
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值; 
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量; 
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。 
2.说明define和const在语法和含义上有什么不同? 
答:(1) #define是C语法中定义符号变量的方法,符号常量只是用来表达一个值,在编译阶段符号就被值替换了,它没有类型; 
(2) Const是C++语法中定义常变量的方法,常变量具有变量特性,它具有类型,内存中存在以它命名的存储单元,可以用sizeof测出长度 
3.const 符号常量; 
(1)const char *p 
(2)char const *p 
(3)char * const p 
说明上面三种描述的区别 . 
答:如果 const 位于星号的左侧,则 const 就是用来修饰指针所指向的变量,即指针指向为常量; 
如果 const 位于星号的右侧, const 就是修饰指针本身,即指针本身是常量。 
(1)const char *p 
一个指向 char 类型的 const 对象指针, p 不是常量 , 我们可以修改 p 的值,使其指向不同的 char ,但是不能改变它指向非 char 对象,如: 
const char *p; 
char c1=’a’; 
char c2=’b’; 
p=&c1;//ok 
p=&c2;//ok 
*p=c1;//error 
(3)char * const p 
此时 *p 可以修改,而 p 不能修改。 
(4)const char * const 
这种是地址及指向对象都不能修改。 
4.const 有什么用途?(请至少说明两种) 
答:(1)可以定义 const 常量,(2)const 可以修饰函数的参数、返回值,甚至函数的定义体。被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

static相关: 
总结static的应用和作用? 
答:(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值; 
(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问; 
(3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内; 
(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝; 
(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

联合。结构体,类相关 
1、设有以下说明和定义:

typedef union  {        long i;      int k[5];    char c;  } DATE;    struct data  {       int cat;     DATE cow;        double dog; } too;     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

则语句 printf(“%d”,sizeof(struct data)+sizeof(max));的执行结果是:52 
考点:区别struct与union.(一般假定在32位机器上) 
答:DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20. data是一个struct, 每个变量分开占用空间. 依次为int4 + DATE20 + double8 = 32. 所以结果是 20 + 32 = 52. 当然…在某些16位编辑器下, int可能是2字节,那么结果是 int2 + DATE10 + double8 = 20

struct(结构) 和 union(联合)的区别? 
1)结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在(不同成员的存放地址不同)。 
2) 对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。

class 和 struct 的区别? 
答:struct 的成员默认是公有的,而类的成员默认是私有的 
结构体在默认情况下的成员都是public的,而类在默认情况下的成员是private的。结构体和类都必须使用new创建, 
struct保证成员按照声明顺序在内存在存储,而类不保证。

下面关于“联合”的题目的输出? 
a)

#includeunion{    int i;    char x[2];}a;void main(){    a.x[0] = 10;    a.x[1] = 1;    printf(“%d”,a.i);}//答案:266 (低位低地址,高位高地址,内存占用情况是Ox010A)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

b)

main(){    union{        int i;        struct{            char first;            char second;        }half;    }number;    number.i=0×4241;    printf(“%c%c ”, number.half.first, mumber.half.second);    number.half.first=’a';    number.half.second=’b';    printf(“%x ”, number.i);    getch();}//答案: AB (0×41对应’A',是低位;Ox42对应’B',是高位)//6261 (number.i和number.half共用一块地址空间)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

关联、聚合(Aggregation)以及组合(Composition)的区别? 
涉及到UML中的一些概念:关联是表示两个类的一般性联系,比如“学生”和“老师”就是一种关联关系;聚合表示has-a的关系,是一种相对松散的关系,聚合类不需要对被聚合类负责,如下图所示,用空的菱形表示聚合关系: 
从实现的角度讲,聚合可以表示为: 
class A {…} class B { A* a; …..} 
而组合表示contains-a的关系,关联性强于聚合:组合类与被组合类有相同的生命周期,组合类要对被组合类负责,采用实心的菱形表示组合关系: 
实现的形式是: 
class A{…} class B{ A a; …}

class MyStruct{       double ddal;        char dda;        int type;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。 
其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的始地址偏移量必须为该变量的类型占用字节数的倍数,如Char偏移量为sizeof(char)即1的倍数,先为第一个成员dda1分配空间,其起始地址跟结构的起始地址相同,偏移量0刚好为sizeof(double)的倍数,该成员变量占用sizeof(double)=8个字节;接下来为第二个成员dda分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数,占sizeof(char)=1字节为第三个成员type分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是sizeof(int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自动填充3个字节 
这时下一个可以分配的地址对于结构的起始地址的偏移量是12,刚好是sizeof(int)=4的倍数, 
所以把type存放在偏移量为12的地方,占 用sizeof(int)=4个字节。总的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。

sizeof()相关: 
记住一点,C++无法知道指针所指对象的大小,指针的大小永远为4字节

char a[]=”Hello World!”char *p=a;count sizeof(a) end; //12字节count sizeof(p) endl; //4字节char s1[] = ""    //1char *q = NULL    //4void *r = malloc(100)  //4//strlen函数char s1[10] = {'m',o'','b','i','l'}char s2[20] = {'A','N','S','I','\0','C','+','+'}char s3[6] = {'I','D','O','C','+','+'}//strlen(s1) = 5//strlen(s2) = 4//strlen(s3) = 不确定//s2[8] = ‘\0’
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

而且,在函数中,数组参数退化为指针,所以下面的内容永远输出为4

void fun(char a[1000]){count sizeof(a) endl; //输出4而不是1000}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

以下为Windows NT 下的32 位C++程序,请计算sizeof 的值(10 分)

void Func ( char str[100]){    //请计算    sizeof( str ) = 42 分)}char str[] = “Hello” ;char *p = str ;int n = 10;//请计算sizeof (str ) = 62 分)sizeof ( p ) = 42 分)sizeof ( n ) = 42 分)void *p = malloc( 100 );//请计算sizeof ( p ) = 42 分)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

引用相关: 
1.引用和指针有什么区别? 
答:引用必须初始化,指针则不必;引用初始化以后不能改变,指针可以改变其指向的对象; 
不存在指向空值的引用,但存在指向控制的指针; 
引用是某个对象的别名,主要用来描述函数和参数和返回值。而指针与一般的变量是一样的,会在内存中开辟一块内存。 
如果函数的参数或返回值是类的对象的话,采用引用可以提高程序的效率。

2.将“引用”作为函数参数有哪些特点 
答:(1)传递引用给函数与传递指针的效果是一样的,这时,被调函数的形参就成为原来主调函数的实参变量或者 
对象的一个别名来使用,所以在被调函数中形参的操作就是对相应的目标对象的操作 
(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作,当参数数据较大时,引用 
传递参数的效率和所占空间都好 
(3)如果使用指针要分配内存单元,需要重复使用“*指针变量名”形式进行计算,容易出错且阅读性较差。

各类零值比较: 
分别写出BOOL,int, float, 指针类型的变量 a 与 “零值”的比较语句

  BOOL: if(!aor   if(a)  int : if( 0 == a)  float : const EXPRESSION EXP = 0.000001;  if(a < EXP && a > -EXP)  pointer:     if(a != NULL) or  if(a == NULL)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
0 0