读书人

[c/c++/OC]高质量的面试题及答案及注脚

发布时间: 2013-10-10 14:14:51 作者: rapoo

[c/c++/OC]高质量的面试题及答案及注解

一、 选择题

C语言:

1. 声明语句为int a[3][4]; 下列表达式中与数组元素a[2][1]等价的是( A )。

A、*(a[2]+1) B、a[9] C、*(a[1]+2) D、*(*(a+2))+1

a[2] <==> *(a+2)是等价的

C两个数反过来了,D、1放进去


2.请问经过表达式a = 5 ? 0 : 1的运算,变量a的最终值是( C )

A.6 B.1 C.0 D.true

前者为真


3. 下面不能正确将字符串“car”进行完整赋值操作的语句是( D )

A、char s[]="car";

B、char s[]={'c','a','r','\0'};

C、char *s="car";

D、char s[]={"car"};

D、应该char s[][]={"car"}

4. 下列程序的输出结果是( D )

main()

{

   char p1[15]=“abcd”,*p2=“ABCD”, str[50]=“xyz”;

   strcpy(str+2,strcat(p1+2,p2+1));

printf(“%s”,str);

}

A、xyabcAB B、abcABz C、 ABabcz D、 xycdBCD

strcat是字符串的拼接,strcpy是字符串的拷贝

5. 设有如下的程序段

char*ptr=NULL;

char str[]="Hello";

ptr=str;

执行完上面的程序段后,*(ptr+5)的值为( B )

A、'o' B、'\0'

C、不确定的值 D、'o'的地址

字符串有‘\0’

6. 假如指针p已经指向某个整型变量x,则(*p)++相当于( B )

A、p++ B、x++ C、*(p++) D、&x++

*p <==>x

7. 有声明及定义如下:

struct student

{

long num; char name[20];

charsex; float score;

}stu1;

structstudent *p=&stu1;

则下面对stu1中的成员num表示错误的是( B )

A、stu1.num B、stu1->num C、(*p).num D、p->num


8. 若有说明:int *p,m=5,n;以下正确的程序段是( D )

A、p=&n; scanf(“%d”,&p);

B、p=&n; scanf(“%d”,*p);

C、scanf(“%d”,&n); *p=n; //p不知道等于多少

D、p=&n; *p=m;

A.B直接写p

9. 下面程序段的运行结果是( C )

{ char *s =”abcde”;

s+=2;

printf(“%d”,s);

}

A、cde B、字符’c’

C、字符’c’的地址 D、无确定的输出结果

10. 以下程序:

#include<stdio.h>

void main()

{

char grade;

scanf(”%c”,&grade);

switch(grade)

case ’A’: printf(”优秀”);

case ’B’: printf(”良好”);

default:printf(”中等”);

}

如果输入’A’,问输出什么( C )

A、优秀 B、优秀良好 C、优秀良好中等 D、都不是

缺少break;

修改:如果将default移动到最上面还是会往后面继续执行


C++:

1. 下列关于this指针的说法正确的是( B )

A)this指针存在于每个函数之中

B)在类的非静态函数中this指针指向调用该函数的对象

C)this指针是指向虚函数表的指针

D)this指针是指向类的函数成员的指针



2. 在下列关于C++函数的叙述中,正确的是( C )

A)每个函数至少要有一个参数 B)每个函数都必须返回一个值

C)函数在被调用之前必须先声明 D)函数不能自己调用自己

3. 下列情况中,哪一种情况不会调用拷贝构造函数 ( B )

A)用派生类的对象去初始化基类对象时

B)将类的一个对象赋值给该类的另一个对象时 //不会初始化或者创建新的

C)函数的形参是类的对象,调用函数进行形参和实参结合时

D)函数的返回值是类的对象,函数执行返回调用者时

拷贝构造函数只有在拷贝构造新的对象的时候才会调用,如果是先存在的的对象,然后进行复制,这时是不会调用拷贝构造函数的。

例如:object obj1;

object obj2 = obj1; 这就会调用拷贝构造函数

如果是 object obj2;obj2 = obj1;这时只会调用=号的运算符重载,不会调用拷贝构造函数

4. 下面的程序段的运行结果为( D )

charstr[] = "job", *p = str;

cout<< *(p+2) << endl;

A)98 B)无输出结果 C)字符’b’的地址 D)字符’b’

*(p+2) <==>p[2]

5. 下面程序的输出结果是( C )

#include<iostream>

usingnamespace std;

classBase

{

public:

Base(inti) { cout << i; }

~Base() { }

};

classBase1: virtual public Base

{

public:

Base1(inti, int j=0) : Base(j) { cout << i; }

~Base1(){}

};

classBase2: virtual public Base

{

public:

Base2(inti, int j=0) : Base(j) { cout << i; }

~Base2(){}

};

classDerived : public Base2, public Base1

{

public:

Derived(inta, int b, int c, int d) : mem1(a), mem2(b), Base1(c),

Base2(d),Base(a)

{ cout << b; }

private:

Base2mem2;

Base1mem1;

};

voidmain() { Derived objD (1, 2, 3, 4); }

A)134122 B)123412 C)14302012 D)143212

先Base(a),虚基类只构建一次,防止重复构建


6. 下面程序的输出结果是( C )

#include <iostream>

using namespace std;

class Base

{

public:

virtual void f() { cout << “f0+”; }

void g() { cout << “g0+”; }

};

class Derived : public Base

{

public:

void f() { cout << “f+”; }

void g() { cout << “g+”; }

};

void main() { Derived d; Base *p = &d; p->f(); p->g(); }

A)f+g+ B)f0+g+ C)f+g0+ D)f0+g0+

首先是在base类中去找,如果有virtual的话看子类里面有没有同名方法,如果有就用子类的,如果方法没有virtual,那就用父类的这个方法

7. 下面程序的输出结果是( C )

#include<iostream>

usingnamespace std;

classSample

{

friend long fun (Sample s)

{

if (s.x < 2) return 1;

return s.x * fun(Sample(s.x-1));

}

public:

Sample(long a) { x = a; }

private:

longx;

};

voidmain()

{

int sum = 0;

for (int i=0; i<4; i++)

{

sum += fun(Sample(i));

}

cout << sum;

}A)12 B)16 C)10 D)34

1+1+2+6=10


8. 下列关于虚基类的描述中,错误的是(C)

A. 使用虚基类可以消除由多继承产生的二义性

B. 构造派生类对象时,虚基类的构造函数只被调用一次

C. 声明 class B:virtual public A 说明类B为虚基类

D. 建立派生类对象时,首先调用虚基类的构造函数



9. 有下类定义

Class A{

Char*a;

Public:

A():a(0){}

A(char*aa) {//把aa所指字符串拷贝到a所指向的存储空间

A=___________________;

Strcpy(a,aa);

~A(){delete [] a;}

};

正确的选择是(A)

A. new char[strlen(aa)+1] B.char[strlen(aa)+1]

C.char[strlen(aa)] D. newchar[sizeof(aa)+1]

new和delete会调用构造和析构函数

malloc和free只会根据大小来开辟空间

10. 假定AA为一个类,inta()为该类的一个成员函数,若该成员函数在类定义体外定义,则函数头为( A )。

A)int AA::a( ) B) int AA:a()

C)AA::a() D) AA::int a()

11. 有如下程序:

#include<iostream>

usingnamespace std;

classTest{

public:

Test(){}

~Test(){cout<<'#';}

};

intmain(){

Test temp[2], *pTemp[2];

return0;

}

执行这个程序输出星号(#)的个数为(B )。

A)1 B)2 C)3 D)4

指针的是指向两个对象并没有创建对象,而数组是保存创建的对象


12. 有如下程序:

#include<iostream>

usingnamespace std;

classMyClass{

public:

MyClass(inti=0){cout<<1;}

MyClass(constMyClass&x){cout<<2;}

MyClass&operator=(const MyClass&x){cout<<3; return *this;}

~MyClass(){cout<<4;}

};

intmain(){

MyClassobj1(1),obj2(2),obj3(obj1);

obj1=obj2;

return0;

}运行时的输出结果是( A)。

A)1123444 B)11114444 C)121444 D)11314444

复制的时候是调用的=运算符重载


13. 有如下程序:

#include <iostream>

usingnamespace std;

classpoint

{

public:

static int number;

public:

point(){ number++;}

~point(){number--;}

};

int point::number=0;

void main()

{ point*ptr;

pointA,B;

{

point*ptr_point=new point[3];

ptr=ptr_point;

}

point C;

delete[]ptr;

cout<<point::number;

}

程序结果为(A)

A)3 B)4 C)6 D)7



OC:

1.NSString *aa = @"Simple Audio Engine";NSLog(@"%@",[aa substringToIndex:8]);会输出( C )?

A.Simple Au B.A C.Simple A D.u

这里 还是从0开始,但是截取到它之前

如果是substringFromIndex这是包括当前这个的


2.多态的定义是( B )

A._来自不同对象可以接受同一消息的能力

B.来自不同类的对象可以接受同一消息的能力

C.来自不同的类可以接受同一消息的能力

D.以上都不是

3.已知 char s[20],*p=s,则在下列语句中,错误的是( B )。

A.p=s+5 B.s=p+s

C.s[2]=p[4] D.*p=s[0]

4. 以32位C++程序,请计算sizeof的值 ( C )

void Func ( char str[100] ) { sizeof( str ) = ? }

void*p = malloc( 100 );

sizeof( p ) = ?;

A.8 100 B. 4 100

C.4 4 C. 100 100

5.@[@"a",@"b"];该类型是( C )

A._字符串对象 B.字典对象 C.数组对象 D.集合对象

6. NSString *str =@"a123"; NSLog(@"%@",(str ==@"123")?@"yes":@"no");会输出(B )

A. yes B. no C.不确定 D.错误

7.NSString *str =@"a123";NSLog(@"%d",[str intValue]);会输出( A )

A.0 B.123 C.123a D.不确定

8.int a = 0;-+a--; NSLog(@"%d",a);会输出( B )

A.0 B.-1 C.1 D.不确定

9. Person *person =[[Person alloc]initWithObjects:@"11", nil];

[person release];

NSLog(@"%d",person.retainCount);会输出( C )

A.0 B.-1 C.1 D.错误,直接崩溃

虽然释放了,但是在执行下一段代码的时候还没来得及释放,所以还是1,如果中间还有代码,就会被释放了,在执行retaincount就会选D


10. 以下关于子类和父类的叙述中,正确的是( A )

A.代码中使用父类对象的地方,都可以使用子类对象进行替换

B.代码中使用子类对象的地方,都可以使用父类对象进行替换

C.父类定义的对象与子类定义的对象在属性和方法上一定相同

D.父类定义的对象与子类定义的对象在属性和方法上一定不同

二、 选择题

C语言:

1. a是整型变量,则执行表达式a=25/3%3后a的值为 2

2. 执行下列语句:int a=1, b=2; a=a+b; b=a-b; a=a-b; printf("%d , %d \n", a,b );的输出结果分别是 2,1

3. inta=24; printf("%o ", a );输出结果是 30

4. 当a=3,b=2,c=1时,表达式f=a>b>c的值是 : 0 。先计算a>b 然后是1,在1>c,结果是0

5.若有定义:inta[2][3]={2,4,6,8,10,12};则*(&a[0][0]+2*2+1)的值是: 12


C++:

1.用递归法求从1到n的立方和:

f(1)=1 (n=1)

f(n)=f(n-1)+n3 (n>1)

#include<iostream>

using namespace std;

int f(int);

int main(){

int n,s;

cout<<"input the number n:";

cin>>n;

s= f(n) ;

cout<<"The result is"<<s<<endl;

return 0;

}

int f(int n){ //递归法求立方和函数

if ( n==1 ) return 1;

else return ( f(n-1)+n*n*n );

}

2. 请将下列程序补充完整,使得输出结果为“Destructor Derived DestructorBase”。

#include <iostream>

using namespace std;

class Base

{

public:

virtual ~Base () { cout << “DestructorBase”<< endl; }

};

class Derived : public Base

{

public:

~Derived(){ cout << “Destructor Derived”<< endl; }

};

void main ()

{

Base*pBase = new Derived;

delete pBase ;

}

OC:

1、变量分为全局和局部两种,_____局部变量________变量没有赋初值时,其值是不确定的。

2、使用const语句定义一个标识符常量时,则必须对它同时进行____.初始化._______。

3、objective-c中定义静态方法使用是什么修饰符____+____.

4、objective-c中是否有私有方法_____否___(是/否),它可以用什么方法来代替____类别.___. //只有静态方法和实例方法

5、objective-c 对象的创建: 类名 对象指针=[[类名 alloc] 初始化方法];

6.void GetMemory(char *p, int num)

{

p = (char *)malloc(sizeof(char) * num);

}

void Test(void)

{

char *str = NULL;

GetMemory(str, 100);

strcpy(str, "hello");

}

运行结果以及现象:______ coredump_______.

修改:______GetMemory(&str,100);_______.

三、问答题

C语言:

1.建立一个结构体数组,有10个元素。成员有两个,一个是char name[30],一个是号码int number.每个人的姓名可以通过各种方式输入。每个人的号码通过随机数获得(范围是1~1000,真随机,不能每次运行结果都一样),并打印。

struct Person

{

char name[30];

int number;

};

int main(int argc,constchar * argv[])

{

srand(time(NULL));

struct Person persons[10];

for (int i =0; i <sizeof(persons)/sizeof(struct Person); i++) {

persons[i].number = rand()%1000+1;

cout<< "输入第" << i <<"个姓名:" << endl;

cin >> persons[i].name;

}

for (int i =0; i <sizeof(persons)/sizeof(struct Person); i++) {

cout << "姓名:" << persons[i].name<<"号码:" << persons[i].number << endl;

}

}

C++:

1.编写类String的构造函数、析构函数和赋值函数,已知类String的原型为:

class String

{

 public:

  String(const char *str = NULL); // 普通构造函数

  String(const String &other); // 拷贝构造函数

  ~ String(void); // 析构函数

  String & operate =(const String &other); // 赋值函数

 private:

  char *m_data; // 用于保存字符串

};

//普通构造函数

String::String(const char *str)

{

 if(str==NULL)

 {

  m_data = new char[1]; // 对空字符串自动申请存放结束标志'\0'的空

  *m_data = '\0';//加分点:对m_data加NULL判断

 }

 else

 {

  int length = strlen(str);

  m_data = new char[length+1]; // 若能加NULL判断则更好

  strcpy(m_data,str);

 }

}

// String的析构函数

String::~String(void)

{

 delete [] m_data; // 或deletem_data;

}

//拷贝构造函数

String::String(const String &other) // 输入参数为const型

{

 int length = strlen(other.m_data);

 m_data = new char[length+1];    //对m_data加NULL 判断

 strcpy(m_data,other.m_data);

}

//赋值函数

String & String::operate =(const String &other) //输入参数为const型

{

 if(this == &other)  return *this;//检查自赋值

 delete [] m_data;     //释放原有的内存资源

 int length = strlen(other.m_data );

 m_data = new char[length+1]; //对m_data加NULL 判断

 strcpy( m_data,other.m_data );

 return *this;        //返回本对象的引用

}

2.分别给出BOOL,int,float,指针变量与“零值”比较的 if 语句(假设变量名为var)

解答:

   BOOL型变量:if(!var)

   int型变量:if(var==0)

   float型变量:

   const float EPSINON =0.00001;

   if ((x >= - EPSINON)&& (x <=EPSINON)

   指针变量:  if(var==NULL)

3.New,delete 与malloc ,free 的联系与区别?

答案:都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,new 会自动调用对象的构造函数。delete 会调用对象的析构函数,而free 不会调用对象的析构函数.

4.将“引用”作为函数参数有哪些特点?

(1)传递引用给函数与传递指针的效果是一样的。这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标对象(在主调函数中)的操作。

(2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数。因此,当参数传递的数据较大时,用引用比用一般变量传递参数的效率和所占空间都好。

(3)使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。

5. .h头文件中的ifndef/define/endif的作用?

答:防止该头文件被重复引用。

OC:

1. 定义属性时,什么情况使用copy、assign、retain?

答:

assign用于简单数据类型,如NSInteger,double,bool,

retain和copy用于对象,

copy用于当a指向一个对象,b也想指向同样的对象的时候,如果用assign,a如果释放,再调用b会crash,如果用copy的方式,a和b各自有自己的内存,就可以解决这个问题。

retain 会使计数器加一,也可以解决assign的问题。

另外:atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。

加了atomic,setter函数会变成下面这样:

if (property !=newValue) {

[property release];

property = [newValueretain];

}

2. #import和#include的区别,@class代表什么?

答:

@class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文件中还是需要使用#import,而#import比起#include的好处就是不会引起重复包含

3. Object-C有私有方法吗?私有变量呢?

答:

objective-c 类里面的方法只有两种,静态方法和实例方法.这似乎就不是完整的面向对象了,按照OO的原则就是一个对象只暴露有用的东西.如果没有了私有方法的话,对于一些小范围的代码重用就不那么顺手了.在类里面声名一个私有方法

@interface Controller: NSObject { NSString *something; }

+(void)thisIsAStaticMethod;

(void)thisIsAnInstanceMethod;

@end

@interface Controller(private)

(void)thisIsAPrivateMethod;@end

@private可以用来修饰私有变量
在ObjectiveC中,所有实例变量默认都是私有的,所有实例方法默认都是公有的

4. 阐述一下 person.money=100; 和 int num = person.money 的区别

答:前者调用的是setter方法,而后者调用的是getter方法

5. 定义一个类实现NSCoding 和 NSCopying 并实现

答:

- (void) encodeWithCoder:(NSCoder*)encoder {

[encoder encodeObject:_title forKey:kTitleKey];

[encoder encodeFloat:_rating forKey:kRatingKey];

}

-(id)initWithCoder:(NSCoder *)decoder {

NSString *title = [decoderdecodeObjectForKey:kTitleKey];

float rating = [decoderdecodeFloatForKey:kRatingKey];

return [self initWithTitle:titlerating:rating];

}

-(id)copyWithZone:(NSZone *)zone

{

Fraction *newFract = [[Fraction allocWithZone:zone] init];

[newFract setTo:a over:b];

return newFract;

}


读书人网 >C++

热点推荐