ホームページ >バックエンド開発 >C#.Net チュートリアル >C/C++の違いは何ですか?あまり知られていない比較方法
C/C は、キーワード、ソースファイル、変数の定義や宣言箇所、関数、デフォルトパラメータの数から比較する必要があります。いつも迷っている場合は、この記事を読むと役立ちます。
C/C 以下の観点からの比較:
キーワードの数:
C 言語: C99バージョン、32 キーワード
C: C98 バージョン、63 キーワード
ソース ファイル:
C ソース ファイル拡張子 .c、C ソース ファイル拡張子 。 cpp、ソース ファイルの作成時に何も指定しない場合、デフォルトは .cpp です。
変数の定義または宣言の場所:
C 言語は次の場所で定義する必要があります。最初の行; C は必要ありません
関数:
(1) 戻り値
C 言語では、関数で指定されていない場合、戻り値の型を指定すると、デフォルトで int 型が返されます;
C では、関数の戻り値の検出がより厳しくなります。関数が値を返さない場合は、void として指定する必要があります。
(2 ) パラメータ リスト
C 言語では、関数がパラメータ リストを指定しない場合、デフォルトで任意の数のパラメータを受け入れることができます。ただし、C では、厳密なパラメータ タイプ検出により、パラメータ リストのない関数はデフォルトで void になります。パラメータは受け入れられません。
デフォルト パラメータ:
デフォルト パラメータは、関数の宣言または定義時に、関数のパラメータのデフォルト値を指定します。この関数を呼び出すとき、実パラメータが指定されていない場合はデフォルト値が使用され、そうでない場合は、指定された実パラメータが使用されます。
//1.实现缺省参数void Test(int a = 50){ cout << a << endl; } int main(){ Test(); // 输出50 Test(100); // 输出100}
(1) すべてのデフォルト パラメータ: すべてのパラメータにすべてのデフォルト値を指定します //コード
// 实现全缺省参数void Test(int a = 1,int b = 2,int c = 3) { cout << a << "" <<" "<< b << "" <<" "<< c << endl; }int main() { Test();//1 2 3 Test(100);//100 2 3 Test(100, 200);//100 200 3 Test(100, 200, 300);//100 200 300}
(2) 準デフォルトパラメータ: デフォルト値は右から左へのみ渡すことができると規定されています //コード
// 实现半缺省参数 注:缺省值只能从右往左传void Test1(int a = 1, int b = 2, int c = 3) { cout << a << "" << " " << b << "" << " " << c << endl; }void Test2(int a , int b = 2, int c = 3) { cout << a << "" << " " << b << "" << " " << c << endl; }void Test3(int a , int b , int c = 3) { cout << a << "" << " " << b << "" << " " << c << endl; }void Test4(int a = 1, int b , int c = 3)//不能通过编译,因为它违背了缺省值只能从右往左依次来给这一规定{ cout << a << "" << " " << b << "" << " " << c << endl; }void Test5(int a = 1, int b = 2, int c )//不能通过编译,因为它违背了缺省值只能从右往左依次来给这一规定{ cout << a << "" << " " << b << "" << " " << c << endl; }void Test6(int a = 1, int b , int c )//不能通过编译,因为它违背了缺省值只能从右往左依次来给这一规定{ cout << a << "" << " " << b << "" << " " << c << endl; }void Test7(int a , int b = 2, int c )//不能通过编译,因为它违背了缺省值只能从右往左依次来给这一规定{ cout << a << "" << " " << b << "" << " " << c << endl; }int main() { Test1();//1 2 3}
注:
a. 带缺省值的参数必须放在参数列表的最后面。 b. 缺省参数不能同时在函数声明和定义中出现,只能二者则其一,最好放在函数声明中。 c. 缺省值必须是常量或全局变量。
C 言語はサポートしていませんデフォルトパラメータ
関数のオーバーロードとは、同じスコープ内の同様の関数を持つ同じ名前の複数の関数を宣言することを指します。これらの仮パラメータのリストは、同じ名前の関数 (それぞれの番号、型、型の順序) は異なっていなければなりません。
//函数重载void Add();void Add(int a);//行参个数不一样void Add(char b);//行参类型不同void Add(int a, char b);void Add(char a, int b);//行参类型的次序不同
戻り値の型が異なるだけで、関数のオーバーロードを構成することはできません。
//仅仅返回值的类型不同,是不能构成函数重载的void Add(int a, int b) {}int Add(int a, int b) { return a + b; }int main() { Add(1, 2);//因为这样会造成调用不明确,两函数都可以被调用 return 0; }
C 関数のオーバーロードがサポートされている理由: VS エディターは、関数パラメーターの型を下部の関数名にコンパイルするため、元の関数はname は別の一意の名前に変更されます。
int Add(int a, int b); // ?Add@@YAHHH@Zchar Add(int a, int b); // ?Add@@YADHH@Zchar Add(char a, char b); // ?Add@@YADDD@Z
C 言語が関数のオーバーロードをサポートしていない理由: 生成される新しい関数名は同じです。関数名の前に __
を追加するだけです。C 言語スタイルで関数をコンパイルするには、先頭に extern "c"
extern "C" int Add(char a, int b);
C 言語で関数にパラメータを渡すには、値渡しと アドレス渡し#の 2 つの方法があります。
##値による受け渡し: 関数呼び出し中に、一時変数が生成されて仮パラメータに置き換えられ、最後に実際のパラメータの値が新しいパラメータに渡されます。割り当てられた一時変数、つまり仮パラメータ。
値渡しの利点: 関数の副作用は外部パラメーターに影響しません。
値渡しの欠点: パラメータを変更することで外部パラメータを変更することはできません。
参照の受け渡し: 関数呼び出し中に、一時変数が生成されて仮パラメータに置き換えられ、最後に実際のパラメータのアドレスが新しく割り当てられた一時変数に渡されます。
参照を渡す利点: スペースの節約、高効率、パラメータの変更により外部の実パラメータを変更できる。
ポインターを渡すことの欠点: ポインターは安全ではなく、関数の副作用が外部の実パラメーターに影響します。
C Medium:
参照: (1) 概念: 参照とは、変数を新規に定義することではなく、既存の変数を参照することです。別名を取得した後、コンパイラは参照変数にメモリ空間を割り当てず、参照変数と同じメモリ空間を共有します。
(2) 形式:
型&参照変数名 = 参照実体
//引用int main() { int a = 10; int& ra = a; printf("%p\n", a); printf("%p\n", ra);//ra和a的地址相同,说明ra和a是同一个实体,他们共用同一块内存空间 ra = 3; printf("%d\n", a);//3 return 0; }注:
a. 引用在定义时,必须初始化。 b. 一个变量可以被多次引用。 c. 引用一旦引用了一个实体,就不能在引用其他实体。 d. 引用变量的生命周期比实体的生命周期短。(3) よく参照する
常引用int main() { const int a = 1; //int& ra = a;//编译会出错,因为实体a是常量 const int& ra = a; double b = 12.34; //int& rb = b;//编译会出错,因为类型不同 const int& rb = b; printf("rb=%d\n", rb);//rb=12 b = 5.0; printf("b=%f\n", b);//b=5.0 printf("rb=%d\n", rb);//rb=12 //b的值改变,但rb的值并没有随之改变,说明rb和b是两个不同的实体}(4) 配列参照
//数组引用int a[10];//数组a的类型为 int[10]int(&ra)[10] = a;(5) 参照シナリオ:
a. 実際のパラメータを変更するには、関数のパラメータとして参照を使用します。
void Swap(int* pLeft, int* pRight) { int temp = *pLeft; *pLeft = *pRight; *pRight = temp; } void Swap(int& left, int& right) { int temp = left; left = right; right = temp; } //如果用引用时不想改变实参的值,则给引用前加const void Swap(const int& left, const int& right);int main() { int a = 10; int b = 20; Swap(&a, &b);//通过传地址来改变实参 printf(" a=%d ", a); printf(" b=%d\n", b); Swap(a, b);//通过引用来改变实参 printf(" a=%d ", a); printf(" b=%d\n", b); }b. 関数の戻り値として参照変数を使用する //コード
情形1:int& FunTest() { int a = 10; return a; }int main() { int b = FunTest();//将函数的返回值赋给了b printf("b=%d\n", b);//b=10 printf("b=%d\n", b);//b=10 printf("b=%d\n", b);//b=10 return 0; } 情形2:int& FunTest2() { int a = 10; return a; }int main() { int& b=FunTest2();//将函数的返回值作为实体, printf("b=%d\n", b);//b=10 printf("b=%d\n", b);//随机值 printf("b=%d\n", b);//随机值 return 0; } 情形3:int& FunTest3(int& a) { a = 10; return a; }int main() { int b; int& rb = FunTest3(b); printf("b=%d\n", b);//b=10 printf("rb=%d\n", rb);//rb=10 printf("rb=%d\n", rb);//rb=10 printf("rb=%d\n", rb);//rb=10 return 0; } 注意:不能返回栈空间上的引用値渡し、参照渡し、参照の効率の比較
//比较struct BigType { int array[10000]; };void FunTest(BigType bt)//传值或传址{}void FunTest(BigType& bt)//引用{}void TestFunTestRumTime() { BigType bt; size_t Start = GetTickCount(); for (i = 0; i < 1000000; i++) { FunTest(bt);//传值或传引用 FunTest(&bt);//传址 } size_t End = GetTickCount(); printf("%d\n", End - Start); }//此代码检测出传值最慢,而传址和引用速度快且用时差不多相同
参照とポインターには 2 つの違いがあります。違いは何ですか?
類似点:
引用比指针使用起来相对安全。
在C++中,变量、函数和类都是大量存在的,这些变量、函数和类的名称将都存在于全局命名空间中,会导致很多冲突,使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染。
命名空间的定义
//命名空间namespace N1 { int a = 30; void FunTest() { printf("N1::FunTest()\n"); } }//N1的命名空间int a = 20;void FunTest() { printf("::FunTest()\n"); }//在全局作用域中int main() { int a = 10; printf("%d\n", a); printf("%d\n", ::a); ::FunTest(); printf("%d\n", N1::a); N1::FunTest(); return 0; }//命名空间的嵌套namespace N2 { int a = 40; void FunTest() { printf("N2::FunTest()\n"); } namespace N3 { int a = 50; void FunTest() { printf("N2::N3::FunTest()\n"); } } }int main() { N2::FunTest(); N2::N3::FunTest(); return 0; }// 在同一个工程里允许存在多个相同名称的命名空间,编译器最后会合成到同一个命名空间中namespace N1 { int b = 70; void Test() { printf("N1::Test()\n"); } }
说明
a.一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。
b.没有名称的命名空间只能在当前文件中使用,它里面定义的变量相当于工程里面的全局变量。
命名空间的使用
//命名空间的使用namespace N1 { int a = 1; int b = 2; int c = 3; /*void FunTest1() {} void FunTest2() {}*/}//法二:using N1::b;//法三:using namespace N1;int main() { int a = 4; //法一: printf("a=%d\n", N1::a);//a=1 printf("b=%d\n", b);//b=2 printf("c=%d\n", c);//c=3}
//代码
//C++输入输出#include <iostream>using namespace std;//std标准命名空间int main() { int a = 10; double b = 3.14; char c = 'c'; cout << a ; cout << b << '\n'; cout << c << endl; cout << a << " " << b << " " << c << endl; cin >> a ; cin >> b >> c; return 0; }// cout:标准命名空间重输出流对象 <<输出操作符 // cin:标准命名空间重输入流对象 >>输入操作符
相关推荐:
以上がC/C++の違いは何ですか?あまり知られていない比較方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。