[Basic C++] 1. 入門知識の紹介 (C++ キーワード、名前空間、C++ 入出力、デフォルト パラメーター、関数のオーバーロード)

================================================= =======================

相关代码gitee自取

C言語学習日記:がんばりましょう(gitee.com)

 ================================================= =======================

接上期

[基本データ構造] 11. マージソート(比較ソート)の説明と実装
(再帰版+非再帰版 - C言語実装) - CSDNブログ

 ================================================= =======================

                     

はじめに: C++ とは何ですか

  • C 言語構造化されておりモジュール式です。 > 言語 より小さなプログラム< a i=9>の処理に適しています。 複雑な問題の場合、大規模なプログラム高度な抽象化とモデリングが必要な場合C 言語は適していません< a i=17> a>。 1980 年代に、ソフトウェア危機を解決するために、コンピュータ業界は次のことを提案しました。 OOPオブジェクト指向プログラミングオブジェクト指向


    アイデア サポート オブジェクト指向プログラミング言語が誕生

                             
  • 1982 年、ビャルネ ストロイストラップ博士C 言語オブジェクト指向の概念を導入および拡張し
    新しいプログラミング言語を発明しましたC++ と呼ばれます。あ>C++言語と C 言語の間の起源関係を表現します
                             
  • したがって:C++C 言語に基づいています
    は C 言語で 手続き型プログラミングを実行できます
    オブジェクト指向プログラミング を実行することもできます。オブジェクトベースのプログラミング
    抽象データ型を特徴とする

                      
  • C++ C 言語に基づいています オブジェクト指向プログラミングのアイデア
    には、多くの便利な機能が追加されていますライブラリプログラミング パラダイム など a>
    C 言語に精通している場合は、C++ を学習すると役立ちます
                    
  • このブログの主な目的:
    1. C 言語の文法の欠点を補う a> と C++ C 言語の無理な設計を最適化する方法です。 > a>、
    例: スコープ アスペクト IO の側面関数の側面ポインタの側面< a i =17>、マクロの側面 など
    2. その後の理解 a>基礎の構築クラスとオブジェクト

           

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

             

はじめに: C++ の開発の歴史

1979 年、ベル研究所ベンジャニは、UNIX カーネルの分析を試みていました。 a>、< /span>呼び出しますプリプロセッサを完成させます実行できるクラスメカニズム追加C 言語をベースに拡張 をモジュール化しようとしたため、 カーネル

                    

C++语言也进行着逐步递进由浅入深过程

C++ の過去のバージョン:
ステージ コンテンツ
C とクラス

クラスと派生クラス、パブリック メンバーとプライベート メンバー、クラスの構築と破棄、フレンド、インライン関数、代入演算子
オーバーロードなど

C++1.0 仮想関数、関数と演算子のオーバーロード、参照、定数などの概念を追加します。
C++2.0 オブジェクト指向、新しい保護されたメンバー、多重継承、オブジェクトの初期化、抽象クラス、静的メンバー、const メンバー関数のサポートが強化されました。
C++3.0 さらなる改善、多重継承と対応する構築と破棄の処理によって引き起こされる曖昧さの問題を解決するためのテンプレートの導入
C++98 C++ 標準の最初のバージョンほとんどのコンパイラはをサポートし、国際標準化機構 (ISO) および アメリカStandards Institute が承認し、テンプレート方式で C++ 標準ライブラリを書き直す STL (標準テンプレート ライブラリ) の導入
C++03 C++ 標準の 2 番目のバージョンでは、主にエラーの修正と多様性の削減という言語機能に大きな変更はありません。
C++05

C++ 標準委員会は集計レポート (テクニカル レポート -- TR1) を発行し、正式に C++0x と名前が変更されました。
つまり、今世紀の最初の 10 年間に計画されています。いつか

C++11 多くの機能を追加しましたC++ を新しい言語に近づけました
正規表現、範囲ベースの for ループ、自動キーワード、新しいコンテナ、リストの初期化、標準スレッド ライブラリなど
C++14 C++11 への拡張。主に C++11 の抜け穴の修正と改善を目的としています。
例: 汎用ラムダ式、自動戻り値型導出、バイナリ リテラル定数、など
C++17 C++11 でいくつかのマイナーな改善が行われ、19 個の新機能が追加されました。
例: static_assert() のテキスト情報はオプションであり、Fold 式は変数に使用されます。テンプレート、
if ステートメントや switch ステートメントの初期化子など
C++20 C++11 以降最大のリリース多くの新機能が導入されています
など: モジュール、コルーチン、範囲、コンセプト (制約)
およびその他の主要な機能。
もあります。既存の機能の更新: Lambda によるテンプレートのサポート、ループの範囲による初期化のサポートなど
C++23 開発中で...

            

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

              

1. C++キーワード(C++98版)

C++合計キーワード 63 個、C 32 キーワードを含む 言語用

C++ バージョンのキーワード テーブル:
アズム する もし 戻る 試す 続く
自動 ダブル 列をなして 短い typedef のために
ブール ダイナミックキャスト 整数 署名済み タイプID 公共
壊す それ以外 長さ のサイズ タイプ名 投げる
場合 列挙型 可変 静的 連合 wchar_t
キャッチ 明示的な 名前空間 static_cast 署名されていない デフォルト
チャー 輸出 新しい 構造体 を使用して 友人
クラス 外部 オペレーター スイッチ バーチャル 登録する
定数 間違い プライベート テンプレート 空所 真実
const_cast 浮く 保護された これ 揮発性の その間
消去 後藤 再解釈_キャスト

(赤色のキーワードは、C 言語ブログで以前に言及または使用したキーワードです。< /span>)

         

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

             

2. 名前空間 – 名前空間キーワード

(1). 名前空間の役割:

C/C++中,变量函数后面要了解的类都是大量存在的,
这些变量函数的名称都将存在于全局作用域可能会导致很多冲突
使用命名空间的目的对标识符的名称进行本地化,以避免命名冲突名字污染
namespace关键字的出现就是针对这种问题

例:

                     

                     


                    

(2). 名前空間の定義:

  • 名前空間を定義する名前空間キーワードを使用する必要があります、

    キーワードの後に​​はネームスペースの名前が続きますその後中かっこのペアを追加します{}

    中括弧 {} 内のコンテンツは、 ネームスペース のメンバーです。
                      

  • 一般的な開発では、プロジェクト名を使用します。 としてネームスペースの名前
                            

一般的な名前空間の定義:

名前空間のネストされたサブ名前空間:

同じ名前の複数の名前空間が存在します。
  • 同じプロジェクトは同じ名前の複数の名前空間を持つことができます
    コンパイラは最終的に同じ名前空間にマージする
                 
  • 一个工程中的 test.h头文件)  text.cppC++文件
    两个同名命名空间会被合并成一个

                     

                     


                    

(3). ネームスペースの使用:

ネームスペースを定義する新しいスコープを定義する

ネームスペース内のすべてのものそのネームスペースに制限されます

そのため直接呼び出して

ネームスペースを使用するには 3 つの方法があります:

                      

方法 1:
名前空間名とスコープ修飾子を追加する
  • 作用域限定符两个冒号) --   : :

                       

方式二:
using namespace 命名空间名称 展开命名空间
  • 使用 using namespace 命名空间名称 可以展开对应的命名空间
    展开后可以直接通过该命名空间中成员的名称使用该成员
                        
  • 但是使用该方式对命名空间的展开
    会导致命名空间的所有内容暴露出来
    可能又会导致命名冲突问题
                   
  • 所以一般在自己使用时为了方便才会使用该方式
    如果是项目工程该方式一定要慎重使用,可能会出大问题的

                 

方式三:
使用using关键字只展开命名空间中的某个成员
  • 通过方式二直接展开命名空间会有命名冲突的风险
    那么我们可以通过
    using 命名空间名称::指定成员
    指定只展开命名空间中的某个成员
                         
  • 这种方式比较常用的,
    通常是对一些常用的成员对象进行使用
    避免频繁使用方式一调用命名空间减轻代码冗余

            

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

三、C++输出&输入

C++中有了新的输入和输出方法,虽然说有了新的输入输出方法,
之前C语言中的输入和输出方法也是可以用的
了解C++的输入和输出方法前,需要先了解以下概念

                     

                     

std -- C++标准库命名空间

stdC++标准库的命名空间名C++标准库的定义实现都放在这个命名空间中
上一标题我们知道了使用命名空间的三种方式,而使用std命名空间的方式要考虑实际情况

               

std命名空间的使用惯例:

  • 在自己的日常练习中,建议直接方式二即可
    即:using namespace std
    这样使用std命名空间就很方便了,不用频繁使用方式一进行操作
                     
  • 而在项目工程中,using namespace std 展开方式二展开),
    标准库就全部暴露出来了,如果我们定义了跟库中重名的 类型/对象/函数
    就会存在命名冲突问题。该问题在日常练习中很少出现
    但是项目开发中代码较多规模大,就很容易出现
                        
  • 所以建议在项目开发中使用方式三指定展开
    即:using std::成员(对象)
    指定展开std命名空间中常用的几个库对象/类型/成员
    像是C++输出时使用的cout输入时使用的cin

                         

                         


                        

cout 和 cin

  • cout  --  console(控制台) out  --  标准输出对象(控制台)  --  流插入
    cin  --  console(控制台) in  --  标准输入对象(键盘)  --  流提取
                        
  • 使用cout标准输出对象cin标准输入对象
    需要包含 <iostream> 头文件IO流头文件以及 按命名空间使用方法使用std
注:C++ <iostream>头文件 不需要像C语言一样加“.h”后缀

早期标准库所有功能全局域中实现声明在“.h”后缀的头文件
使用时只需包含对应头文件即可后来将标准库所有功能实现在std命名空间
为了和C语言头文件区分,也为了正确使用命名空间规定C++头文件不加“.h”后缀
旧编译器(vc 6.0)中还支持 <iostream.h> 格式,后续编译器已不支持,
因此推荐使用 <iostream> + std命名空间 的方式
                   

  • cout cin 全局的流对象endlendline)是特殊的C++符号表示换行输出
    他们都包含在 <iostream>头文件
                         
  • 使用cout进行输出时还需要用到<<  --  流插入运算符
    使用cin进行输入时还需要用到>>  --  流提取运算符
    (在C语言中<<>> 位于算符在C++中又多了以上身份
                    
  • 使用C++输入和输出相对C语言更方便
    不需要像 scanf / printf 输入输出时要手动控制格式%d%p……),
    C++的输入和输出可以自动识别变量类型
                         
  • 实际上 cout cin 分别是 ostream istream 类型对象
    >> <<涉及运算符重载等知识这里只是简单了解并使用
    关于coutcin还有很多更复杂的用法
    比如控制浮点数输出精度控制整型输出进制格式等,但并不常用
    实在需要使用时可以用C语言来操作C++兼容C语言的操作
示例:

对应代码:
//包含IO流头文件:
#include <iostream>

//指定展开命名空间成员:
using std::cout;  //指定展开标准输出对象(控制台)
using std::cin;  //指定展开标准输入对象(键盘)
using std::endl;  //指定展开C++换行符号

int main()
{
	int a = 10; //整型变量
	double b = 3.14; //浮点型变量

	cout << "使用cout打印当前a和b:" << endl;

	//使用cout进行输出:
	cout << a << endl << b << endl;
	/*
	* 通过cout标准输出对象和<<流插入运算符进行输出打印:
	* 
	* 先将a这个变量流进std::cout这个控制台中打印,
	* 再进行endl换行,再将b这个变量
	* 流进std::cout这个控制台中打印,再换行。
	* 
	* 即使 a变量 和 b变量 的类型不同也能打印
	* C++的输入和输出可以自动识别变量类型
	*/
	
	cout << "使用cin分别输入数据到a和b:" << endl;

	//使用cin进行输入:
	cin >> a >> b;
	/*
	* 通过cin标准输入对象和>>流提取运算符对数据进行输入:
	*
	* 让你在控制台上输入的数据分别流入a和b这两个变量中
	*
	* 即使 a变量 和 b变量 的类型不同也能输入
	* C++的输入和输出可以自动识别变量类型
	*/

	cout << "输入后再使用cout进行输出打印:" << endl;

	cout << a << endl << b << endl;

	return 0;
}

            

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

四、缺省参数

(1). 缺省函数的概念:

缺省参数在声明或定义函数时函数的参数指定一个缺省值
调用该函数时如果没有指定实参则采用该形参的缺省值否则使用指定的实参,

有了缺省参数可以调整参数的各种形式来调用该函数

                        

  • 缺省值必须是常量或者全局变量
                    
  • C语言不支持缺省参数编译器不支持
                             
  • 缺省参数不能在函数声明和定义中同时出现

                     


                    

(2). 缺省函数的分类:

全缺省参数:

函数的所有参数都设置对应的缺省参数

图示:

                          

                   

半缺省参数:

只对函数的部分参数设置对应的缺省参数

                       

  • 半缺省参数必须从右往左依次来给出不能间隔着给
    传参从左往右半缺省参数从右往左
图示:

            

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

             

五、函数重载

自然语言中,一个词可以有多重含义
人们可以通过上下文来判断该词真实的含义,即该词被重载

                           

函数重载的概念:

函数重载是函数的一种特殊情况
C++允许在同一作用域中声明几个功能类似的同名函数
这些同名函数的形参列表参数个数参数类型类型顺序不同
函数重载常被用来处理实现功能类似但数据类型不同的问题

图示:

                     

                     


                    

(难)C++支持函数重载的原理 -- 名字修饰(name Mangling)

为什么C语言不支持函数重载而C++支持函数重载

解决这个问题,需要先了解一下编译链接的过程,往期相关博客:
学C的第三十四天【程序环境和预处理】_高高的胖子的博客-CSDN博客
                        

简单解释编译链接过程:

假设我们现在有三个文件

Func.h                Func.cpp                Test,cpp

函数声明)        (函数实现)        (主函数调用

执行主函数时需要进行以下过程

预处理  =>  编译  =>  汇编  =>  链接

现有文件和其内容:

                     

预处理:
  • 预处理过程操作包括:头文件展开(主要)  /  ​​​宏替换  /  条件编译  /​  去除注释​​​

Fun.cpp文件Test.cpp文件 中,因为都包含了 Func.h头文件

所以在预处理时对头文件进行展开,之后会生成预处理文件Func.i文件 和 Test.i文件

所以在 Func.i文件 中就会有Func函数的声明和实现Func.i函数声明和定义),

Test.i文件会有被调用的函数的声明和调用Test.i函数的声明和实际调用

                           

编译:
  • 编译过程操作包括:检查语法是否错误 / 生成汇编代码

进行编译时生成汇编代码文件.s文件),

Func.s文件Test.s文件分别由 Func.i文件 Test.i文件 生成),

Func.s文件存放了两个重载函数对应的汇编代码

Test.s文件 中则存放了主函数main函数的汇编代码

包括被调用的两个重载函数的汇编代码

要调用这两个重载函数,还需要用到汇编语言中的 call指令获取函数的地址

但在编译阶段,因为 Test.i文件 中只包含了 Func.h头文件只有函数声明没有函数实现

所以 call指令无法获得对应的函数地址

在这种情况下,编译器判断调用的函数和头文件中函数是否匹配,如果匹配的话

即使 call指令 还没找到函数地址也可以先让其通过编译方便实现多文件项目

                  

汇编:
  • 汇编过程操作包括:将汇编代码文件中的代码转换为二进制的机器码
    二级制的机器码CPU能读懂的代码

汇编后生成目标文件.o文件),
 Func.o文件 Test,o文件分别由 Func.s文件Test.s文件 生成),

两个文件都将汇编代码转换成了对应的二进制机器码

                 

链接: 
  • 链接过程操作包括:将目标文件链接合并到一起链接一些没有确定函数地址等等

汇编操作中Func.o文件 Test.o文件 合并为 a.out文件默认情况下),

合并后的 a,out文件 中:

之前在编译过程call指令未找到的函数地址可以在合并后的 a.out文件 中找到
(因为合并前 Func.o文件包含对应函数的实现

                          

                          
---------------------------------------------------------------------------------------------

                       

C++支持重载函数,而C语言不支持的原因:

通过上面对编译链接过程的简单了解,我们可以知道:

编译过程中 call指令 还未找到被调用函数的地址,直到链接过程合并文件后才能够找到

                   

C语言不支持重载函数的原因:

C语言中没有重载函数,即函数名唯一的情况下

找函数地址只需要通过唯一的函数名即可找到
即在链接过程中通过唯一的函数名 Func.o目标文件 中的符号表进行对地址的查找

所以如果C语言中有重载函数函数名不唯一的情况下无法在链接过程中找到函数地址

因此C语言无法支持重载函数

                      

C++支持重载函数的原因 -- 名字修饰(name Mangling):

不同编译器实现方式不同,这里Linux中的g++为例

C++オーバーロードされた関数がある場合、つまり関数名が一意でない場合

C++これを渡すできる関数があります。関数名 および パラメータ条件 新しい関数名 を変更します。 、

関数名は同じですが、パラメータは異なります、< a i=4 >別の関数名を変更する

次に、 対応する によって変更された関数名を検索します。関数アドレス

  • 修饰名字构成方式
    _Z  函数名字符个数  +  函数名  +  各参数首字母
    假设有一个函数:Func(int a, double b)修饰后的函数名字为:_Z4Funcid
    假设有另一个函数:Func(double b, int a) 修饰后的函数名字为:_Z4Funcdi
    所以即使函数名相同也可以通过参数情况来创建出不同的函数名字

おすすめ

転載: blog.csdn.net/weixin_63176266/article/details/134147231