コンテンツ
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キーワードを追加した場合でも)
- ループがあります
- 条件付き判断が多すぎる
- 関数本体は巨大です
- インライン関数に対処します(インライン関数にはエントリがありません)
- 次の状況では、コンパイラはこれがインライン関数であるとは見なしません(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 ++が密かに最適化されていると思います。
-