【系统学C++】一、从C语言到C++(一)

【系统学C++】一、从C语言到C++(一)

  • C++介绍
    • C语言和C++的联系
    • C++介绍
  • 头文件
  • 命名空间
    • 定义命名空间
    • 使用命名空间中的名称
    • 使用`using`声明或指令
    • 命名空间与C语言的对比
    • 给命名空间起别名
    • 注意事项
    • `std`
  • 标准输入输出
    • `std::endl`
    • 使用`std::cout`进行输出
    • 使用`std::cin`进行输入
    • 格式化输出

C++介绍

C语言和C++的联系

  1. 继承关系:C++是由C语言发展而来的,因此C++与C语言具有很深的渊源和联系。C++在设计时充分考虑了对C语言的兼容性,使得大多数C语言代码都可以不加修改地在C++环境中编译和运行。
  2. 扩展与增强:C++在C语言的基础上增加了许多新的特性和功能,特别是面向对象编程(OOP)的支持,使得C++在编程时更加灵活和强大。这些新增的特性包括类、封装、继承、多态等。
  3. 编译方式:尽管C++已经发展成为一门独立的编程语言,但现有的许多C/C++编译器仍然可以同时支持C和C++代码的编译。这些编译器通过不同的前端处理C和C++的语法和语义,但共享后端和优化器等基础设施。

C++介绍

  1. 基本特性:C++是一种静态类型的、编译式的、通用的、大小写敏感的编程语言,支持过程化编程、面向对象编程和泛型编程。C++被认为是一种中级语言,它综合了高级语言和低级语言的特点。
  2. 面向对象编程:C++完全支持面向对象的程序设计,包括封装、继承、多态和抽象等四大特性。这些特性使得C++在程序设计时更加灵活和易于维护。
  3. 泛型编程:C++支持泛型编程,可以实现代码的复用和泛化。泛型编程的思想是将代码中与数据类型无关的部分抽象出来,形成通用的代码框架,从而实现更高效、更灵活的代码编写。
  4. 标准库:标准的C++由三个重要部分组成:核心语言、C++标准库和标准模板库(STL)。这些库提供了大量的函数和数据结构,用于操作文件、字符串、数据结构等,极大地提高了编程效率。
  5. ANSI标准:为了确保C++的便携性,ANSI标准规定了C++的语法和语义。由于ANSI标准已经稳定使用了很长时间,所有主要的C++编译器的制造商都支持ANSI标准。
  6. 创始人与发展:C++是由Bjarne Stroustrup于1979年在新泽西州美利山贝尔实验室开始设计开发的。最初命名为“带类的C”,后来在1983年更名为C++。

综上所述,C++和C语言虽然都是编程语言,但C++在C语言的基础上增加了许多新的特性和功能,特别是在面向对象编程和泛型编程方面的支持,使得C++在编程时更加灵活和强大。同时,C++也继承了C语言的许多优点,如简洁、高效和可移植性等。

头文件

从C语言到C++的演进中,头文件(header files)的角色和用法也发生了一些变化。在C语言中,头文件主要用于声明函数、变量、宏和类型定义等,以便在多个源文件中共享这些声明。而在C++中,头文件的使用方式与C语言类似,但也有一些扩展和新的特性。

  1. 声明和定义分离

    • 在C++中,通常将类的声明(即类的接口)放在头文件中,而将类的成员函数的具体实现(即定义)放在源文件中。这样可以使头文件更加简洁,并且可以在多个源文件中包含同一个头文件而不会导致多重定义错误。
  2. 包含保护

    • 为了防止头文件被多次包含(即多重包含)导致的编译错误,C++程序员通常会在头文件的开头和结尾使用预处理器指令来创建包含保护。这通常是通过定义一个唯一的标识符(如使用#ifndef, #define, 和 #endif)来实现的。
    // myclass.h
    #ifndef MYCLASS_H
    #define MYCLASS_H// 类的声明
    class MyClass {
    public:// ...
    };#endif // MYCLASS_H
    
  3. 模板和头文件

    • C++中的模板(包括函数模板和类模板)通常需要在头文件中定义,因为模板的实例化是由编译器在编译时完成的,并且需要看到模板的完整定义。因此,模板的头文件通常不仅包含声明,还包含定义。
  4. 命名空间

    • C++引入了命名空间(namespaces)来组织代码,避免命名冲突。在头文件中使用命名空间可以使代码更加清晰,并允许开发者在不同的命名空间中定义相同名称的类或函数。
  5. 内联函数

    • C++支持内联函数(inline functions),这些函数通常在头文件中定义,以便编译器在调用点处内联展开函数体,提高执行效率。
  6. 标准库头文件

    • C++标准库提供了大量的头文件,这些头文件包含了标准库中的类和函数的声明。这些头文件通常以<iostream>, <vector>, <string>等形式包含,与C语言中的标准库头文件(如<stdio.h>, <stdlib.h>)在命名和用法上有所不同。
  7. #pragma once

    • 一些编译器支持#pragma once指令作为包含保护的一种替代方法。这是一个非标准的扩展,但它在许多编译器上都被支持,并且在某些情况下可能比使用#ifndef/#define/#endif更加简洁和方便。

请注意,尽管C++在头文件的使用上有一些新的特性和约定,但C++仍然与C语言兼容,因此许多C语言中的头文件和包含约定在C++中仍然有效。然而,随着C++的发展,许多新的编程风格和最佳实践已经形成,并在现代C++代码中得到了广泛应用。

命名空间

从C语言过渡到C++时,一个显著的特性是C++引入了**命名空间(Namespace)**的概念。命名空间是C++中用于解决命名冲突的一种方法,它允许开发者将相关的名称(如变量名、函数名、类名等)组织在一起,形成一个逻辑上的分组。

定义命名空间

在C++中,你可以使用namespace关键字来定义一个命名空间。例如:

namespace MyNamespace {int variable = 42;void myFunction() {// ...}class MyClass {public:// ...};
}

在这个例子中,我们定义了一个名为MyNamespace的命名空间,并在其中声明了一个整数变量variable、一个函数myFunction()和一个类MyClass

使用命名空间中的名称

要在命名空间外部访问命名空间中的名称,你需要使用作用域解析运算符::。例如:

int main() {std::cout << MyNamespace::variable << std::endl; // 假设我们包含了<iostream>MyNamespace::myFunction();MyNamespace::MyClass obj;// ...return 0;
}

注意,在这个例子中,我们还使用了std命名空间中的cout对象,它是C++标准库中的一个输出流对象。

使用using声明或指令

如果你不想每次都使用作用域解析运算符来访问命名空间中的名称,你可以使用using声明或指令来简化代码。

  • using声明:在局部作用域中引入命名空间中的某个特定名称。
using MyNamespace::myFunction;
myFunction(); // 不需要MyNamespace::前缀
  • using指令:在局部作用域或全局作用域中引入整个命名空间中的所有名称。
using namespace MyNamespace;
myFunction(); // 不需要MyNamespace::前缀
MyClass obj;  // 同样不需要MyNamespace::前缀

但是,过度使用using namespace指令可能会导致命名冲突,特别是在大型项目中,因此通常建议在函数或类的局部作用域中使用它,而不是在全局作用域中。

命名空间与C语言的对比

在C语言中,没有命名空间的概念。为了避免命名冲突,开发者通常会在变量名、函数名等前面加上特定的前缀或后缀来标识它们所属的模块或库。然而,这种方法并不是一种很好的解决方案,因为它可能会导致名称变得冗长且难以阅读。C++的命名空间提供了一种更优雅和灵活的方式来组织和管理代码中的名称。

给命名空间起别名

在编程中,特别是在C++或C#等语言中,你可以给命名空间起别名,以便于更简洁地引用命名空间中的内容。这在命名空间名称较长或需要频繁引用某个命名空间中的元素时特别有用。

在C++中,你可以使用namespace指令与using关键字结合来给命名空间起别名。以下是一个示例:

#include <iostream>namespace VeryLongNamespaceName {void printHello() {std::cout << "Hello from VeryLongNamespaceName!" << std::endl;}
}// 给命名空间起别名
namespace VLNN = VeryLongNamespaceName;int main() {// 使用别名调用命名空间中的函数VLNN::printHello();return 0;
}

在这个例子中,VeryLongNamespaceName 是一个很长的命名空间名称,我们通过 namespace VLNN = VeryLongNamespaceName; 为它创建了一个别名 VLNN。之后,我们就可以通过这个简短的别名来访问命名空间中的内容了。

请注意,起别名时应选择简洁且有意义的名称,以提高代码的可读性。同时,避免使用可能与现有命名空间或类名冲突的别名。

注意事项

  1. 定义与使用位置

    • 命名空间使用namespace关键字声明,并且必须位于其他代码之前(包括任何非PHP代码以及空白符,除了declare关键字)。
    • 命名空间下的类(包括抽象类和traits)、接口、常量和函数会受命名空间影响。
  2. 避免重复定义

    • 在头文件中使用命名空间时,不能定义函数或变量,因为这可能会导致多个源文件中出现重复定义的链接错误。
    • 如果需要在命名空间中定义变量,可以加上staticconstexpr关键字,使其变成静态变量或常量。
    • 如果需要在命名空间中定义函数,可以加上inline关键字,使其变成内联函数。
  3. 结构体和类的定义

    • 在头文件中使用命名空间时,可以定义结构体和类,因为这些不是具体的实例,不会导致链接错误。
  4. using关键字的使用

    • using关键字用于引入命名空间中的符号,以便在代码中直接使用这些符号,而不需要使用完整的命名空间前缀。
    • 使用using关键字时,建议在引用完所有头文件后使用,以避免符号冲突。
    • 尽量避免在头文件中使用using namespace语句,因为这相当于引入了命名空间内的所有元素,可能会导致其他文件使用时出现命名冲突。
  5. 避免全局变量的使用

    • 过多使用全局变量会导致内存占用问题,并可能引发命名冲突,应该尽量避免。
  6. 注意循环和函数调用

    • 尽量减少循环嵌套次数和函数调用次数,以提高程序性能。
  7. 命名空间的合并

    • 允许存在多个相同名称的命名空间,编译器会自动将其合并到同一个命名空间中。
  8. 函数定义的位置

    • 命名空间中的函数,其定义可以放在命名空间内部,也可以放在命名空间外部。放在命名空间外部时,函数前面必须加上命名空间名的前缀。

遵循这些注意事项可以帮助你更好地管理和组织代码,提高代码的可读性和可维护性。

std

在C++中,std 是一个非常重要的命名空间,它包含了C++标准库中的大部分内容。std 是 “standard” 的缩写,表示这个命名空间包含了C++标准所定义的功能和对象。

当你使用C++标准库中的任何功能时,例如输入输出流(如 std::coutstd::cin)、字符串(如 std::string)、容器(如 std::vector, std::map, std::set 等)、算法(如 std::sort, std::find 等)以及其他许多实用工具时,你通常需要使用 std 命名空间。

有几种方法可以访问 std 命名空间中的名称:

  1. 使用作用域解析运算符 ::
    你可以通过 std:: 前缀来明确指定你想要使用的是标准库中的名称。例如:

    std::cout << "Hello, world!" << std::endl;
    std::string s = "Example";
    
  2. 使用 using 声明
    如果你只想在局部作用域中使用某个特定的标准库名称,你可以使用 using 声明。例如:

    using std::cout;
    using std::endl;
    cout << "Hello, world!" << endl;
    

    但请注意,这只会引入 coutendl 到当前作用域,不会引入其他标准库名称。

  3. 使用 using 指令
    如果你希望在当前文件中使用整个 std 命名空间中的所有名称,你可以使用 using 指令。但请注意,这可能会导致命名冲突,特别是当你自己定义的名称与标准库中的名称相同时。因此,在大型项目中通常不推荐这样做。

    using namespace std;
    cout << "Hello, world!" << endl;
    

为了编写清晰、可维护的代码,通常建议只在必要时使用 using 声明,并在整个项目中一致地使用 std:: 前缀来访问标准库名称。这有助于避免命名冲突,并使代码更易于阅读和理解。

此外,C++标准库还包含了许多头文件,你需要通过包含这些头文件来使用标准库中的功能。例如,要使用输入输出流,你需要包含 <iostream> 头文件;要使用字符串,你需要包含 <string> 头文件;要使用容器和算法,你需要包含 <vector>, <map>, <set>, <algorithm> 等头文件。

标准输入输出

在C++中,标准输入输出是通过预定义的流对象来实现的,这些对象分别是std::cin(用于输入)和std::cout(用于输出)。这两个对象都是C++标准库<iostream>中的一部分。

std::endl

std::endl 是 C++ 标准库 <iostream> 中定义的一个操纵符(manipulator),它通常与输出流(如 std::cout)一起使用,以在输出中添加一个新行,并立即刷新输出缓冲区。

源码:

_EXPORT_STD template <class _Elem, class _Traits>
basic_ostream<_Elem, _Traits>& __CLRCALL_OR_CDECL endl(basic_ostream<_Elem, _Traits>& _Ostr) { // insert newline and flush stream_Ostr.put(_Ostr.widen('\n'));_Ostr.flush();return _Ostr;
}

std::endl 的功能主要有两个:

  1. 添加新行:在输出的末尾添加一个换行符(在 Unix/Linux 系统中是 \n,在 Windows 中是 \r\n),这样下一次的输出就会从新的一行开始。
  2. 刷新缓冲区:调用 std::endl 后,输出缓冲区会被立即刷新,确保到目前为止所有的输出都被发送到它们的目标位置(如控制台、文件等)。如果不刷新缓冲区,输出可能会被缓存起来,直到缓冲区满或遇到其他导致刷新的操作。

使用 std::endl 的一个常见例子是:

#include <iostream>int main() {std::cout << "Hello, World!" << std::endl;std::cout << "This is a new line." << std::endl;return 0;
}

在这个例子中,std::endl 确保了 “Hello, World!” 和 “This is a new line.” 分别在新的一行输出,并且每个字符串之后都立即刷新了输出缓冲区。

然而,需要注意的是,频繁地刷新输出缓冲区可能会影响程序的性能,因为刷新操作通常是相对昂贵的。因此,在不需要立即看到输出或不需要确保输出顺序的情况下,可以使用 \n 代替 std::endl 来避免不必要的刷新。例如:

std::cout << "Hello, World!\n";
std::cout << "This is a new line.\n";
// 输出缓冲区不会被立即刷新

使用std::cout进行输出

std::cout是一个输出流对象,它允许你将数据发送到标准输出设备(通常是终端或控制台)。你可以使用插入运算符(<<)将数据发送到std::cout

示例:

#include <iostream>int main() {std::cout << "Hello, World!" << std::endl;return 0;
}

使用std::cin进行输入

std::cin是一个输入流对象,它允许你从标准输入设备(通常是键盘)读取数据。你可以使用提取运算符(>>)从std::cin读取数据。

示例:

#include <iostream>int main() {int num;std::cout << "Enter a number: ";std::cin >> num;std::cout << "You entered: " << num << std::endl;return 0;
}

在上面的示例中,程序首先输出一个提示消息,然后等待用户输入一个整数。当用户输入一个整数后,程序读取该整数并将其存储在变量num中,然后输出该整数。

格式化输出

C++标准库提供了许多操纵符来控制输出的格式。例如,你可以使用std::setwstd::setfill来设置字段宽度和填充字符,或者使用std::fixedstd::setprecision来设置浮点数的输出格式。

示例(设置字段宽度和填充字符):

#include <iostream>
#include <iomanip> // 引入iomanip头文件以使用setw和setfillint main() {int num = 123;std::cout << std::setw(5) << std::setfill('0') << num << std::endl; // 输出:00123return 0;
}

示例(设置浮点数的输出格式):

#include <iostream>
#include <iomanip> // 引入iomanip头文件以使用fixed和setprecisionint main() {double pi = 3.14159265358979323846;std::cout << std::fixed << std::setprecision(2) << pi << std::endl; // 输出:3.14return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/25783.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

EGST:Explicit Geometric Structure Transformer论文解读

目录 一、导言 二、相关工作 1、3D局部描述子 2、点云配准方法 三、EGST模型 1、结构化特征 2、特征提取 3、点云匹配 4、变换估计 5、损失函数 四、实验 1、数据集 2、评估指标 3、细节 4、对比实验 一、导言 该论文提出一种基于增强几何结构特征的点云配准方…

flutter image_picker 执行拍照的图片怎么保存到本地

在 Flutter 中&#xff0c;使用 image_picker 插件拍照的图片默认会被保存到设备的临时目录中。这个临时目录的具体位置取决于设备的操作系统。在 iOS 上&#xff0c;它通常是应用的沙盒目录&#xff1b;在 Android 上&#xff0c;它通常是应用的缓存目录。 这些图片不会被自动…

C语言详解文件操作

目录 什么是文件&#xff1f; 为什么使用文件&#xff1f; 程序文件和数据文件、文本文件和二进制文件 1.程序文件和数据文件 1.1程序文件 1.2数据文件 2.文本文件和二进制文件 文件的打开和关闭&#xff08;流、标准流、文件指针和文件的打开与关闭&#xff09; 1.流和标…

Web前端管理系统项目:深度解析与实现之道

Web前端管理系统项目&#xff1a;深度解析与实现之道 在当今数字化时代&#xff0c;Web前端管理系统项目已成为企业信息化建设的核心组成部分。这类项目不仅涉及技术的深度和广度&#xff0c;更考验开发者的综合素质和创新能力。本文将从四个方面、五个方面、六个方面和七个方…

希尔排序(Shell_sort)

希尔排序常用于插入排序的数据预处理&#xff0c;用于提升插入排序的大数据处理速度 将插入排序的函数改为n递增即可使用希尔排序 间隔为n的插入排序&#xff1a; 将i初始值改为1&#xff0c;然后j循环所有的1改为n即可 void Insertion_sort(int *arr,int size,int n) {int…

有点好玩的python运维脚本

python运维脚本 1. 常用端口扫描2. 文件整理 1. 常用端口扫描 在计算机网络中&#xff0c;端口是一个通信端点&#xff0c;允许不同的进程或服务通过网络连接和交换数据。端口通过数值来标识&#xff0c;并与特定的协议相关联。未采取适当安全措施而保持端口开放&#xff0c;可…

InternLM Xtuner Qlora 微调

Xtuner 简介 XTuner 是由上海人工智能实验室开发的一款低成本大模型训练工具箱。它以高效、灵活和全能的特性&#xff0c;成为轻量化大模型微调的理想选择。借助 XTuner&#xff0c;用户仅需 8GB 显存即可对 InternLM2-7B 模型进行微调&#xff0c;从而定制出独一无二的 AI 助手…

C++~~期末复习题目讲解---lijiajia版本

目录 1.类和对象 &#xff08;3&#xff09;创建对象的个数 &#xff08;3&#xff09;全局变量&#xff0c;局部变量 &#xff08;4&#xff09;构造函数的执行次数 &#xff08;5&#xff09;静态动态析构和构造顺序 &#xff08;6&#xff09;初始化顺序和声明顺序 &a…

安装systemd-bootchart

要安装systemd-bootchart&#xff0c;你可以按照以下步骤进行&#xff1a; 步骤一&#xff1a;更新软件包列表 首先&#xff0c;打开终端并更新你的软件包列表&#xff0c;以确保你拥有最新的可用软件包信息。运行以下命令&#xff1a; sudo apt update步骤二&#xff1a;安…

Git使用总结(git使用,git实操,git命令和常用指令)

简介&#xff1a;Git是一款代码版本管理工具&#xff0c;可以记录每次提交的代码&#xff0c;防止代码丢失&#xff0c;可实现版本迭代&#xff0c;解决代码冲突&#xff0c;常用的远程Git仓库&#xff1a;Gitee&#xff08;国内&#xff09;、GitHub&#xff08;国外&#xff…

接口请求的六种常见方式详解(get、post、head等)

一&#xff0e;接口请求的六种常见方式&#xff1a; 1、Get 向特定资源发出请求&#xff08;请求指定页面信息&#xff0c;并返回实体主体&#xff09; 2、Post 向指定资源提交数据进行处理请求&#xff08;提交表单、上传文件&#xff09;&#xff0c;又可能导致新的资源的建…

封装console

目的 1. 封装console.log , 使得打印更美观方便 2. 同时希望上线后不在打印消耗资源 例图&#xff1a; export const prettyLog () > {const isProduction import.meta.REACT_APP_ENV "prod";const isEmpty (value) > {return value null || val…

【C++关键字】指针空值nullptr(C++11)

指针空值nullptr&#xff08;C11&#xff09; C98中的指针空值C11中的指针空值 C98中的指针空值 在学习C语言阶段&#xff0c;由良好的C\C编程习惯&#xff0c;声明一个变量时最好给该变量一个合适的初始值&#xff0c;否则会出现未初始化的指针&#xff0c;野指针等情况。 in…

Flutter 实现dispose探测控件

文章目录 前言一、什么是dispose探测控件&#xff1f;1、通常情况2、使用dispose探测控件 二、如何实现1、继承StatefulWidget2、定义dipose回调3、定义child4、重载Dispose方法5、build child 三、完整代码四、使用示例1、基本用法2、设置定义数据 总结 前言 开发flutter一般…

Java 期末复习 习题集

&#x1f496; 单选题 &#x1f496; 填空题 &#x1f496; 判断题 &#x1f496; 程序阅读题 1. 读代码写结果 class A {int m 5;void zengA(int x){m m x;}int jianA(int y){return m - y;} }class B extends A {int m 3;int jianA(int z){return super.jianA(z) m;} …

Mybatis面试题系列四

1、通常一个Xml映射文件&#xff0c;都会写一个Dao接口与之对应&#xff0c; 请问&#xff0c;这个Dao接口的工作原理是什么&#xff1f;Dao接口里的方法&#xff0c; 参数不同时&#xff0c;方法能重载吗&#xff1f; Dao 接口即 Mapper 接口。接口的全限名&#xff0c;就是映…

Chapter 6 Frequency Response of Amplifiers

Chapter 6 Frequency Response of Amplifiers 这一节我们学习单极和差分运放的频率响应. 6.1 General Considerations 我们关心magnitude vs 频率, 因此有低通, 带通, 高通滤波器 6.1.1 Miller Effect Miller’s Theorem 考虑impedance Z1和Z2, X和Y之间增益为Av. Z1 Z/(…

spring 启动顺序

BeanFactoryAware 可在Bean 中获取 BeanFactory 实例 ApplicationContextAware 可在Bean 中获取 ApplicationContext 实例 BeanNameAware 可以在Bean中得到它在IOC容器中的Bean的实例的名字。 ApplicationListener 可监听 ContextRefreshedEvent等。 CommandLineRunner 整…

数据结构与算法笔记:基础篇 - 二叉树基础(下):有了如此高效的散列表,为什么还需要二叉树?

概述 上篇文章&#xff0c;我们学习了树、二叉树及二叉树的遍历&#xff0c;本章来学习一种特殊的二叉树&#xff0c;二叉查找树。二叉查找树最大的特点就是&#xff0c;支持动态数据集合的快速插入、删除、查找操作。 之前说过&#xff0c;散列表也是支持这些操作的&#xf…

盘点2024年5月Sui生态发展,了解Sui近期成长历程!

2024年5月是Sui的第一个生日月&#xff0c;Sui迎来了它的上线一周年纪念日。在过去的一年中Sui在技术进步与创新、生态系统的扩展、社区发展与合作伙伴关系以及重大项目和应用推出方面取得重要进展&#xff0c;展示了其作为下一代区块链平台的潜力。 以下是Sui的近期成长历程集…