C ++入門
C言語のhelloworldファイルサフィックスは「.c」であり、C ++のファイルサフィックスは「.cpp」であることがわかっています。
最初にC ++の言語を理解する最初のC ++プログラムHelloWorldを作成します。
#include <iostream>
using namespace std; //1.命名空间
int main()
{
cout<<"Hello World!"<<endl; //2.输出
return 0;
}
C ++のHello Worldから、C言語との直感的な違いを確認できます。
- C言語のヘッダーファイルは「.h」で終わりますが、C ++はヘッダーファイルの名前を直接書き込みます
- 名前空間stdを使用するC ++にはもう1つのステートメントがあります
- C ++の出力ステートメントはcoutであり、改行ステートメントはendlです。
次に、C ++の基本的な知識を次の側面から説明します。
1.名前空間
C / C ++には、多数の変数、関数、およびクラスがあります。これらの変数、関数、およびクラスの名前はすべてグローバルスコープに存在するため、多くの競合が発生する可能性があります。名前空間を使用する目的は、名前の競合や名前の汚染を回避するために識別子の名前をローカライズすることです。名前空間キーワードの出現により、この問題が解決されます。
たとえば、名前の競合について説明します。
あなたとあなたの同僚は、プロジェクトの異なるモジュールを担当していると仮定します。場合は、変数aを定義し、あなたの同僚も変数aを定義し、変数を定義するプログラムは、変数Aを使用する場合は?この問題を解決するには、C ++で名前空間名前空間を使用します。
1.1名前空間の定義
名前空間を定義します。使用する必要があります名前空間キーワード、名前空間の名前、そして{}、{}のペアが名前空間のメンバーです。名前空間を定義するには、次の3つの方法があります。
1.1.1通常の名前空間
名前空間の内容は、変数定義または関数定義のいずれかです。
//1. 普通的命名空间
namespace N1 // N1为命名空间的名称
{
// 命名空间中的内容,既可以定义变量,也可以定义函数
int a;
int Add(int left, int right)
{
return left + right;
}
}
1.2.2名前空間のネスト
N3はN2にネストできます
//2. 命名空间可以嵌套
namespace N2
{
int a;
int b;
int Add(int left, int right)
{
return left + right;
}
namespace N3 //N3嵌套在N2中
{
int c;
int d;
int Sub(int left, int right)
{
return left - right;
}
}
}
1.3.1同じプロジェクトで同じ名前の複数の名前空間が許可され、コンパイラは最終的に同じ名前空間に合成されます。
以下のN1の内容は、前の1のN1の内容と1つのスペースにマージされます。
namespace N1
{
int Mul(int left, int right)
{
return left * right;
}
}
注:
名前空間は新しいスコープを定義し、名前空間内のすべてのコンテンツはその名前空間に制限されます。つまり、名前空間はそれ自体の名前空間でのみ有効になります。
1.2コマンドスペースの使用
#include<stdio.h>
namespace N2
{
int a = 10;
int b = 20;
int Add(int x, int y)
{
return x + y;
}
namespace N3
{
int c = 30;
int d = 40;
int Sub(int x ,int y)
{
return x - y;
}
}
}
int main()
{
printf("%d\n", a); // 该语句编译出错,无法识别a
printf("%d\n", c); // 该语句编译出错,无法识别c
return 0;
}
上記のプログラムがa変数とb変数を直接使用する場合、エラーが報告されます。名前空間を使用する3つの方法を説明するために、例として2番目の方法を取り上げましょう。
1.2.1名前空間名とスコープ修飾子を追加する
名前空間名N1とスコープ修飾子::を変数名の前に追加して、変数aとcにアクセスします。
int main()
{
printf("%d\n", N2::a);
printf("%d\n", N2::N3::c);
return 0;
}
結果:
1.2.2名前空間にメンバーを導入するためにusingを使用する
using N2::a;
int main()
{
printf("%d\n", a);
printf("%d\n", N2::N3::c);
return 0;
}
アクセス変数aは、N2を追加せずに直接使用できます::
1.2.3名前空間名を使用して導入する
using namespace N2;
int main()
{
printf("%d\n", a);
printf("%d\n", N3::c);
printf("%d\n", Add(20,30));
return 0;
}
N2 ::を入力しなくても、N2変数とネストされた名前空間の変数と関数にアクセスできます。
2、入力と出力
- 使用するcout標準出力(コンソール)およびcin標準入力(キーボード)の場合、<iostream>ヘッダーファイルとstd標準名前空間をインクルードする必要があります。
- シェーピング-%d、文字-%cなどのデータ形式制御を追加せずに、C ++入力および出力を使用する方が便利です。
#include <iostream>
using namespace std;
int main()
{
int a;
double b;
char c;
cin>>a;
cin>>b>>c;
cout<<a<<endl;
cout<<b<<" "<<c<<endl;
return 0;
}
3、デフォルトのパラメータ
3.1デフォルトパラメータの定義
デフォルトパラメータは、関数を宣言または定義するときに、関数のパラメータのデフォルト値を指定することです。この関数を呼び出すときに、実際のパラメーターが指定されていない場合はデフォルト値が使用され、指定されていない場合は指定された実際のパラメーターが使用されます。
#include <iostream>
using namespace std;
void TestFun(int a = 10)
{
cout<<a<<endl;
}
int main()
{
TestFun(); // 没有传参时,使用参数的默认值
TestFun(20); // 传参时,使用指定的实参
}
3.2デフォルトのパラメータ分類
3.2.1完全なデフォルトパラメータ
デフォルト値のすべてのパラメーターはすべてデフォルトのパラメーターです
void TestFun1(int a=10, int b =20, int c=30)
{
cout<<"a= "<<a<<endl;
cout<<"b= "<<b<<endl;
cout<<"c= "<<c<<endl;
}
int main()
{
TestFun1();
TestFun1(1);
TestFun1(1,2);
TestFun1(1,2,3);
}
3.2.2準デフォルトパラメータ
一部のパラメータのみのデフォルト値は半デフォルトパラメータです
void TestFun2(int a, int b=20, int c=30)
{
cout<<"a= "<<a<<endl;
cout<<"b= "<<b<<endl;
cout<<"c= "<<c<<endl;
}
注:
1。半デフォルトのパラメーターは、右から左の順に指定する必要があり、個別に
指定することはできません。2。デフォルトのパラメーターは、関数の宣言と定義に同時に表示することはできません。
//a.h
void TestFunc(int a = 10);
// a.c
void TestFunc(int a = 20)
{
}
// 注意:如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那
个缺省值。
3.デフォルト値は定数またはグローバル変数である必要があります
。4。C言語はサポートしていません(コンパイラーはサポートしていません)
4、関数のオーバーロード
4.1関数のオーバーロードの概念
関数のオーバーロード:これは関数の特殊なケースです。C++では、類似した関数を持つ同じ名前の複数の関数を同じスコープで宣言できます。同じ名前を持つこれらの関数のパラメーターリスト(パラメーターの数、タイプ、または順序)は必須です。は異なり、それらを処理するために一般的に使用されます。実現関数は、さまざまなデータタイプの問題に似ています。
#include <iostream>
using namespace std;
int Add(int left ,int right)
{
return left+right;
}
double Add(double left, double right)
{
return left+right;
}
long Add(long left, long right)
{
return left+right;
}
int main()
{
Add(10, 20);
Add(10.0, 20.0);
Add(10L, 20L);
return 0;
}
4.2 C ++は関数のオーバーロードをサポートしますが、C言語は関数のオーバーロードをサポートしません
4.2.1プロセス分析
C / C ++では、プログラムを実行するには、前処理、コンパイル、アセンブリ、およびリンクの段階を経る必要があります。
これらの4つのステージの特定の機能については、このブログの2番目のセクション
「LinuxC言語開発ツール-プログレスバーの小さなプログラムを介したgcc、gdb、およびmake / Makefileツールの使用方法の学習」を参照してください。
次のプログラムがあるとします。
#include <iostream>
using namespace std;
int Add(int left ,int right)
{
return left+right;
}
double Add(double left, double right)
{
return left+right;
}
long Add(long left, long right)
{
return left+right;
}
int main()
{
Add(10, 20);
Add(10.0, 20.0);
Add(10L, 20L);
return 0;
}
C言語を使用してコンパイルすると、関数名が同じであるためコンパイルは失敗しますが、C ++はコンパイルできます。
分解して、CおよびC ++での関数名の変更を確認します。
- Linuxでは、次の名前を使用してC言語の逆アセンブリ結果を表示します
objdump -S 05-C_FunOverload
結論:Linuxでは、gccでコンパイルした後、関数名の変更は変更されていません。
- Linuxでは、次の名前を使用してC ++逆アセンブリの結果を表示します。
objdump -S 05-FunOverload
結論:Linuxでは、g ++でコンパイルした後、関数名の変更が変更され、コンパイラは変更された名前に関数パラメータタイプ情報を追加します。
4.2.2結論
分析により、gcc関数の名前は変更後も変更されていないことがわかります。g ++の関数は、変更後、[_ Z +関数の長さ+関数名+タイプのイニシャル]になります。
これにより、同じ名前の関数を区別できないため、C言語ではオーバーロードをサポートできないことがわかりました。C ++は、関数変更ルールによって区別されます。パラメーターが異なる限り、変更された名前は異なり、オーバーロードがサポートされます。
4.3外部「C」
C ++プロジェクトでは、特定の関数をCスタイルでコンパイルする必要がある場合があります。関数の前にextern "C"を追加します。これは、C言語の規則に従って関数をコンパイルするようコンパイラーに指示することを意味します。例:tcmallocはGoogleによってC ++で実装されたプロジェクトです。tcmallc()とtcfreeの2つのインターフェースを提供しますが、Cプロジェクトの場合は使用できないため、extern "C"を使用して解決します。
extern "C" int Add(int left, int right);
int main()
{
Add(1,2);
return 0;
}