【C++】入门(一)

在这里插入图片描述

前言:
本篇博客将带大家认识C++,熟悉基本语法


文章目录

  • 认识C++
    • C++的诞生与发展
    • C++ 在行业中的运用
  • 一、命名空间
    • 1.1 命名空间的定义
    • 1.2 命名空间的使用
    • 1.3 命名空间的访问
  • 二、C++输入&输出
    • 输出操作符 `<<`
    • 输入操作符 `>>`
    • 换行符和刷新输出缓冲区
    • 关键字 using
  • 三、缺省参数
    • 3.1 概念
    • 3.2 缺省参数分类
  • 四、函数重载
    • 概念
    • 函数重载的原理

认识C++

C++的诞生与发展

C++ 是由丹麦计算机科学家贝尔纳斯·斯特劳斯特博士(Bjarne Stroustrup)于20世纪80年代初期开发的。他在贝尔实验室工作时,对 C 语言进行了扩展,加入了OOP(object oriented programming:面向对象)思想,从而诞生了 C++。C++ 的名字中的 “++” 表示在 C 语言的基础上的一个增量,暗示这是对 C 的增强和扩展。因此:它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计。

C++ 在其发展过程中经历了多个标准版本的发布,其中最早的标准是于1998年发布的 C++98,之后又有 C++03、C++11、C++14、C++17 和 C++20 等版本。每个版本都引入了新的特性和改进,使得 C++ 成为一个强大而灵活的编程语言。

" C with Classes" 是 C++ 的前身,这个术语最初用于描述贝尔纳斯·斯特劳斯特博士在开发 C++ 时的初期版本。C++ 最初是在 C 语言的基础上引入了一些面向对象编程的概念,而 “C with Classes” 就是这个过渡阶段的命名。

C++ 在行业中的运用

  1. 系统级编程: C++ 被广泛用于开发操作系统、驱动程序和其他系统级软件,因为它提供了对硬件的底层访问和高效的系统编程能力。

  2. 游戏开发: 许多游戏引擎和大型游戏项目都使用 C++。其高性能和底层控制使其成为游戏行业的首选语言之一。

  3. 嵌入式系统: C++ 被用于开发嵌入式系统,如智能家居设备、汽车控制系统等。它的效率和灵活性使其适用于资源受限的环境。

  4. 金融领域: 在金融行业,C++ 被广泛用于开发高性能的交易系统、风险管理工具和其他金融应用。

  5. 图形界面应用: C++ 被用于开发桌面应用程序、图形用户界面(GUI)和各种图形软件。

  6. 网络编程: C++ 的网络库和框架使其成为开发网络应用和服务器端程序的理想选择。

C++ 以其高性能、灵活性和底层控制能力,成为许多领域中首选的编程语言之一。


一、命名空间

命名空间(Namespace)是一种在C++中用于组织和封装代码的机制。它允许将一组相关的标识符(如变量、函数、类等)封装在一个逻辑单元中,目的是对标识符的名称进行本地化,以避免命名冲突或名字污染。命名空间可以被定义在全局作用域或其他命名空间内。

1.1 命名空间的定义

语法:

namespace 名称 {// 命名空间内的代码块// 变量、函数、类的声明和定义等
}
  1. 命名空间中可以定义变量/函数/类型

    namespace Namespace {// 变量int rand = 10;//函数int Add(int left, int right) {return left + right;}//类型struct Node {struct Node* next;int val;};
    }
    
  2. 命名空间可以嵌套

    // 外层命名空间
    namespace N1{int a;int Add(int left, int right){return left + right;}// 内层命名空间namespace N2{int c;int Sub(int left, int right){return left - right;}}
    }
    
  3. C++ 允许命名空间的逐渐定义,而多个定义会在编译时进行合并,确保同一命名空间内的内容是唯一的。
    在这个例子中,num3 命名空间的两个部分分别定义在不同的文件中,但它们最终会在编译时合并成为一个包含两个成员的命名空间。

    // 文件1.cpp
    namespace num3 {int rand = 3;
    }// 文件2.cpp
    namespace num3 {int y = 4;
    }
    

1.2 命名空间的使用

以下是一些常见的命名空间的使用场景和实践:

  1. 避免全局命名冲突: 命名空间允许将相关的标识符封装在一个独立的逻辑单元中,从而避免与其他代码中的相同名称的标识符发生冲突。这对于大型项目或多人协作的代码库非常重要。

    // 定义命名空间
    namespace MyNamespace {int myVariable;void myFunction();class MyClass { /* ... */ }
    }
    
  2. 组织和模块化代码: 命名空间使得代码更加模块化和易于组织。通过将相关的功能放置在同一个命名空间中,代码结构更加清晰,对于代码的理解和维护更加方便。

    // 在项目中的不同文件中使用同一个命名空间
    // File1.cpp
    namespace Math {int add(int a, int b);
    }// File2.cpp
    namespace Math {int subtract(int a, int b);
    }
    
  3. 防止全局污染: 将标识符限定在命名空间中,避免了全局命名空间的污染。这样有助于控制和隔离代码的影响范围。

    // 不使用命名空间的情况
    int globalVariable;// 使用命名空间
    namespace MyNamespace {int myVariable;
    }
    
  4. 版本控制: 在不同的版本中,可以使用命名空间来隔离和管理不同版本的功能或接口,以确保向后兼容性或易于升级。

    // Version 1
    namespace MyApp_v1 {void someFunction();
    }// Version 2
    namespace MyApp_v2 {void someFunction();void newFunction();
    }
    
  5. 解决命名冲突: 当使用第三方库或合作开发时,可能会遇到不同部分使用相同名称的情况。使用命名空间可以帮助解决这些命名冲突。

    // 第三方库的命名空间
    namespace ExternalLibrary {void commonFunction();
    }// 项目的命名空间
    namespace MyProject {void commonFunction();void myFunction();
    }
    

1.3 命名空间的访问

命名空间的成员可以通过作用域解析运算符 :: 进行访问。通过 :: 运算符,你可以指定要访问的命名空间的名称,从而使用其中的变量、函数或类等成员。

以下是一些命名空间访问的示例:

通过 MyNamespace::,我们可以访问命名空间 MyNamespace 中的变量、函数和类。这样的方式可以有效地避免全局命名冲突,同时使得代码更具可读性。

// 定义命名空间
namespace MyNamespace {int myVariable = 42;void myFunction() {// 函数定义}class MyClass {// 类定义}
}int main() {// 访问命名空间中的变量int value = MyNamespace::myVariable;// 访问命名空间中的函数MyNamespace::myFunction();// 访问命名空间中的类MyNamespace::MyClass myObject;return 0;
}

通过 NS1:: 和 NS2:: 分别指定了要访问的命名空间,从而区分了两个同名的变量。

namespace NS1 {int x;
}namespace NS2 {int x;
}int main() {// 访问不同命名空间中的同名变量int value1 = NS1::x;int value2 = NS2::x;return 0;
}

当你有一个嵌套的命名空间结构时。在这个示例中,OuterNamespace 是外层命名空间,InnerNamespace 是内层命名空间。通过作用域解析运算符 ::,我们可以访问这两个命名空间中的变量。value1 获取了外层命名空间的变量值,而 value2 获取了内层命名空间的变量值。

// 外层命名空间
namespace OuterNamespace {int outerVariable = 42;// 内层命名空间namespace InnerNamespace {int innerVariable = 10;}
}int main() {// 访问外层命名空间的变量int value1 = OuterNamespace::outerVariable;// 访问内层命名空间的变量int value2 = OuterNamespace::InnerNamespace::innerVariable;return 0;
}

二、C++输入&输出

C++ 中的输入和输出操作符是 <<(输出操作符)和 >>(输入操作符)。这些操作符用于在控制台或文件中进行输入和输出操作。

std 是C++标准库(Standard Library)的命名空间,coutcinendl 是C++标准库中命名空间std的对象,它们属于输入输出流相关的头文件 <iostream> 中的一部分。

输出操作符 <<

在C++中,<< 是输出流操作符,用于将右侧的数据插入到左侧的输出流中(通常是标准输出流,即屏幕)。std::cout 是标准输出流对象,<< 将数据输出到流中。多个 << 操作符可以串联使用,将多个数据输出到同一个流中。

#include <iostream>int main() {int number = 42;std::cout << "The value of number is: " << number << std::endl;return 0;
}

输入操作符 >>

在C++中,>> 是输入流操作符,用于从流中读取数据。std::cin 是标准输入流对象,>> 从流中读取数据并存储在 number 变量中。

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

换行符和刷新输出缓冲区

std::endl 是C++标准库中的一个操作符,用于表示换行符和刷新输出缓冲区。它实际上是一个函数模板,定义在头文件 中,并属于 std 命名空间。

使用 std::endl 可以在输出流中插入一个换行符,并确保输出缓冲区被刷新。刷新输出缓冲区是为了确保立即将输出内容显示在屏幕上,而不是等待缓冲区被填满或遇到显式的刷新操作。等效地,也可以使用 '\n' 来表示换行符。

#include <iostream>int main() {int number = 42;// 使用 std::endl 插入换行符并刷新输出缓冲区std::cout << "The value of number is: " << number << std::endl;return 0;
}

关键字 using

使用 using 关键字可以展开命名空间中的标识符,使其在代码中更直接可用,而不需要显式加上命名空间的前缀。

以下是使用 using 展开命名空间的示例:

#include <iostream>// 使用 using 展开命名空间
using namespace std;int main() {// std::cout 可以直接使用为 coutcout << "Hello, World!" << endl;return 0;
}

需要注意的是,虽然 using namespace std; 提供了方便,但在大型项目中或与其他库集成时,可能会引入潜在的命名冲突。为了避免这些问题,一种更安全的方式是只使用需要的特定标识符,而不是整个命名空间。例如:

#include <iostream>// 使用 using 展开需要的标识符
using std::cout;
using std::endl;int main() {// 直接使用展开后的标识符cout << "Hello, World!" << endl;return 0;
}

三、缺省参数

3.1 概念

缺省参数(default parameters)允许在函数声明中为一个或多个参数指定默认值。这意味着在调用函数时,如果没有提供相应的参数值,将使用该参数的默认值

void Func(int a = 0){cout << a << endl;
}int main(){Func();     // 没有传参时,使用参数的默认值Func(10);   // 传参时,使用指定的实参return 0;
}

3.2 缺省参数分类

函数的参数可以全部使用缺省参数,也可以部分使用缺省参数,实现全缺省参数和半缺省参数的效果。

全缺省参数:
printInfo 函数的所有参数都使用了缺省参数,可以在调用时不提供任何参数值,或者提供部分或全部参数值。

#include <iostream>// 函数声明时全部使用缺省参数
void printInfo(int a = 1, int b = 2, int c = 3);int main() {// 调用函数时不提供任何参数值,使用了所有参数的默认值printInfo();// 提供部分参数值printInfo(4);// 提供所有参数值,不使用默认值printInfo(7, 8, 9);return 0;
}// 函数定义时也使用全部缺省参数
void printInfo(int a, int b, int c) {std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}

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

#include <iostream>// 函数声明时部分使用缺省参数
void printInfo(int a, int b = 2, int c = 3);int main() {// 调用函数时提供所有参数值,不使用默认值printInfo(7, 8, 9);// 提供部分参数值printInfo(4);// 调用函数时不提供任何参数值,使用了第一个参数的默认值printInfo();return 0;
}// 函数定义时也使用部分缺省参数
void printInfo(int a, int b, int c) {std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}

需要注意的是, 缺省参数应避免函数声明和定义中同时出现,当缺省参数在函数声明和定义中同时出现时,编译器会面临二义性的问题

如果缺省参数在函数声明和定义中同时出现:

  • 编译阶段:

    • 编译器首先会处理声明,其中包含缺省参数的值。这个信息在汇编代码中被保存。
    • 接着,编译器会处理定义,其中也包含缺省参数的值。
  • 链接阶段:

    • 链接器需要解析符号,即函数名和参数列表。但现在存在两个相同的函数符号,一个来自声明,一个来自定义。
    • 缺省参数的值在编译阶段已经确定,但由于声明和定义提供了相同的信息,链接器无法准确地选择应该使用哪个缺省参数的值。

因此,在声明和定义中同时出现缺省参数会导致链接阶段的二义性,编译器无法确定应该使用哪个值,从而引发错误。为了避免这种情况,建议在声明中指定缺省参数的值,而在定义中不再提供。这样,在链接阶段,编译器就能够使用声明中的默认值。


四、函数重载

概念

函数重载是指在同一个作用域内定义多个同名函数,但它们的参数列表 (包括参数的类型、顺序或数量)不同

#include <iostream>using namespace std;// 重载函数,按类型
void print(int x) {cout << "Integer: " << x << endl;
}void print(double x) {cout << "Double: " << x << endl;
}// 重载函数,参数个数不同
void display(int x) {cout << "Display Integer: " << x << endl;
}void display(int x, double y) {cout << "Display Integer and Double: " << x << ", " << y << endl;
}// 重载函数,参数顺序不同
void show(double x, int y) {std::cout << "Show Double and Integer: " << x << ", " << y << endl;
}void show(int x, double y) {cout << "Show Integer and Double: " << x << ", " << y << endl;
}int main() {// 函数按类型重载print(42);       // 调用第一个 print 函数print(3.14);     // 调用第二个 print 函数// 函数参数个数不同重载display(10);                   // 调用第一个 display 函数display(20, 3.5);              // 调用第二个 display 函数// 函数参数顺序不同重载show(2.5, 15);                 // 调用第一个 show 函数show(7, 4.2);                  // 调用第二个 show 函数return 0;
}

函数重载的原理

C++中使用名称修饰来实现函数重载。而在C语言中,并不使用名称修饰的方式,函数名是直接暴露的,因此C语言不支持函数重载

函数重载的编译阶段和链接阶段:

  1. 编译阶段:

    • 函数定义: 在源代码中,定义了多个同名但参数列表不同的函数,即进行函数重载。例如:

      void print(int x);
      void print(double x);
      
    • 名称修饰: 编译器在编译阶段根据函数的名称和参数列表生成唯一的名称修饰后的标识符。这个过程被称为名称修饰或符号修饰。

      • 例如,生成的标识符可能为 _Z5printi_Z5printd
    • 生成目标文件: 编译器将源代码编译成目标文件(通常是 .o 文件),其中包含了函数的名称修饰后的标识符。

  2. 链接阶段:

    • 符号表生成: 在链接阶段,链接器将汇总所有目标文件中的符号,创建一个符号表。符号表记录了函数和变量名与其对应的地址或标识符。

      • 符号表可能包含了 _Z5printi_Z5printd 这样的名称修饰后的标识符。
    • 解析函数调用: 当程序中有函数调用时,链接器查找符号表,尝试解析函数名。

      • 如果有一个唯一匹配的标识符,链接器确定正确的函数地址或标识符。
    • 写入可执行文件: 链接器将正确的函数地址或标识符写入最终的可执行文件中,确保在运行时能够正确调用相应的函数。

  3. 运行时:

    • 函数调用: 当程序运行时,根据函数调用,执行相应的函数。函数的具体实现取决于编译时和链接时确定的地址或标识符。

函数重载的过程涉及编译阶段和链接阶段:编译阶段中,编译器根据函数的名称和参数列表生成唯一的名称修饰后的标识符,汇总所有标识符并创建一个符号表;链接阶段中,链接器通过符号表解析函数调用,将正确的函数地址或标识符写入最终的可执行文件,确保在运行时能够正确调用相应的函数。


在这里插入图片描述
如果你喜欢这篇文章,点赞👍+评论+关注⭐️哦!
欢迎大家提出疑问,以及不同的见解。

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

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

相关文章

跟着我学Python进阶篇:03. 面向对象(下)

往期文章 跟着我学Python基础篇&#xff1a;01.初露端倪 跟着我学Python基础篇&#xff1a;02.数字与字符串编程 跟着我学Python基础篇&#xff1a;03.选择结构 跟着我学Python基础篇&#xff1a;04.循环 跟着我学Python基础篇&#xff1a;05.函数 跟着我学Python基础篇&#…

java实现将集合数据导入excel表格之竖向

这里使用的是apache.poi&#xff0c;当然如果使用easyExcel也可以实现 括号是EasyExcel官网&#xff08;EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel&#xff09; 找到填充&#xff0c;都会有相对应的demo实列 下面是我写的apache.poi实现代码 public static vo…

初学python系列: pandas操作excel

媳妇工作中经常用到excel处理&#xff0c;想用python处理excel更高效&#xff0c;所以自学了python&#xff0c;觉得python比Java还是简单多了&#xff0c;没有变量类型声明&#xff0c;比Java也就多了元组&#xff0c;各种库很丰富。 需求是&#xff1a; 汇总两个excel中 列&…

2024年 复习 HTML5+CSS3+移动web 笔记 之CSS遍

28-第三天课程介绍_哔哩哔哩_bilibili CSS 第一天 1.1 引入方式 1.2 选择器 1.3 画盒子 div 独占一行 1.4 文字控制 div 外层 1.5 调试工具 F12 1.5 综合案例 一 新闻详情 1.6 综合案例 二 CSS 简介 CSS 第二天 2.1 复合选择器 2.2 伪类选择器 2.3 CSS 特性 2.4 Emmet 写法 2.5…

JavaEE 网络原理

JavaEE 网络原理 文章目录 JavaEE 网络原理1. 网络互连1.1 局域网LAN1.2 广域网WAN 2. 网络通信基础2.1 IP地址2.2 端口号 3. 网络协议3.1 概念3.2 五元组3.3 协议分层3.4 TCP/IP 五层模型3.5 封装和分用 1. 网络互连 随着时代的发展&#xff0c;需要多个计算机协同工作来完成…

Pix2Pix理论与实战

本文为&#x1f517;365天深度学习训练营 中的学习记录博客 原作者&#xff1a;K同学啊|接辅导、项目定制 我的环境&#xff1a; 1.语言&#xff1a;python3.7 2.编译器&#xff1a;pycharm 3.深度学习框架Pytorch 1.8.0cu111 一、引入 在之前的学习中&#xff0c;我们知道…

Haar小波下采样模块

论文原址&#xff1a;Haar wavelet downsampling: A simple but effective downsampling module for semantic segmentation - ScienceDirect 原文代码&#xff1a;HWD/HWD.py at main apple1986/HWD (github.com) 介绍 深度卷积神经网络 &#xff08;DCNN&#xff09; 通…

springboot中一些注解

springboot中一些注解 1:项目启动时会去扫描启动的注解&#xff0c;一般是启动时就想要被加载的方法&#xff1a; 2:springBoot中MSApplication启动类的一些其他注解&#xff1a; EnableAsync&#xff1a;这是一个Spring框架的注解&#xff0c;它用于开启方法异步调用的功能。当…

2017年认证杯SPSSPRO杯数学建模B题(第一阶段)岁月的印记全过程文档及程序

2017年认证杯SPSSPRO杯数学建模 跨年龄人脸识别模型的建立与分析 B题 岁月的印记 原题再现&#xff1a; 对同一个人来说&#xff0c;如果没有过改变面容的疾病、面部外伤或外科手术等经历&#xff0c;年轻和年老时的面容总有很大的相似性。人们在生活中也往往能够分辨出来两…

2.【SpringBoot3】用户模块接口开发

文章目录 开发模式和环境搭建开发模式环境搭建 1. 用户注册1.1 注册接口基本代码编写1.2 注册接口参数校验 2. 用户登录2.1 登录接口基本代码编写2.2 登录认证2.2.1 登录认证引入2.2.2 JWT 简介2.2.3 登录功能集成 JWT2.2.4 拦截器 3. 获取用户详细信息3.1 获取用户详细信息基本…

一周时间,开发了一款封面图生成工具

介绍 这是一款封面图的制作工具&#xff0c;根据简单的配置即可生成一张好看的封面图&#xff0c;目前已有七款主题可以选择。做这个工具的初衷来自平时写文章&#xff0c;都为封面图发愁&#xff0c;去图片 网站上搜索很难找到满意的&#xff0c;而且当你要的图如果要搭配上文…

【JavaEE进阶】 关于⽇志框架(SLF4J)

文章目录 &#x1f333;SLF4j&#x1f332;⻔⾯模式(外观模式)&#x1f6a9;⻔⾯模式的定义&#x1f6a9;⻔⾯模式的优点 &#x1f343;关于SLF4J框架&#x1f6a9;不引⼊⽇志⻔⾯&#x1f6a9;引⼊⽇志⻔⾯ ⭕总结 &#x1f333;SLF4j SLF4J不同于其他⽇志框架,它不是⼀个真正…

构建高效外卖系统:技术实践与代码示例

外卖系统在现代社会中扮演着重要的角色&#xff0c;为用户提供了便捷的用餐解决方案。在这篇文章中&#xff0c;我们将探讨构建高效外卖系统的技术实践&#xff0c;同时提供一些基础的代码示例&#xff0c;帮助开发者更好地理解和应用这些技术。 1. 技术栈选择 构建外卖系统…

BP蓝图映射到C++笔记1

教程链接&#xff1a;示例1&#xff1a;CompleteQuest - 将蓝图转换为C (epicgames.com) 1.常用的引用需要记住&#xff0c;如图所示。 2.蓝图中可以调用C函数&#xff0c;也可以实现C函数 BlueprintImplementableEvent:C只创建&#xff0c;不实现&#xff0c;在蓝图中实现 B…

C++提高编程---模板---类模板

目录 一、类模板 1.模板 2.类模板的作用 3.语法 4.声明 二、类模板和函数模板的区别 三、类模板中成员函数的创建时机 四、类模板对象做函数参数 五、类模板与继承 六、类模板成员函数类外实现 七、类模板分文件编写 八、类模板与友元 九、类模板案例 一、类模板 …

软件测试的需求人才越来越多,为什么大家还是不太愿意走软件测试的道路?

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

【动态规划】【C++算法】801. 使序列递增的最小交换次数

作者推荐 【动态规划】【广度优先搜索】【状态压缩】847 访问所有节点的最短路径 本文涉及知识点 动态规划汇总 数组 LeetCode801使序列递增的最小交换次数 我们有两个长度相等且不为空的整型数组 nums1 和 nums2 。在一次操作中&#xff0c;我们可以交换 nums1[i] 和 num…

路飞项目--03

二次封装Response模块 # drf提供的Response&#xff0c;前端想接收到的格式 {code:xx,msg:xx} 后端返回&#xff0c;前端收到&#xff1a; APIResponse(tokneasdfa.asdfas.asdf)---->{code:100,msg:成功,token:asdfa.asdfas.asdf} APIResponse(code101,msg用户不存在) ---…

学习笔记-李沐动手学深度学习(一)(01-07,概述、数据操作、tensor操作、数学基础、自动求导)

个人随笔 第三列是 jupyter记事本 官方github上啥都有&#xff08;代码、jupyter记事本、胶片&#xff09; https://github.com/d2l-ai 多体会 【梯度指向的是值变化最大的方向】 符号 维度 &#xff08;弹幕说&#xff09;2&#xff0c;3&#xff0c;4越后面维度越低 4…

Java 面向对象案例 02 (黑马)

代码&#xff1a; public class foodTest {public static void main(String[] args) {//1、构建一个数组food[] arr new food[3];//2、创建三个商品对象food f1 new food("apple","123",3.2,500);food f2 new food("pear","456",4…