天天看點

[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

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

     ~Base1(){}

classBase2: virtual public Base

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

     ~Base2(){}

classDerived : public Base2, public Base1

     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

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

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

class Derived : public Base

     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    )

classSample

   friend long fun (Sample s)

  {

    if (s.x < 2) return 1;

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

  }

    Sample(long a) { x = a; }

    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. 有如下程式:

classTest{

public:

Test(){}

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

intmain(){

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

return0;

執行這個程式輸出星号(#)的個數為(B )。

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

指針的是指向兩個對象并沒有建立對象,而數組是儲存建立的對象 

12. 有如下程式:

classMyClass{

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

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

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

~MyClass(){cout<<4;}

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

obj1=obj2;

}運作時的輸出結果是( A)。

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

複制的時候是調用的=運算符重載

13. 有如下程式:

 #include <iostream>

classpoint

  static int number;

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.父類定義的對象與子類定義的對象在屬性和方法上一定不同

二、  選擇題

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)

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”。

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

     ~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);_______.

三、問答題

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;

    }

        cout << "姓名:" << persons[i].name<<"号碼:" 

<< persons[i].number << endl;

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的作用?

答:防止該頭檔案被重複引用。

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可以用來修飾私有變量

在Objective‐C中,所有執行個體變量預設都是私有的,所有執行個體方法預設都是公有的

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;  

}  

繼續閱讀