C/C++求職宝典21個の重点ノート(筆記試験の面接点をよく試験する)

18427 ワード

これは私が前に仕事を探すつもりで《C/C++求職宝典》の本を読んで作ったノートで、すべていくつかの筆記試験の面接の中でよく試験する重点の難点の問題で、しかし比較的に基礎で、初心者に適しています.
 
1. char c = '\72'; の72は1文字、72は8進数、ASCIIコード文字":".
2.10*a++ではaが乗算を行ってから自増する(筆記試験ではこのような演算子の優先度が混同されやすい出力の問題がよく好まれる).
3.constとstaticの役割
よくある質問ですが、以下に詳細な参考答案を示します.
staticキーワード:
1)関数内static変数の作用範囲は関数体である.auto変数とは異なります.この変数のメモリは一度だけ割り当てられます.したがって、その値は、次回の呼び出し時に前回の値を維持します.
2)モジュール内のstaticグローバル変数は、モジュール内のすべての関数によってアクセスすることができる.ただし、モジュール外の他の関数にはアクセスできません.
3)モジュール内のstatic関数は、このモジュール内の他の関数によってのみ呼び出される.この関数の使用範囲は、宣言されたモジュールに制限されます.
4)クラス内のstaticメンバー変数はクラス全体に属し、クラスのすべてのオブジェクトに対して1つのコピーしかありません.
5)クラス内のstaticメンバー関数はクラス全体の所有であり、この関数はthisポインタを受け入れないため、クラスのstaticメンバー変数にのみアクセスできます.
constキーワード:
1)変数が変更されるのを阻止するにはconstキーワードを使用します.このconst変数を定義する場合、通常は初期化する必要があります.これからはそれを変える機会がないからです.
2)ポインタについては,ポインタ自体をconstとしてもよいし,ポインタが指す数をconstとしてもよい.または両方がconstです.
3)関数の宣言では、constは入力パラメータであることを示すパラメータを修飾することができる.関数内で値を変更することはできません.
4)クラスのメンバー関数の場合、constタイプとして指定します.定数関数であることを示します.クラスのメンバー変数は変更できません.
5)クラスのメンバー関数では、constタイプの戻り値を指定する必要がある場合があります.戻り値が「左」でないようにします.
 
4.sizeofは関数ではなく演算子なので、変数を計算するのにかかる空間が大きい場合は括弧を省略することができますが、計算タイプが大きい場合は括弧を省略することはできません.例えばint i=0です.sizeof intはエラーです.
 
5.1,2,...,nの無秩序配列があり,並べ替えアルゴリズムを求め,時間的複雑度O(n),空間的複雑度O(1)を要求し,交換を用い,一度に2つの数しか交換できない.
#include <stdio.h>
int main() {
    int a[] = {10, 6, 9, 5, 2, 8, 4, 7, 1, 3};
    int i, tmp;
    int len = sizeof(a) / sizeof(a[0]);
    for(i = 0; i < len;) {
        tmp = a[a[i] - 1];
        a[a[i] - 1] = a[i];
        a[i] = tmp;
        if(a[i] == i + 1) i++;
    }
    for(i = 0; i < len; ++i)
        printf("%d ", a[i]);
    printf("
"); return 0; }

 
6.誤解しやすい:int a[5]の場合、aと&aは同じアドレスであるため、等価である.
Aと&aは異なることに注意してください.両者のアドレスは同じですが、意味が違います.&aは配列全体のオブジェクトのヘッダアドレスで、aは配列ヘッダアドレス、すなわちa[0]のアドレスで、aのタイプはint[5]、a[0]のタイプはintです.そのため、&a+1はaのアドレス値にsizeof(int)*5を加え、つまりa[5]、次のオブジェクトのアドレスは、すでに境界を越えています.一方、a+1は、aのアドレスにsizeof(int)、すなわちa[1]のアドレスを付加することに相当する.
 
7.小数を整数部と小数部に分解する方法
ヘッダファイルのライブラリ関数modfを使用することを忘れないでください.次は関数のプロトタイプです(実用的なライブラリ関数を覚えて、自分で書き直さないでください).
double modf(double num, double *i); //  num       *i     (     )

 
8.関数リロード判断の根拠とすることができるのは、パラメータ個数、パラメータタイプ、const修飾子;
重荷判定の根拠にならないものとしては、返却タイプがあります.
 
9.プログラム出力問題:
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int *p = &(a + 1)[3];
printf("%d
", *p);

出力:5
説明:a+1はaの2番目の要素を指すため、[3]はさらに3つの要素を後ろに移動することを示す.
 
10.プログラム出力問題:
 char str1[] = "abc";
 char str2[] = "abc";
 const char str3[] = "abc";
 const char str4[] = "abc";
 const char *str5 = "abc";
 const char *str6 = "abc";
 char *str7 = "abc";
 char *str8 = "abc";
 cout << (str1 == str2) << endl;
 cout << (str3 == str4) << endl;
 cout << (str5 == str6) << endl;
 cout << (str7 == str8) << endl;

出力:0 0 1
説明:str 1~str 8を出力するアドレスは:
0x23aa80
0x23aa70
0x23aa60
0x23aa50
0x23aa48
0x23aa40
0x23aa38
0x23aa30
出力str 1~str 8の内容「abc」の記憶アドレスは、
0x23aa80
0x23aa70
0x23aa60
0x23aa50
0x100403030
0x100403030
0x100403030
0x100403030
str 1~str 4の内容はスタック上に存在し,アドレスはそれぞれ異なり,str 5~str 8の内容はいずれも定数領域に格納されているため,アドレスは同じであることが分かった.
 
注意:
char *str = "abc";
printf("%p
", str1); cout << &str1 << endl;

上には文字列「abc」のアドレスが印刷され、下にはstr 1変数のアドレスが印刷されます.
 
11.Cの構造体とC++の構造体の違い
(1)Cの構造体には関数の存在は許されず,C++には内部メンバー関数が許され,その関数が虚関数であることが許される.したがって,Cの構造体には構造関数,構造関数,およびthisポインタはない.
(2)Cの構造体の内部メンバー変数へのアクセスはpublicのみであり,C++はpublic,protected,privateの3種類を許可する.
(3)C言語の構造体は継承できず,C++の構造体は他の構造体やクラスから継承できる.
 
以上は表面的な違いであり、実際の違いはプロセス向けとオブジェクト向けのプログラミング構想の違いである.
Cの構造体はデータ変数を包むだけで,アルゴリズムには関与しない.
C++は、データ変数とこれらのデータ変数に関するアルゴリズムをカプセル化し、これらのデータとクラスに異なるアクセス権を与える.
C言語にはクラスの概念はないが,C言語は構造内に関数ポインタを作成することでオブジェクト指向思想を実現できる.
 
12.クラスで定数メンバーを定義して初期化する方法
解答:constメンバーは、初期化リストでのみ初期化できます.次のようにします.
class CBook {
public:
    const double m_price;
    CBook() :m_price(8.8) { }
};

次の方法は間違っています.
class CBook {
public:
    const double m_price;
    CBook() {
        m_price = 8.8;
    }
};

次の方法は間違っていませんが、warningがあります.お勧めしません.
class CBook {
public:
    const double m_price = 8.8; //        const     
    CBook() { }
};

 
13.クラスのメンバー関数を定義するときにmutableキーワードを使用する役割は何ですか?
解答:constメソッドでオブジェクトのデータメンバーを変更する必要がある場合は、データメンバーの前にmutableキーワードを使用してコンパイルエラーを防止できます.例は次のとおりです.
class CBook {
public:
    mutable double m_price; //         
    CBook(double price) :m_price(price) { }
    double getPrice() const; //   const  
};
double CBook::getPrice() const {
    m_price = 9.8;
    return m_price;
}

 
14.コンストラクション関数、コピーコンストラクション関数、コンストラクション関数の呼び出し点と順序の問題.次の例の出力は何ですか.
class CBook {
public:
    CBook() {
        cout << "constructor is called.
"; } ~CBook() { cout << "destructor is called.
"; } }; void invoke(CBook book) { // , & , & , // , , cout << "invoke is called.
"; } int main() { CBook c; invoke(c); }

解答:コピーコンストラクション関数は、オブジェクトが関数パラメータとして渡されるときに呼び出され、オブジェクト参照ではなくオブジェクトインスタンスであることに注意してください.したがって、この問題の出力は次のとおりです.
constructor is called.
invoke is called.
destructor is called. //  invoke                        ,             
destructor is called.

 
引用:コピーコンストラクション関数はどのような場合に呼び出されますか?
(1)関数のパラメータはクラスオブジェクトであり、パラメータは値伝達方式を採用する.
(2)クラスオブジェクトを関数の戻り値とする.
 
15.C++のexplicitキーワードはどのような役割を果たしますか?
解答:コンストラクション関数を変換関数として使用することを禁止します.すなわち、コンストラクション関数が自動的に暗黙的なタイプ変換を行うことを禁止します.
例えばCBookには1つのパラメータm_しかありませんpriceは,オブジェクトを構築する際にCBook c=9.8のような暗黙的な変換を用いることができ,explicitを用いてこの変換の発生を防止する.
 
16.C++では、あるコンストラクション関数の作成プロセスが決定された場合、そのコンストラクション関数で他のリロードされたコンストラクション関数が呼び出された場合、他のコンストラクション関数の初期化リスト部分コードは実行されず、関数体コードが実行され、通常の関数に劣化します.例は次のとおりです.
class CBook {
public:
    double m_price;
    CBook() {
        CBook(8.8);
    }
    CBook(double price) : m_price(price) { }
};
int main() {
    CBook c;
    cout << c.m_price << endl; //            8.8
}

 
17.静的データ・メンバーは、グローバル領域でのみ初期化でき、クラスではできません(コンストラクション関数では初期化できません)、静的データ・メンバーはオブジェクトに関係しないため、クラス・アクセス制限子に制限されません.
例は次のとおりです.
class CBook {
public:
    static double m_price;
};
double CBook::m_price = 8.8; //        ,   CBook           

 
18.C++でリロードできる演算子:new/delete、new[]/delete[]、++など.
リロードできない演算子:、.、::、?:、sizeof、typeid、.、**、演算子の優先度は変更できません.
 
引用:++と–をリロードするとき、接頭辞++と接尾辞++をどのように区別しますか?
たとえば、コンパイラが++a(先に増加)を見た場合、operator+(a)が呼び出されます.
しかし、コンパイラがa++を見るとoperator+(a,int)が呼び出されます.すなわち,コンパイラは異なる関数を呼び出すことによってこの2つの形式を区別する.
 
19.C++の多態性は静的多態と動的多態に分けられる.
静的多態性:コンパイル中にどの操作を具体的に実行するかを決定し、主に関数リロードと演算子リロードによって実現される.
動的多様性:実行時にどの操作を具体的に実行するかを決定し、主に虚関数によって実現します.
 
20.虚関数の原理試験点、例えば次のプログラムの出力は何ですか.
class A {
public:
    virtual void funa();
    virtual void funb();
    void func();
    static void fund();
    static int si;
private:
    int i;
    char c;
};

問:sizeof(A)=?
回答:
クラスが使用するメモリ容量については、次の点に注意してください.
(1)クラスに虚関数が含まれている場合、コンパイラはクラスのために虚関数テーブルを構築する必要があります.クラスにはこの虚関数テーブルを指すポインタのヘッダアドレスを格納する必要があります.いくつかの虚関数があっても、1枚のテーブルしか作成されません.すべての虚関数アドレスはこのテーブルに存在し、クラスには1つのポインタが虚関数テーブルのヘッダアドレスを指すだけでよいことに注意してください.
(2)クラス内の静的メンバーは、sizeof計算の空間に計上されないクラスのすべてのインスタンスによって共有される
(3)クラス内の一般関数または静的一般関数はスタックに格納され,sizeof計算の空間に計上されない
(4)クラスメンバーがバイト整列でスペースを割り当てる
答え:12(32ビットシステム)または16(64ビットシステム)
 
21.虚継承の役割は何ですか.
マルチ継承では、子クラスに複数の親が同時に存在する場合があります.これらの親に同じ親がある場合(先祖クラス)では、サブクラスに複数の先祖クラスが存在します.たとえば、クラスBとクラスCの両方がクラスAを継承し、クラスDがBとCから派生した場合、クラスDには2つのAが存在します.複数の継承中子クラスに重複する親クラスが存在しないように、親継承時に虚関数、すなわちクラスBとクラスCがクラスAを継承する際にvirtualキーワードを使用します.たとえば、次のようになります.
class B : virtual public A
class C : virtual public A
注:マルチ継承は複雑な問題が多いので、慎重に使用してください.