C++基础

C++简介,Linux下开发C++Ubuntu)、安装g++、创建C++文件、编译C++文件、"hello world"示例C++特点,新增特性,面向对象编程,类和对象,构造函数和析构函数,继承和多态 运算符重载,异常处理,标准模板库(STL),命名空间、OOPObject-Oriented Programming)对象(Object)类(Class)封装(Encapsulation)继承(Inheritance)组合(Composition)、多态(Polymorphism)、动态绑定(Dynamic Binding)、静态绑定(Static Binding)、消息传递(Message Passing)、方法(Method)。泛型编程 基本概念。STL ( Standard Template Library标准模板库)六大组件以及组件间的关系、编译C++程序基本步骤(与C语言一样)、预处理(Preprocessing)、编译(Compilation)、汇编(Assembly)、链接(Linking)。C++程序基本结构、C++基本规范、源文件扩展名、头文件命名规则、命名可描述性头文件、C++C的差异性、新增变量引用(reference)、 给变量取别名:、引用传参、面对条件不同C:面向过程、C++:面向对象、新增泛型编程、支持异常处理、支持函数和运算符重载、支持名字空间、函数、函数重载、函数重载的特点、函数默认参数、结构体基本语法、访问权限、成员函数定义、作用域C++支持三种作用域、局部域、类域、名字空间域、链接性与存储性、变量的链接性(linkage)、变量的存储性、函数、语言动态内存1.new/delete运算符2.new [ ] / delete [ ]

一、C++简介

        1983年,贝尔实验室( Bell Labs )的Bjarne Stroustrup发明了C++。C++在C语言的基础上进行了扩充和完善,是一种面向对象程序设计( OOP)语言
        Stroustrup说:“这个名字象征着源自于C语言变化的自然演进”。还处于发展完善阶段时被称为“newC”,之后被称为“C with Class”。

        C++被视为C语言的上层结构,1983年Rick Mascitti建议使用C+十这个名字,就是源于C语言中的“++”操作符(变量自增)。而且在共同的命名约定中,使用“+”以表示增强的程序。

C++是一种通用的、高级的编程语言,它在许多领域都得到了广泛的应用。C++是从C语言发展而来的,它继承了C语言的特性,并增加了面向对象编程的能力。

Linux下开发C++(Ubuntu)

1、安装g++

sudo apt-get install g++

2、创建C++文件

vi hello.cpp

3、编译C++文件

g++ hello.cpp -o hello

4、"hello world"示例

#include <iostream>//标准输入输出流
//名字空间
using namespace std;
//入口函数
int main(int argc, char *agv[])
{
    cout<<"hello world"<<endl;
    return 0;
}

运行结果:

C++特点

1. 面向对象

        C++支持面向对象编程,可以使用类、对象、继承、多态等面向对象的概念和特性。这使得C++更加灵活和易于扩展。

2. 高效性

        C++是一种系统级编程语言,它提供了低级的内存访问和直接的硬件控制能力。通过手动内存管理和内联汇编等技术,可以实现高效的程序性能。

3. 可移植性

        C++的代码可以在不同的操作系统和平台上进行编译和运行,具有很好的可移植性。这使得C++成为开发跨平台软件的首选语言之一。

4. 扩展性

        C++支持使用库和模板进行代码重用和扩展。标准库提供了丰富的函数和类,可以快速开发各种应用程序。同时,C++还支持模板元编程,可以在编译时进行代码生成和优化。

5. 多范式

        除了面向对象编程,C++还支持过程式编程和泛型编程。开发者可以根据需要选择合适的编程范式,提高代码的可读性和可维护性。

        C++广泛应用于系统软件、游戏开发、嵌入式系统、科学计算、金融等领域。它是一门强大而灵活的编程语言,具有很高的学习价值和实用性。

二、新增特性

相比于C语言,C++引入了许多新增的特性和功能,使其更加强大和灵活。以下是C++相对于C语言的一些主要新增特性:

1. 面向对象编程

        C++支持面向对象编程,引入了类、对象、继承、多态等概念和特性。这使得程序的设计和组织更加模块化和可扩展,提高了代码的复用性和可维护性。

2. 类和对象

        C++中引入了类和对象的概念,允许开发者通过定义自己的数据类型来建立抽象和封装。类可以封装数据和函数,并提供公共接口进行访问和操作。

3. 构造函数和析构函数

        C++允许在类中定义构造函数和析构函数。构造函数在创建对象时执行初始化操作,而析构函数在对象销毁时执行清理工作。这方便了资源的管理和对象的生命周期控制。

4. 继承和多态

        C++支持继承机制,可以从一个现有的类派生出新的类,并继承其属性和行为。多态性允许使用基类的指针或引用来操作派生类的对象,实现了动态绑定和运行时多态。

5. 运算符重载

        C++允许开发者对运算符进行重载,使其适应自定义类型的操作。通过运算符重载,可以实现自定义类型的直观操作和语法糖。

6. 异常处理

        C++引入了异常处理机制,允许开发者在程序中捕获和处理异常情况。通过使用try-catch块,可以对可能发生的异常进行捕获和处理,提高程序的健壮性和可靠性。

7. 标准模板库(STL)

        C++标准库提供了丰富的类模板和函数模板,即标准模板库(STL)。STL包括容器、算法和迭代器等组件,提供了高效的数据结构和算法,可以快速开发复杂的数据处理和算法应用。

8. 命名空间

        C++引入了命名空间(namespace)机制,用于避免命名冲突和隔离不同的代码模块。通过将相关的函数、类和变量放置在命名空间中,可以更好地组织和管理代码。

这些新增特性使得C++相比C语言更加强大和灵活,能够满足更多复杂应用的需求,并提高开发效率和代码质量。

三、OOP(Object-Oriented Programming)

1、简介

        面向对象编程(Object-Oriented Programming,简称OOP)是一种软件开发的编程范式,它将数据和操作数据的方法封装在对象中,以模拟现实世界中的实体和其相互作用。OOP强调了数据的抽象、封装、继承和多态等概念,以实现代码的可重用性、可扩展性和可维护性。

1、重用性


        代码被重复使用,以减少代码量,就是重用性的重要指标。

2、灵活性


        软件系统由很多可以复用的构件随意重构,以达到实现不同的功能,非常灵活。

3、扩展性


        软件系统可以容易地新增需求,基本构件也可以轻松的扩展功能。

4、面向过程设计


        程序=数据结构+算法

5、面向对象设计


        对象=数据结构+算法
        程序=(对象+对象+...)+对象间通讯机制

6、面向对象编程主要涉及概念


        类、对象、数据抽象、继承、动态绑定、数据封装、多态性、消息传递。

2、核心思想

        OOP的核心思想是类和对象。类是对一类具有相同属性和行为的对象进行抽象的描述,它定义了对象的属性(成员变量)和行为(成员函数)。对象则是类的实例化,是具体的、可以操作的实体。

3、重要概念

1. 封装(Encapsulation)

        封装是通过将数据和操作数据的方法包装在一个对象中,隐藏内部的实现细节,只暴露必要的接口给外部使用。这样可以保证数据的安全性和完整性,并且简化了代码的使用。

2. 继承(Inheritance)

        继承是指一个类(子类/派生类)可以从另一个类(父类/基类)继承属性和方法,并可以在此基础上进行扩展或修改。通过继承,可以实现代码的重用,减少重复编写相似的代码。

3. 多态(Polymorphism)

        多态是指同一个方法可以根据不同的对象产生不同的行为。在继承关系中,子类可以重写父类的方法,并且可以通过父类的引用或指针调用子类的方法,实现了动态绑定和运行时多态。

4. 抽象(Abstraction)

        抽象是指从具体的事物中提取出其共性的特征和行为,形成抽象类或接口。抽象类不能被实例化,只能作为其他类的基类。接口则定义了一组方法的规范,类可以实现接口以满足特定的功能需求。

        通过使用OOP,可以将复杂的问题分解为更小的模块,每个模块都是一个对象,具有自己的属性和行为。对象之间可以通过消息传递进行通信和协作,从而使代码更加模块化、可维护和可扩展。

        值得注意的是,尽管OOP是一种强大的编程范式,但并不是所有问题都适合使用OOP来解决。在实际开发中,需要根据具体情况选择合适的编程范式和方法。

当谈到面向对象编程时,我们经常会遇到以下几个核心概念

下面我将对它们逐一进行解释。

1. 对象(Object)

        对象是面向对象编程的基本概念,它是一个具体的实体,具有状态和行为。对象可以是现实世界中的实际物体,也可以是抽象的概念。例如,一个人、一辆车或一个订单都可以表示为对象。对象具有特定的属性(成员变量)和行为(成员函数),可以通过访问对象的接口来操作它的数据和行为。

2. 类(Class)

        类是对象的抽象描述,是一种用户自定义的数据类型。它定义了对象的属性和行为,包括成员变量和成员函数。类可以看作是创建对象的模板或蓝图,用于定义对象的结构和行为。通过实例化类,可以创建多个具有相同属性和行为的对象。

3. 封装(Encapsulation)

        封装是一种将数据和操作数据的方法捆绑在一起的机制,以隐藏对象的内部实现细节,并通过公共接口提供对对象的访问。封装可以防止外部直接访问对象的状态,只能通过类的公共方法来操作对象。这样做的好处是增加了代码的安全性和可维护性,同时简化了对象的使用。

4. 继承(Inheritance)

        继承是一种创建新类的机制,通过从现有类派生出新的类,新类可以继承原有类的属性和行为。原有类称为父类或基类,新类称为子类或派生类。子类可以通过继承获得父类的属性和方法,并且可以在此基础上进行扩展或修改。继承具有代码重用的优势,可以减少重复编写相似代码的工作量。

5. 组合(Composition)

        组合是一种将多个对象组合成更大的对象的关系。在组合关系中,一个对象包含其他对象作为其部分,被包含的对象不能单独存在。例如,一个汽车对象可以由引擎、轮胎和座椅等部件组合而成。组合关系可以表达整体与部分之间的层次结构,使得对象之间的关系更加灵活和复杂。

6、多态(Polymorphism)

        多态是指同一个方法可以根据不同的对象产生不同的行为。在面向对象编程中,多态通过继承和接口实现。子类可以重写父类的方法,并且可以通过父类的引用或指针调用子类的方法,实现了动态绑定和运行时多态性。

7、动态绑定(Dynamic Binding)

        动态绑定是指在程序运行时确定要调用的具体方法。当使用父类的引用或指针调用子类的方法时,根据实际对象的类型来决定执行哪个方法。这允许通过多态性实现灵活的对象行为。

8、静态绑定(Static Binding)

        静态绑定是指在编译时就确定要调用的方法。当使用对象自身的引用或指针调用方法时,编译器根据引用或指针的类型确定要调用的方法。这种绑定发生在编译时期,称为静态绑定。

9、消息传递(Message Passing)

        消息传递是对象之间通信和协作的方式。一个对象通过向另一个对象发送消息来请求执行某个操作。对象接收到消息后,根据消息的内容执行相应的方法。消息传递是面向对象编程中实现对象间交互的机制。

10、方法(Method)

        方法是类中定义的行为。它是一段可被调用的代码,用于实现特定的功能。方法可以操作对象的数据和状态,并且可以返回结果。在面向对象编程中,对象通过调用方法来执行任务和操作数据。

这些概念共同构成了面向对象编程的基础,它们提供了一种模块化和可扩展的方式来组织和管理代码。通过封装、继承和组合等机制,可以将复杂问题分解为更小的模块,使代码更加可维护、可重用和易于理解。

四、泛型编程

1、基本概念

        泛型编程是一种编程范式,旨在实现代码的通用性和复用性。它允许创建可以适用于多种数据类型的类、函数和数据结构,而不需要为每种数据类型编写重复的代码。

        在泛型编程中,使用泛型(Generics)来表示类型参数,这样可以将具体的类型延迟到代码编译时或运行时确定。通过使用泛型,我们可以编写不依赖于特定类型的代码,从而提高代码的灵活性和可维护性。

        泛型编程由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所发明,目的是为了实现C++的模板库STL ( Standard Template Library标准)。
        C++中的支持机制就是模板(Templates)。模板的实质就是参数化类型,简而言之:把特定的类型信息抽象化,抽象成模板参数T。这样就可以编写出任意类型动作一致的类或方法,在使用时才指定实际类型。泛型一定程度上杜绝了类型转换。

2、特点和优势

1. 代码复用

        泛型编程允许编写可重用的代码,因为代码可以适用于多种数据类型而不需要修改。这减少了重复编写相似代码的工作量,提高了代码的开发效率。

2. 类型安全

        使用泛型可以在编译时捕获类型错误,避免在运行时出现类型不匹配的错误。这提供了更高的类型安全性,减少了潜在的运行时错误。

3. 抽象和通用性

        泛型在很大程度上提高了代码的抽象水平和通用性。通过泛型,可以编写适用于多种数据类型的算法和数据结构,使代码更加灵活和适应不同的场景。

4. 性能优化

        泛型编程可以通过编写通用的高效算法来提高性能。泛型代码通常遵循抽象数据类型的原则,允许进行更多的优化和改进。

在许多编程语言中,包括Java、C++和C#等,都支持泛型编程。这些语言提供了泛型类、泛型函数和泛型接口等机制,以便开发人员使用泛型来实现通用的代码和数据结构。

总之,泛型编程是一种强大的编程范式,通过使用泛型可以提高代码的复用性、类型安全性和灵活性,从而使得程序更加通用、可维护和高效。

3、STL ( Standard Template Library标准模板库)

六大组件

STL(Standard Template Library,标准模板库)是C++标准库的一部分,它提供了一系列通用的模板类和函数,用于实现各种常见的数据结构和算法。STL包括了许多组件,其中最常提到的六大组件分别是:

1. 容器(Containers)

        STL提供了多种容器,如vector、list、deque、set、map等,用于存储和管理数据。这些容器提供了不同的数据组织形式和访问方式,可以满足各种不同的需求。

特殊的数据结构,实现了数组、链表、队列、等等,实质是模板类

2. 算法(Algorithms)

        STL包含了丰富的算法,如排序、搜索、合并等,用于对容器中的数据进行各种操作。这些算法实现了高效的数据处理和操作,开发人员可以直接使用而无需自行实现。

读写容器对象的逻辑算法:排序、遍历、查找、等等,实质是模板函数空间

3. 迭代器(Iterators)

        迭代器是STL中用于遍历容器元素的抽象概念,它提供了统一的访问接口,使得开发人员可以以统一的方式遍历不同类型的容器

一种复杂的指针,可以通过其读写容器中的对象,实质是运算符重载

4. 适配器(Adapters)

        STL中的适配器用于修改或扩展容器或迭代器的行为,例如stack和queue就是适配器,它们提供了基于其他容器的栈和队列功能。

5. 函数对象(Function Objects)

        STL中的函数对象是一种可调用对象,它们可以像函数一样被调用,通常用于算法中作为参数传递,以实现定制的数据处理逻辑。

6. 配置器(Allocators)

        STL中的分配器用于管理内存分配和释放,它允许用户定制容器的内存管理策略,例如使用不同的内存分配策略来满足特定的需求。

这些组件共同构成了STL的核心部分,提供了丰富的数据结构和算法,使得C++开发人员能够更加高效地进行数据处理和操作。利用STL的这些组件,开发人员可以避免从头开始编写数据结构和算法的工作,从而提高了开发效率,并且能够借助STL的优化实现获得高性能的数据处理能力。

组件间的关系

        container(容器)通过allocator(配置器)取得数据储存空间,

        algorithm(算法)通过 iterator(迭代器)存取container(容器)内容,

        functor(函数对象)可以协助algorithm(算法)完成不同的策略变化,

        adapter(适配器)可以修饰或套接functor(函数对象)。

五、编译C++程序

1、基本步骤(与C语言一样)

1、预处理(Preprocessing)

在这一步骤中,编译器会对源代码进行预处理,包括宏展开、头文件包含、条件编译等。预处理后生成一个预处理文件。g++会在源文件中查找以“#”开头的预处理指令,如#include等,并将其替换为对应的内容。可以使用-E参数单独执行预处理并输出结果。

g++ -E hello.cpp -o hello.i

2、编译(Compilation)

g++会将预处理后的文件转化为汇编代码,即将C++源代码转化为汇编语言代码。可以使用-S参数单独执行编译并输出结果。在这一步骤中,编译器会将预处理后的文件翻译成汇编语言,并生成一个汇编代码文件。

g++ -s hello.i -o hello.s

3、汇编(Assembly)

g++会将汇编代码转化为机器码,并生成可重定位目标文件(.o文件),其中包括程序的代码和数据。可以使用-c参数单独执行汇编并输出结果。在这一步骤中,汇编器将汇编代码转换成可执行的目标文件,这个目标文件包含了机器能够直接执行的指令和数据。

g++ -c hello.s -o hello.o

4、链接(Linking)

g++会将多个可重定位目标文件链接成一个可执行文件或共享库。链接的过程包括符号解析、重定位等步骤,以确保程序能够正确地执行。可以使用-o参数指定输出文件名,如果不指定则默认为a.out。 在这一步骤中,链接器将目标文件和库文件链接在一起,生成最终的可执行文件。

g++ hello.o -o a.out

2、编译器

3、详细过程:

1. 预处理

预处理器首先会展开所有的宏定义,替换其中的符号为它们的定义,然后将多个源文件合并成一个单独的文件。接着,预处理器会查找include指令,将所包含的头文件插入到代码中。最后,预处理器会根据条件编译指令判断哪些部分需要被编译或忽略。

2. 编译

编译器将预处理后的文件翻译成汇编语言,这一步骤包括词法分析、语法分析、语义分析和中间代码生成等过程。在词法分析阶段,编译器会将源代码分解成一个个单独的词元,例如关键字、标识符、常量等。接着,在语法分析阶段,编译器会使用语法规则来分析词元之间的关系,生成一棵语法树。在语义分析阶段,编译器会检查语法树是否符合语言规范,并生成中间代码表示程序的语义。

3. 汇编

汇编器将编译器生成的汇编代码转换成机器指令,生成一个目标文件。在这个过程中,汇编器会将汇编代码转换成二进制指令,并为每个符号分配一个地址,以便在链接过程中能够正确地进行符号解析。

4. 链接

链接器将目标文件和库文件链接在一起,生成最终的可执行文件。在这个过程中,链接器会解析所有的符号引用,并将它们与相应的符号定义进行匹配。如果一个符号没有被找到或者有多个符号与之匹配,则链接器会报错。最后,链接器会将所有被链接的目标文件和库文件合并成一个单独的可执行文件。

4、C++程序基本结构

C++程序的基本结构包括以下几个部分:

1. 头文件(Header Files)

头文件通常以".h"或".hpp"为后缀,用于声明和定义类、函数、变量等。头文件中包含了需要在源文件中使用的函数原型、常量定义、类的声明等内容。

2. 主函数(Main Function)

每个C++程序都必须包含一个主函数,即main函数。程序从main函数开始执行,其中包含了程序的入口点和逻辑控制流程。

3. 全局变量(Global Variables)

全局变量是在函数外部声明的变量,它们在整个程序中都可见。可以在任何函数中使用这些全局变量,但需要注意全局变量的作用域和生命周期。

4. 类和对象(Classes and Objects)

C++是一种面向对象的编程语言,支持类和对象的概念。类是一种用户自定义的数据类型,用于封装数据和相关的函数操作。对象是类的实例,通过创建对象来使用类中定义的成员变量和成员函数。

5. 函数(Functions)

函数是一段可重用的代码块,用于执行特定的任务。C++程序中可以包含多个函数,并且可以在其他函数中调用这些函数。

6. 控制语句(Control Statements)

C++提供了多种控制语句,如条件语句(if-else)、循环语句(for、while、do-while)、跳转语句(break、continue、return)等,用于控制程序的执行流程。

7. 输入输出(Input and Output)

C++提供了输入输出流库(iostream),可以使用cin进行标准输入和cout进行标准输出。通过这些流对象,可以进行用户输入的读取和结果的输出。

8. 注释(Comments)

注释是用于给代码添加说明和解释的文本,不会被编译器执行。C++支持单行注释(//)和多行注释(/* ... */),可以提高代码的可读性和可维护性。

5、基本规范

1、源文件扩展名

C++源代码文件的标准扩展名为 ".cpp",也可以使用 ".cc"、".cxx"、".C" 等扩展名。在一些旧的C++编译器中,也可能会使用 ".c" 或 ".h" 扩展名来表示源代码文件。

- .cpp:标准的C++源代码文件扩展名
- .cc:C++源代码文件扩展名,与 ".cpp" 相同
- .cxx:C++源代码文件扩展名,与 ".cpp" 和 ".cc" 相同
- .C:C++源代码文件扩展名,通常用于区分大小写敏感的文件系统
- .h:C++头文件扩展名,包含函数和类的声明等信息
- .hpp:C++头文件扩展名,与 ".h" 相同,但更常用于C++标准库和其他开源库中

不同的编译器可能会对源代码文件扩展名有所差异,最好遵循特定编译器或项目的命名规范。

2、头文件命名规则

在C++中,头文件(Header Files)是用于声明和定义类、函数、变量等的文件,它们通常包含函数原型、常量定义、类的声明等内容。

1. 命名规范

C++头文件通常使用".h"或者".hpp"作为文件扩展名。例如,myheader.h 或者 myheader.hpp。

2. 文件名与类名匹配

如果头文件中定义了一个类,通常情况下会将类名与文件名匹配,以便于维护和识别。例如,如果有一个名为 "MyClass" 的类,则头文件名通常为 "MyClass.h" 或者 "MyClass.hpp"。

3. 全局头文件

对于全局的头文件,尽量避免在其中定义全局变量,因为这样会增加程序的耦合度。全局头文件应该包含必要的函数原型、常量定义和类的声明,但尽量不包含具体的实现细节。

4. 避免使用特殊字符

文件名应该避免使用特殊字符和空格,以确保在不同操作系统上的兼容性。

5. 使用下划线命名法

在命名头文件时,可以使用下划线命名法(例如,my_header_file.h),以提高可读性。

6. 命名可描述性
头文件

头文件的命名应该具有描述性,能够清晰地表达其所包含的内容,并且易于理解和记忆。

六、C++与C的差异性

1、新增变量引用(reference)

       1、 给变量取别名:

#include <iostream>

int main(int argc, char *argv[])
{ 
    int a = 321;
    int &b = a;//给a取别名b
    int c = 110;
    int &d = c;
    //d = b;
    printf("a: %d\n", a);
    printf("b: %d\n", b);
    printf("c: %d\n", c);
    printf("d: %d\n", d);
    return 0;
} 

#include <iostream>

int main(int argc, char *argv[])
{ 
    int a = 321;
    int &b = a;//给a取别名b
    int c = 110;
    int &d = c;
    //d = b;
    printf("a: %d\n", a);
    printf("b: %d\n", b);
    printf("c: %d\n", c);
    printf("d: %d\n", d);
    return 0;
} 

2、引用传参

2、面对条件不同

C:面向过程

        面向过程编程(Procedure Oriented)是以过程为中心,把分析解决问题的步骤流程以函数的形式一步步设计实现。

例:

上学过程()

{        起床

         洗漱

         吃饭

         去学校        }

C++:面向对象

        面向对象编程(OOP)是以事务为中心。一切事物皆对象,通过面向对象的方式,将现实世界的事物抽象成对象。

例:

学生{        属性:

                               姓名

                               年龄

                               班级

                                 ....

                动作:

                                上学

                                放学

                                上课

                                ····                       }

3、新增泛型编程

        支持模板STL ( Standard Template Library标准库)

4、支持异常处理

        核心思想:检错和处理错误分开

5、支持函数和运算符重载

        C++的函数重载是指在同一个作用域内,可以定义多个具有相同名称但参数列表不同的函数。函数重载可以根据不同的参数类型和个数来区分函数,使得函数名在同一个作用域内具有更广泛的适用性。

6、支持名字空间

        用于管理函数名、变量名及类

七、函数

1、函数重载

C++的函数重载是指在同一个作用域内,可以定义多个具有相同名称但参数列表不同的函数。函数重载可以根据不同的参数类型和个数来区分函数,使得函数名在同一个作用域内具有更广泛的适用性。

1.函数重载的特点

- 函数名相同,但参数列表不同。
- 返回值类型不同或者相同。
- 函数重载与函数的返回类型无关。
- 函数重载不能仅通过参数的名称或参数的顺序来区分。

下面是一个示例,展示了函数重载的用法:

#include <iostream>

void print(int num) {
    std::cout << "Printing an integer: " << num << std::endl;
}

void print(double num) {
    std::cout << "Printing a double: " << num << std::endl;
}

void print(const char* str) {
    std::cout << "Printing a string: " << str << std::endl;
}

int main() {
    print(10);                 // 调用print(int)
    print(3.14);               // 调用print(double)
    print("Hello, World!");    // 调用print(const char*)
    
    return 0;
}

在上面的示例中,我们定义了三个名为`print`的函数,分别接受整数、浮点数和字符串作为参数。根据传入的参数类型,编译器能够自动选择调用合适的函数进行处理。在`main`函数中,我们针对不同的参数类型调用了`print`函数,分别打印不同类型的信息。

        函数重载并不仅限于参数类型的不同,还可以根据参数个数进行重载。例如,可以定义一个名为`sum`的函数,实现两个整数相加和三个整数相加的操作,在调用时编译器会根据传入参数的个数来区分使用哪个版本的函数。

函数重载可以提高代码的可读性和灵活性,使得函数在相同的上下文中能够处理更多不同类型的数据。当需要执行类似但略有不同的操作时,可以通过函数重载来减少代码的重复编写。

int sum (int x){
return X+X;
}
int sum (int x, int y){
return x+y;
}
double sum (double x, double y, double z){
return x+y+Z;
}

2、函数默认参数

C++允许赋予函数参数默认值,即在调用该函数时,可以不写某些参数的值,编译器会自动把默认值传递给调用语句中

默认值只能在声明中设置。

注意事项∶
1、不能将实际值传递给引用类型的参数。可以将变量作引用类型参数的默认值,这时变量必须是已经声明且是全局变量
2、若给某一参数设置了默认值,那么在参数表中其后所有的参数都必须也设置默认值
3、在调用时,若给已经设置默认值的参数传递实际值,既要取代默认值,则在参数表中被取代参数的左边所定义的所有参数,无论是否有默认值,都必须传递实际参数

#include <iostream>
int add(int a = 10, int b = 20)
{
    return a+b;
}
int main(int argc, char *argv[])
{ 
    printf("add =  %d\n", add());
    printf("add =  %d\n", add(5));
    printf("add =  %d\n", add(6, 7));
    return 0;
} 

3、结

基本语法:

struct 结构体名{

        成员域1;

        成员域2;

        ...........

                        };

访问权限

        C++语法中相对C语法增加了访问权限的概念,有三种: public、private及protected,默认是public.

        public:        公共成员,表示可以通过结构体变量对象直接访问到成员
        private :        私有成员,表示仅结构体成员函数可以使用的成员
        protected:        保护成员,表示被继承的派生对象可以访问使用的成员

成员函数定义
#include <iostream>
struct Demo{
    public://公有权限 
    int getx(void);//声明
    int setx(int val)
    {
        x = val;
    }
    private://私有权限
    int x;
};
    int Demo::getx(void)//成员函数的定义,在结构体外部定义成员,需要  类名::函数名  限定
    {
        return x;
    }

int main(int argc, char *argv[])
{ 

    return 0;
}

八、作用域

       

 C++支持三种作用域

1、局部域

        局部变量的作用域 { }、()

局部域是包含在函数定义或者函数块中的程序文本部分。

2、类域

       每个类定义都引入了一个独立的类域

class Demo{
    
    void setx(int val)
    {
        x = val;
    }
    
    int getx(void)
    {
        return x;
    }

    int x;//类域

       };

3、名字空间域

名字空间域是不包含在函数声明函数定义或者类定义内的程序文本部分
程序的最外层的名字空间域被称作全局域( global scope),或全局名字空间域(globalnamespace scope)
对象函数类型以及模板都可以在全局域中定义
可以利用名字空间定义namespace definition来定义用户声明的user-declared的名字空间。每个用户声明的名字空间都是一个不同的域,它们都与全局域不同,与全局域相同的是用户声明的名字空间可以包含对象函数类型和模板的声明与定义,以及被嵌套其内的用户声明的名字空间。

#include <iostream>
using namespace std;
namespace A{ //名字空间A
    int i = 123;
    void fun()
    {
        printf("i = %d\n", i);
    }
}

namespace B{ //名字空间B
    int i = 321;
    void fun()
    {
        printf("i = %d\n", i);
    }
}

int main()
{

    A::i = 666;//A的i
    A::fun();//A的fun
    B::i = 888;//B的i
    B::fun(); //B的fun

}

链接性与存储性

1、变量

1、变量的链接性(linkage)

        描述了名称如何在各个单元中的共享。

外部链接:是指名称可以在文件间共享
内部链接:名称仅仅能在一个文件中的函数共享

2、变量的存储性

存储类         作用域        链接性        声明位置

auto             局部域         空                模块内

register        ...                ...                ...

全局变量        全局域        外部       模块之外

static全局        ...               内部        ....

 static局部        局部域        空            模块内

2、函数

1、函数的链接性

函数的存储持续性为静态的
默认的情况下,函数的链接性为外部的要引用函数,可以加extern说明限定符
加static说明限定符的函数,链接性为内部的;如果和外部的函数重名,则静态的函数替换之。非内联函数受单定义规则限制,但是内联函数则不然。C++运行内联函数的定义放在头文件内。不过个内联函数所有的定义必须相同。

        外部链接:全局变量

        内部链接:static的静态函数

3、语言

语言的链接性

对于函数或变量而言,只要有链接性,则每种编程语言,都有自己的规则来处理它们的名字。这个就是语言的链接性。
如果C语言编写的函数需要被C++代码使用到,就要注意到语言的链接性。

extern "C" void hello(const char *) ;// 声明 hello是C函数
extern void hello(const char *);// 声明 hello是C++函数
extern "C++" voidhello(const char *); // 声明 hello是C++函数

/*===============================================
*   文件名称:4.cpp
*   创 建 者:     
*   创建日期:2023年12月13日
*   描    述:
================================================*/
#include <iostream>
extern "C" void hello(const char *);
int main()
{
    printf("Hello C++\n");
    return 0;
}

/*===============================================
*   文件名称:4.c
*   创 建 者:     
*   创建日期:2023年12月13日
*   描    述:
================================================*/
#include <stdio.h>

void hello(const char *h)
{
    printf("%s\n", h);
}

效果:

动态内存

1.new/delete运算符

    new:堆区申请空间

    delete:释放堆区空间

    eg:

        int *p = new int;//在堆区申请int大小的框架

        *p = 123;//给空间赋值123

        delete p;//释放堆区空间

2.new [ ] / delete [ ]    

    eg:

        char *p = new  char [16];  //char ch[16];

        strcpy(p,"hello world");

        delete [] p;

  • 31
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值