[C ++シリーズノート] 01 C ++およびC

C ++およびC

こんにちは世界!

#include <iostream>
using namespace std;
int main() {
    
    
    cout << "Hello world!" << endl;
    system("pause");
    return EXIT_SUCCESS;
}

名前空間(スコープ)

  • ダブルコロン::スコープ演算子{$namespace}::

    • 名前空間を記述しない場合は、グローバル名前空間を使用してください

      ::function(params);
      
  • 名前空間:グローバル名前空間で定義

    namespace {
          
          $namespace}{
          
          
    	// ...函数 类 结构体 变量...
    }
    
  • 名前空間はネストできます

    namespace {
          
          $namespace}{
          
          
    	// ...函数 类 结构体 变量...
        namespace {
          
          $namespace}{
          
          
    	// ...函数 类 结构体 变量...
    	}
    }
    
  • 複数の同一の名前空間が上書きされずに蓄積されます

    namespace {
          
          $namespace}{
          
          
        int a;
        // ...
    }
    namespace {
          
          $namespace}{
          
          
        int b;
        // ...
    }
    // a b 均在 {$namespace} 中
    
  • 名前のない名前空間は、現在のファイルでのみ使用できます

    namespace {
          
          
        int a;
        // 相当于 static int a;
        // ...
    }
    
  • 名前空間エイリアス

    namespace anotherName = {
          
          $namespace};
    

C→C ++の類似点と相違点

  • 変数検出

    • c成功cpp失敗
    int a;
    int a = 1;
    // c success 
    // cpp failure
    
    • cppの成功
    int a = 1;
    // cpp success
    
  • 機能検出

    • c成功cpp失敗
    int function(p){
          
          // 形参类型
        // 返回值
    }
    // c success 
    // cpp failure
    
    • cppの成功
    int function(int p){
          
          // 形参类型
        return 0;// 返回值
    }
    // cpp success
    
  • 関数呼び出しの検出

    • c成功cpp失敗
    int function(p){
          
          
        
    }
    int main(){
          
          
    	function(1, 2, 3);// 参数数量
    }
    // c success 
    // cpp failure
    
    • cppの成功
    int function(int p){
          
          
        return 0;
    }
    int main(){
          
          
    	function(1, 2);// 参数数量
    }
    // cpp success
    
  • 型変換

    • c成功cpp失敗
    char* p = malloc(4);// 隐式转换
    // c success 
    // cpp failure
    
    • cppの成功
    char* p = (char*) malloc(4);// 隐式转换
    // cpp success
    
  • 構造

    • c失敗cpp成功
    struct Type{
          
          
    	void method();
    }
    // c failure 
    // cpp success
    
  • 三項演算子

    • c失敗cpp成功
    int a = 1, b = 2;
    (a > b ? a : b) = 3; 
    // C 报错,认为 = 左边不是一个左值
    // C 的三目返回一个值,而 C++ 返回引用
    
    • c成功
    *(a > b ? &a : &b) = 3; 
    
  • const定数

    • Cの定数は疑似定数ですが、C ++はそうではありません

      const int a = 1;
      int* p = (int*)&a;
      *p = 2;
      // C 伪常量,可以修改,但在全局作用域声明的常量不可修改
      
      • c

        * p = 2 // pはaを指します

        a = 2

      • cpp

        * p = 2 // pはaのコピーを指します

        a = 1

      • 基本的に、メモリが割り当てられている限り、ポインタを介して変更できます。

        また、C ++はハッシュテーブルを介して(ほとんどの場合)const変数にアクセスします。

        メモリは、カスタムデータ型で、または直接変更できるconst変数の変数初期化を通じて割り当てられます。

    • 'Cはデフォルトでconstを外部変数と見なしますが、C ++はそうではありません

見積もり

  • 参照を返す関数(式)は左辺値として使用できます(無視しやすい使用法)

  • 参照の本質はポインター定数int* const varであり、基礎となる実装(アセンブリ)で直接ポインターを使用することにほとんど違いはありません。

  • 配列への参照

    int arr[10] = {
          
          ...};
    int (&arrRef)[10] = arr;
    // 注意 int& arrRef[10] 是引用的数组,即存放引用的数组
    
  • const int &ref = 10定数参照(主に仮パラメーターの変更に使用されます)

    const int &ref = 10;
    

    基礎となる実装はおそらくこのようなものであり、メモリが割り当てられ、ポインタによって変更できます

    int temp = 10;
    int* const ref = temp;
    
  • C ++ 11右辺値参照

    int&& a = 10;
    

    右辺値である必要がありますが、変更は許可されています

インライン関数

Cマクロの代わりに使用

  • マクロの欠陥

    • 読みやすさ

    • タイプなし

    • 文字置換に基づく実現、ロジックなし

      #define Max(a, n) ((a) < (b) ? (a) : (b)
      int main(){
              
              
          int a = 10;
      	Max(++a, 11);
          // 展开为 ((++a) < (11) ? (++a) : (11)
          // 很明显与预期不符
      }
      
  • インライン関数

    inline void function(){
          
          
    	// 实现
    }
    

    インライン関数は実際にはコードフラグメントであり、インライン関数の呼び出しは実際にはコードフラグメントを直接実行することです。

    関数呼び出しのオーバーヘッドを節約します。

    • 次の状況では、コンパイラはこれがインライン関数であるとは見なしません(inlineキーワードを追加した場合でも)
      • ループがあります
      • 条件付き判断が多すぎる
      • 関数本体は巨大です
      • インライン関数に対処します(インライン関数にはエントリがありません)
  • クラスで定義されているメンバー関数は、デフォルトではインライン関数です。

関数のデフォルトパラメータ

void function(int param1 = 1, string param2 = "2"){
    
    
	// 实现
}
int main(){
    
    
	function();
}
  • 関数宣言にデフォルトのパラメーターがある場合、関数定義(実装)はしてはなりません。

    つまり、関数の宣言と定義で許可されるデフォルトパラメータは1つだけです。

関数のプレースホルダーパラメーター

void function(int){
    
    
	// 实现
}

主に、プレースホルダーパラメータのオーバーロード関数として++をオーバーロードするために使用されます。

関数のオーバーロード

  • オーバーロードされた関数は同じスコープ内にある必要があります

  • オーバーロードされた関数を区別するための条件

    • パラメータリスト(タイプ、番号、順序)
    • デフォルトのパラメータがある場合のあいまいさに注意してください
  • C ++シンボルのCリンク可能性

    C ++でコンパイルされたCプログラムを呼び出す状況のCはリンクできません関数が表示されます。

    これは、C ++のポリモーフィズムが原因で発生します。これにより、C ++は、関数名の点でCとは異なる基本的な実装になります

    解決策

    • extern "C"このC ++関数をCモードでコンパイルするように(つまり、C ++の基礎となるポリモーフィズム処理を行わないように)コンパイラーに指示して、C ++呼び出しのCリンク可能性を確保します。

      extern "C" void function();
      
    • または、すべてをCヘッダーファイルに直接インクルードしますextern "C" {}

      // 在 C 函数的头文件中
      #ifdef __cplusplus
      exteern "C"{
              
              
      #endif
      
      // 函数声明
      
      #ifdef __cplusplus
      }
      #endif
      

      問題もあります:

      C ++はC関数を直接呼び出し、VC ++はエラーをコンパイルし、g ++は問題なくコンパイルします。

      g ++が密かに最適化されていると思います。

おすすめ

転載: blog.csdn.net/qq_16181837/article/details/106555944