C++基礎学習(一)

32043 ワード

1.データ型
1.1基本組み込みタイプ
コンピュータの基本的なデータ型のサイズは、次のコードでわかります.
 1 #include  
 2 #include<string>  
 3 #include   
 4 using namespace std;
 5 
 6 int main()
 7 {
 8 
 9     cout << "char: \t\t" << "" << sizeof(char);
10     cout << "\t   :" << (numeric_limits<char>::max)();
11     cout << "\t\t   :" << (numeric_limits<char>::min)() << endl;
12     
13     cout << "float: \t\t" << "" << sizeof(float);
14     cout << "\t   :" << (numeric_limits<float>::max)();
15     cout << "\t\t   :" << (numeric_limits<float>::min)() << endl;
16     
17     cout << "int: \t\t" << "" << sizeof(int);
18     cout << "\t   :" << (numeric_limits<int>::max)();
19     cout << "\t   :" << (numeric_limits<int>::min)() << endl;
20     
21     cout << "unsigned: \t" << "" << sizeof(unsigned);
22     cout << "\t   :" << (numeric_limits::max)();
23     cout << "\t   :" << (numeric_limits::min)() << endl;
24     
25     cout << "long: \t\t" << "" << sizeof(long);
26     cout << "\t   :" << (numeric_limits<long>::max)();
27     cout << "\t   :" << (numeric_limits<long>::min)() << endl;
28     
29     
30     cout << "double: \t" << "" << sizeof(double);
31     cout << "\t   :" << (numeric_limits<double>::max)();
32     cout << "\t   :" << (numeric_limits<double>::min)() << endl;
33     return 0;
34 }

 
1.2 constとauto
1.const基本紹介
constオブジェクトは、作成後に値を変更できないため、constオブジェクトを初期化する必要があります.コンパイラは、コンパイル中にその変数を使用する場所を対応する値に置き換えます.上記の置き換えを実行するには、コンパイラは変数の初期値を知る必要があります.
1 const int i = get_size();  //       
2 const int j = 3; //       
3 const int k;//   

デフォルトでは、constオブジェクトはファイル内でのみ有効です.複数のファイルに同じ名前のconst変数が表示される場合、異なるファイルで独立した変数がそれぞれ定義されているのと同じです.ファイルで共有したい場合は、1つのファイルでconstを定義し、他の複数のファイルで宣言して使用します.externキーワードを使用して、const変数に対して宣言しても定義してもexternキーワードを追加して、一度だけ定義すればいいです.
しかし、次の例に注意してください.
 1 struct A {
 2     int* ptr;
 3 };
 4 
 5 int main()
 6 {
 7     int k = 5, r = 6;
 8     const A a = { &k };// const          
 9     a.ptr = &r; // !error
10     *a.ptr = 7; // no error
11 }

const修飾aの後、ptr(アドレスを格納する)は変更できないことが要求されるが、実際には*ptr--c++を変更して物理定数行を一定に保つことができ、論理定数性は保証されないことがわかる.
2.クラスのconst変数
 1 struct A {
 2     const int i; //
 3 };
 4 
 5 struct B {
 6     static const int i;//   
 7 };
 8 
 9 const int B::i = 3; //          
10 
11 int main()
12 {
13     A bf = { 1 };
14  
15 }

 
3.トップ/ボトムconstとauto
次に、最上位constと最下位constの例を示します.
 1 /*
 2  3       const:        
 4       const:            
 5     
 6  7     auto       const,     const
 8 */
 9 
10 #include"iostream"
11 using namespace std;
12 int main()
13 {
14     const int i = 19; //i     ,  const
15     const int *p = &i;//p     ,  const(*P     ->           )
16     
17     int z = 18;
18     int *const o = &z;//o     ,  const
19     int t = 13;
20     //o = &t; //  ,  o   ,o     
21 
22     //    
23     cout << typeid(i).name() << endl;//int
24     cout << typeid(p).name() << endl;//int const *
25     cout << typeid(*p).name() << endl;//int 
26     cout << typeid(o).name() << endl << endl;// int *
27 
28     auto a = o;
29     int y = 12;
30     a = &y; // a    ,     o   const。   20  o
31     cout << "*a=" << *a << "\t a  " << typeid(a).name()<< endl;
32 
33     auto b = p;
34     b = &y; //p   const,b    const,b    ,  *b    
35     //*b = 9; //  ,b   const,b           。---》  auto     const
36     cout << "*b=" << *b << "\t b  " << typeid(b).name() << endl;
37 
38 
39     return 0;
40 }

 4. const修飾関数
constはクラス戻り値を修飾することができます(一般的にクラス戻り値はポインタの形式です.戻り値を修飾する関数は意味がありません).関数の後(例えば7行目)に書くもよく、クラスのメンバー変数(mutableキーワード修飾のメンバー変数を除く)を変更可能とする.
 1 struct A {
 2     int i;
 3     mutable int j;
 4 
 5     void f() const{
 6         //this->i++;// error, const               。
 7         this->j++;//      mutable   
 8     }
 9 
10     const int* g() {  
11         int k = 2;
12         return &k;
13     }
14 
15     int *const h() {  
16         int k = 2;
17         return &k;
18     }
19 
20 };
21 
22 int main()
23 {
24     A a = { 1 , 2};
25     a.f();
26 
27     /*
28         a.g()      const int *k   。   const, *k     
29     */
30     const int* k = a.g();
31     //*k = 3; //   
32     k = new int();//   
33 
34 
35     /*
36         a.h()       int *const b   。   const, b     
37     */
38     int* const b = a.h();
39     *b = 3; //   
40     //b = new int();//   
41 }

 
 
 
  
2.vectorタイプ
2.1 vector基本操作
  • v.empty() 
  • v.size()はvectorオブジェクト内の要素の数を返し、戻り値タイプはvectorによって定義されたsize_type決定(vector::size_type)
  • v[n]は、vのn番目の位置の要素の参照
  • を返す.
  • v 1=v 2 v 2 v 1の要素
  • をv 2の要素のコピーで置き換える
  • v 1==v 2エレメント数andエレメント値が同じ場合のみ
  • 2.2アクセス
  • は下付き文字でvectorにアクセスできますが、下付き文字で要素を追加するのではなくpush_back()
  • range-base-forまたはiteratorを使用して
  • を巡回
     1 #include
     2 #include
     3 #include
     4 
     5 int main() {
     6     std::vector<: style="color: #0000ff;">string> v1{ "Tom","Jack","Michael" };
     7     std::vector<int> v2(5, 7);
     8     
     9     for (auto& i : v1) {
    10         std::cout << i << std::endl;
    11     }
    12     
    13     std::cout << "====================" << std::endl;
    14 
    15     for (auto k = v2.begin(); k != v2.end(); ++k) {
    16         std::cout << *k << std::endl;
    17     }
    18 
    19     std::cout << "====================" << std::endl;
    20     
    21     v1.push_back("good dog");
    22     std::vector<: style="color: #0000ff;">string>::iterator iter = v1.begin();
    23     for (; iter != v1.end(); ++iter) {
    24         std::cout << *iter << std::endl;
    25     }
    26     
    27     std::cout << "====================" << std::endl;
    28     
    29     v2[0] = 9;
    30     for (decltype(v2.size()) i = 0; i < v2.size(); ++i) {  // v2.size()         (>=0),    int,          ,            。   36~38 
    31         std::cout << v2[i] << std::endl;
    32     }
    33 
    34     std::cout << "====================" << std::endl;
    35     //     “  ”
    36     /*decltype(v2.size()) i = -1;
    37     if( i > 10)
    38         std::cout << "  " << std::endl;*/ 
    39 
    40 
    41     return 0;
    42 }

     
     
     
    3.反復器
  • では、stringオブジェクトまたはvectorオブジェクトの要素にアクセスするには、下付き演算子を使用することができることを知っています(一部の標準ライブラリタイプには下付き演算子があるため、すべてではありません).しかし、反復器を使用するより一般的なメカニズムもあります.
  • 容器が空の場合、iterを通過することができる.end() != iter.begin()は、例えばstring strオブジェクトがあればif(str.end()!=str.begin()) {.....} strが空でないことを保証するために
  • 反復器を使用する循環体は、反復器が属する容器に要素
  • を添加しないでください.
    3.1反復器とポインタ
    疑問があるかもしれませんが、vectorv 1={1,2,3}であれば、反復器で反復するたびに、反復器は1,2,3の3つの数字のアドレスですか(私たちは*iterで数値を得ることができますから)?答えは正しいかどうか.
     1 #include
     2 #include
     3 #include
     4 
     5 int main() {
     6     std::vector<int> v = { 1 ,2,4 };
     7     for (auto& i : v)  
     8         std::cout << typeid(i).name() << &i <<std::endl;
     9     for (auto k = v.cbegin(); k != v.cend(); ++k)  // cbegin()  const_iterator。begin()  iterator。            
    10         std::cout << typeid(k).name() <<std::endl;
    11     return 0;
    12 }

    range-based-forとiterator-forの出力タイプを比較することができ、8行目&iはvの要素のアドレスを出力します.
    あの反復器はいったい何ですか.ここに説明があります.
      range based for loop vs regular iterator for loop