当前位置: 首页 > article >正文

C++修炼之路:初识C++

        Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路!

我的博客:<但凡.

我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》

欢迎点赞,关注!

引言

        ‌C++‌,通常被称为“C加加”,是一种由Bjarne Stroustrup在1983年开发的通用编程语言。它是由C语言扩展升级而来,支持面向对象程序设计、过程化程序设计等多种编程范式。‌

        C++的应用领域服务器端、游戏(引擎)、机器学习引擎、音视频处理、嵌入式软件、电信设备、金融 应用、基础库、操作系统、编译器、基础架构、基础工具、硬件交互等很多方面都有。

        本篇文章作为c++基础教学的第一篇,将带大家认识和简单使用c++。


1、C++的第一个程序

        万物始于hello world.现在我们来用c++写一个hello world:

#include<iostream>
using namespace std;
int main()
{cout << "hello world" << endl;return 0;
}

        我们来分析一下这个程序:首先和C语言一样,上来先包括一个头文件。这里我们包过的头文件是iostream库,意思是输入输出流。里面包含着c++最常用的输入和输出

        接下来一行叫展开命名空间。只有展开的这个明明空间我们的iostream库里的函数才能随便使用。当然了至于什么是命名空间以及为什么要展开我们下文再谈。

        下面一行和我们的c语言一样,都是int main。这里的int main和C语言中的一样就不过多赘述了。

        接下来一行是输出hello world这个字符串。cout是iostream库中提供的输出函数。用法就是cout<<输出内容。后面的endl是换行(endline),但和C语言里面的\n不用,endl是一个函数

2、命名空间

2.1命名空间的定义及使用

        命名空间namespace存在的意义是为了解决命名冲突。在C语言中实现这个代码

#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数” printf("%d\n", rand);return 0;
}

        会报错。报错的原因就是我们自己定的变量rand和C语言自带的库函数冲突了。这时候编译器就无法识别了。这其实是C语言的不足之处。而c++中的命名空间就完美的解决了这个问题。

        想想一下这个场景。小张和小王同时进行一个项目,但是他俩写的函数名有时候会相同,不如小张的加法函数叫test,小王的乘法函数叫test,那这时候都不用和系统自带的函数冲突了,两个人写的函数就已经冲突了。这个时候namespace的用处就来了。我们把小张和小王的代码写成下面这样:

#include<iostream>
using namespace std;
namespace mrZhang
{int test(int x, int y){return x + y;}
}
namespace mrWang
{int test(int x, int y){return x * y;}
}
int main()
{int a = mrZhang::test(1, 5);int b = mrWang::test(1, 5);cout << a << " " << b;return 0;
}

输出一下,分别是6和5,小张和小王的代码可以毫不冲突的正常使用了。

        其实命名空间本质上是定义出一个域,我们小张和小王各有一个域,那他们从自己的域里面调用自己的函数不就毫不冲突了吗?

        在调用的时候,我们只要用 空间名::函数名 这样的格式来调用。

        命名空间还可以进行嵌套,比如这样:

#include<iostream>
using namespace std;
namespace mrZhang
{int test(int x, int y){return x + y;}namespace mrWang{int test(int x, int y){return x * y;}}}
int main()
{int a = mrZhang::test(1, 5);int b = mrZhang::mrWang::test(1, 5);cout << a << " " << b;return 0;
}

        输出结果仍然是6和5。

        命名空间中不止可以定义函数,也可以定义变量和自定义类型。这样的话你自己定义的变量也可以和别的同名变量毫不冲突了。

        另外在多文件中可以定义同名的命名空间。这样的话他们就会合成一个命名空间。

2.2命名空间的展开

        现在看我们第一个helloworld程序,第二行的using namespace std;就是展开命名空间。正常我们使用输入输出函数是这样的:

#include<iostream>
int main()
{std::cout << "hello world" << std::endl;return 0;
}

        当我们程序比较简单,不会出现冲突的命名的时候就可以把命名空间展开。

        比如平时的简单练习程序,或者算法题,我们就可以直接Using namespace std;把命名空间展开直接使用c++自带的函数。

        我们也可以只展开一个命名空间中的某个变量或函数,这样的话访问这个变量或函数就更简便了:

#include<iostream>
using namespace std;
namespace mrZhang
{int test(int x, int y){return x + y;}
}
using mrZhang::test;
int main()
{int a = test(1, 5);cout << a;return 0;
}

3、缺省参数

        缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调用该函数时,如果没有指定实参 则采用该形参的缺省值,否则使用指定的实参,缺省参数分为全缺省和半缺省参数。

        缺省参数又叫默认参数。

比如我们定义一个这样的函数:

int test(int x=2, int y=6)
{return x + y;
}

        我们调用这个函数但是不传入实参,返回结果就是8.

        如果再调用时我们传入实参1和2,那么返回值就是1+2=3。

需要注意三点:

        1、缺省参数必须从右往左给。比如上面的程序,我们只给x缺省参数但不给y缺省参数这样其实是不合法的。

        2、函数实参一定是从左往右给函数的。

        3、函数声明和定义分离时,不能在声明和定义中同时给缺省值。

比如这样,其实是不合法的:

#include<iostream>
using namespace std;int test(int x = 1, int y = 2);
int main()
{int a = test();cout << a;return 0;
}
int test(int x = 1, int y = 2)
{return x + y;
}

        我们只能在声明中给,不能在定义中给。

4、函数重载

        在c++中允许出现同名函数,但是同名函数的返回值或者形参类型或形参个数必须有一个不同。在调用函数时,c++可以根据传入实参的类型自动选择正确的函数。比如这样:

#include<iostream>
using namespace std;int test(int x , int y )
{return x + y;
}
double test(double x, double y)
{return x + y;
}
int main()
{double x = 1.5, y = 2.8;int a = test(1,2);double b = test(x, y);cout << a <<" "<< b ;return 0;
}

5、引用

5.1引用的介绍

        引用其实就是给我们已有的一个变量去别名。并不会开辟新的空间。它的使用格式是这样的:类型&引用别名=引用对象;

        就像每个人都有大名和乳名一样,我叫这两个名字其实指的人都是一个。比如这样:

int i = 5;
int& j = i;

        此时我们改变j就相当于改变了i。那这个东西有什么意义呢?回想我们在C语言阶段学习指针的时候,交换两个数的函数得用指针变量做形参。有了引用这个东西,我们就可以这样写交换函数

void Swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}

        怎么样,是不是方便了很多呢?

        其实引用的底层也是指针。所以说通过引用我们能够改变原值。

5.2引用的特性

        1、引用必须在定义时初始化。比如int& a=0;这句代码其实是不合法的。

        2、一个变量可以有多个引用。

        3、引用一旦引用一个实体,再不能引用其他实体。

比如下面这串代码:

#include<iostream>
using namespace std;int main()
{int a = 10;int& b = a;int c = 20;b = c;cout << &a <<" "<< &b <<" "<< &c << endl;cout << a <<" "<< b <<" "<< c << endl;return 0;
}

        我们进行了b=c的操作,只是把c的值赋值给了b,但并没有改变b的引用实例,正因此a和b地址是相同的。

5.3引用的使用

        引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被 引用对象。

        引用传参我们已经介绍过了,现在我们介绍一下引用做返回值。

int STTop(ST& rs)
{assert(rs.top > 0);return rs.a[rs.top];
}
int main()
{ST st1;STInit(st1);STPush(st1, 1);STPush(st1, 2);STTop(st1)+=10;return 0;
}

        我们截取了一部分之前栈的操作,发现对于STTop(st1)+=10;这个操作是无法达到目的的。

我们想的是让栈顶的数据加上10,但是实际上栈顶的数据并没有改变。

        这是因为咱们返回的是一个值,相当于我们把原来的数拷贝出了他的值然后返回了,就算把这份拷贝的值加上10也无法改变原来的栈顶数据。而且实际上值的拷贝具有常性,根本就无法改变,导致这个程序报错。所以从哪个角度来说栈顶数据都无法被更改。

        但是我们如果是引用返回的话,就可以成功改变栈顶的值,因为我们是直接对栈顶这个区域进行的操作。 

5.4、const引用

        const对象必须用const引用,普通对象也可以用const引用,但普通引用引用不了const对象。       

        这涉及到权限的问题。普通对象是一个变量,可以被改变的,所以他的权限更低。而const对象不能被改变所以他的权限更高。普通引用引用const对象权限就放大了,所以编译器会报错。反过来const引用可以引用普通对象,因为权限是可以缩小的。

6、inline内联 

        由于C语言中宏函数设计的不足,c++中inline的诞生就是为了代替宏函数。

#include<iostream>
using namespace std;
inline int add(int x,int y)
{return x + y;
}
int main()
{cout << add(1, 5) << endl;return 0;
}

        对于短小的函数,inline操作会使函数在编译时展开,可以提高效率。但是如果这个函数过长就不适合使用内联了,过长的函数内联反而会降低时间,甚至,有的编译器防止用户内联过长的函数,就算内联了,也不会起内联的作用。

        注意,内联函数的定义和声明必须在同一个文件。

        好了,今天的内容就分享到这,我们下期再见!

 

 

相关文章:

C++修炼之路:初识C++

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 引言 …...

微信小程序+SpringBoot的单词学习小程序平台(程序+论文+讲解+安装+修改+售后)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统背景 &#xff08;一&#xff09;社会需求背景 在全球化的大背景下&#xff0c;英语作为国际…...

快乐数 力扣202

一、题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&…...

VBA 数据库同一表的当前行与其他行的主键重复判断实现方案1

目的&#xff0c;判断是否主键重复&#xff0c;不重复则登录新数据&#xff0c;重复则不登录。 定义类型&#xff1a; DataRecord   tableName 表名   rowNumber 行号   columnName 列名   data 数据 想要实现的代码逻辑如下&#xff1a; 模拟数据库的登录过程。假设…...

Java基础面试题全集

1. Java语言基础 1.1 Java是什么&#xff1f; • Java是一种广泛使用的编程语言&#xff0c;最初由Sun Microsystems&#xff08;现为Oracle公司的一部分&#xff09;于1995年发布。它是一种面向对象的、基于类的、通用型的编程语言&#xff0c;旨在让应用程序“编写一次&…...

3.激活函数:神经网络中的非线性驱动器——大模型开发深度学习理论基础

激活函数在神经网络中扮演着至关重要的角色&#xff0c;它为模型引入非线性因素&#xff0c;使得网络能够拟合复杂的数据分布&#xff0c;从而实现高效的特征提取与预测。本文将从实际开发角度出发&#xff0c;介绍激活函数的基本概念、常见激活函数&#xff08;如 ReLU、GELU、…...

VUE的第二天

1. 指令修饰符 1.1什么是指令修饰符&#xff1f; ​ 所谓指令修饰符就是通过“.”指明一些指令后缀 不同的后缀封装了不同的处理操作 —> 简化代码 1.2按键修饰符 keyup.enter —>当点击enter键的时候才触发 代码演示&#xff1a; <div id"app"><…...

Element Plus中的树组件的具体用法(持续更新!)

const defaultProps {//子树为节点对象的childrenchildren: children,//节点标签为节点对象的name属性label: name, } 属性 以下是树组件中的常用属性以及作用&#xff1a; data&#xff1a;展示的数据&#xff08;数据源&#xff09; show-checkbox&#xff1a;节点是否可…...

尚硅谷爬虫note14

一、scrapy scrapy&#xff1a;为爬取网站数据是&#xff0c;提取结构性数据而编写的应用框架 1. 安装 pip install scrapy 或者&#xff0c;国内源安装 pip install scrapy -i https&#xff1a;//pypi.douban.com/simple 2. 报错 报错1&#xff09;building ‘twisted.te…...

/***************************所有笔记汇总目录***************************/

文章分类目录 STM32CubeMX 01、STM32CubeMX——定时器&#xff08;普通模式和PWM模式&#xff09; 02、STM32CubeMX——串口&#xff08;HAL库&#xff09; 03、STM32CubeMX——(uart_IAP串口)简单示例 04、STM32CubeMX——ADC采集单通道&#xff0c;多通道&#xff0c;内部…...

Spring Framework中的IoC容器

控制反转(Inversion of Control, IoC)与面向切面编程(Aspect Oriented Programming, AOP)是Spring Framework中最重要的两个概念&#xff0c;本章会着重介绍前者。 2.1.1什么是IoC容器 使用XML来配置类实例 定义一个Java Bean类 在resources文件夹中定义一个beans.xml文件&a…...

永洪科技深度分析实战,零售企业的销量预测

随着人工智能技术的不断发展&#xff0c;智能预测已经成为各个领域的重要应用之一。现在&#xff0c;智能预测技术已经广泛应用于金融、零售、医疗、能源等领域&#xff0c;为企业和个人提供决策支持。 智能预测技术通过分析大量的数据&#xff0c;利用机器学习和深度学习算法…...

2.数据结构-栈和队列

数据结构-栈和队列 2.1栈2.1.1栈的表示和实现2.1.2栈的应用举例数制转换括号匹配检验迷宫给求解表达式求值 2.1栈 栈是限定仅在表尾进行插入或删除操作的线性表&#xff0c;因此&#xff0c;对栈来说&#xff0c;表尾端有其特殊含义&#xff0c;称为栈顶&#xff08;top&#x…...

C++ MySQL 常用接口(基于 MySQL Connector/C++)

C MySQL 常用接口&#xff08;基于 MySQL Connector/C&#xff09; 1. 数据库连接 接口&#xff1a; sql::mysql::MySQL_Driver *driver; sql::Connection *con;作用&#xff1a; 用于创建 MySQL 连接对象。 示例&#xff1a; driver sql::mysql::get_mysql_driver_insta…...

android studio开发文档

android基本样式 1.文本 2.设置文本大小 3.字体颜色 背景 资源文件 xml’引用资源文件 4.视图宽高 5.间距 6.对齐方式 常用布局 1.linearLayout线性布局 2.相对布局 RelativeLayout 3.网格布局GridLayout 4.scrollview滚动视图 Button 点击事件与长按事件 长按 按钮禁用与…...

Java 对象与类——从 C++ 到 Java

文章目录 面向对象程序设计概述使用预定义类用户自定义类静态字段与静态方法方法参数对象构造包JAR 文件文档注释类设计技巧 面向对象程序设计概述 面向对象程序设计&#xff08;OOP&#xff09;在 20 世纪 70 年代出现&#xff0c;是当今主流编程范型&#xff0c;Java 是面向…...

java2025年常见设计模式面试题

1. 请解释建造者模式&#xff08;Builder Pattern&#xff09;及其应用场景。 答案&#xff1a; 建造者模式用于创建一个复杂的对象&#xff0c;同时允许用户只通过指定复杂对象的类型和内容就能构建它们&#xff0c;隐藏了复杂的构建逻辑。 示例&#xff1a; public class C…...

一篇文章讲解清楚ARM9芯片启动流程

SAM9X60 ARM9 boot启动流程关键词介绍&#xff1a; 第一级bootloader - 也叫boot ROM&#xff0c;是集成在MPU内部的ROM里面 它的主要功能是执行对MPU的基本初始化和配置&#xff0c;查找并将第二级bootloader从外部NVM中读取出来并放到MPU内部的SRAM. 可以让MPU强制停留在第一…...

setlocale()的参数,“zh_CN.UTF-8“, “chs“, “chinese-simplified“的差异。

在 C/C 中&#xff0c;setlocale() 函数的参数 zh_CN.UTF-8、chs 和 chinese-simplified 均用于设置中文简体环境&#xff0c;但它们的语义、平台支持和编码行为存在显著差异&#xff1a; ​1. zh_CN.UTF-8&#xff08;推荐&#xff09;​ ​含义&#xff1a; zh_CN: 中文&…...

Python项目-基于Django的在线教育平台开发

1. 项目概述 在线教育平台已成为现代教育的重要组成部分&#xff0c;特别是在后疫情时代&#xff0c;远程学习的需求显著增加。本文将详细介绍如何使用Python的Django框架开发一个功能完善的在线教育平台&#xff0c;包括系统设计、核心功能实现以及部署上线等关键环节。 本项…...

【2025】Electron + React 架构筑基——从零到一的跨平台开发

引言 源代码仓库&#xff1a; Github仓库【electron_git】 你是否厌倦了在命令行中反复输入git status&#xff0c;却依然无法直观看到文件变化&#xff1f; 是否羡慕VS Code的丝滑Git集成&#xff0c;却苦恼于无法定制自己的专属工具&#xff1f; 本专栏将为你打开一扇新的…...

Vue3实战学习(IDEA中打开、启动与搭建Vue3工程极简脚手架教程(2025超详细教程)、Windows系统命令行启动Vue3工程)(2)

目录 一、命令行中重新启动已搭建好的Vue3工程。(快速上手) &#xff08;0&#xff09;Windows环境下使用命令行从零到一手动搭建Vue3工程教程。 &#xff08;1&#xff09;首先找到已建Vue3工程的目录。 &#xff08;2&#xff09;无需再下载依赖包&#xff0c;直接执行npm ru…...

【ArcGIS】地理坐标系

文章目录 一、坐标系理论体系深度解析1.1 地球形态的数学表达演进史1.1.1 地球曲率的认知变化1.1.2 参考椭球体参数对比表 1.2 地理坐标系的三维密码1.2.1 经纬度的本质1.2.2 大地基准面&#xff08;Datum&#xff09;的奥秘 1.3 投影坐标系&#xff1a;平面世界的诞生1.3.1 投…...

Redis- 切片集群

切片集群 切片集群什么是Redis Cluster吗&#xff1f;为什么需要切片集群&#xff1f;Redis Cluster的数据分片机制是怎样的&#xff1f;哈希槽的算法是什么基本算法流程 待填坑 切片集群 什么是Redis Cluster吗&#xff1f;为什么需要切片集群&#xff1f; Redis Cluster是R…...

Oxidized收集H3C交换机网络配置报错,not matching configured prompt (?-mix:^(<CD>)$)

背景&#xff1a;问题如上标题&#xff0c;H3C所有交换机配置的model都是comware 解决方案&#xff1a; 1、找到compare.rb [rootoxidized model]# pwd /usr/local/lib/ruby/gems/3.1.0/gems/oxidized-0.29.1/lib/oxidized/model [rootoxidized model]# ll comware.rb -rw-r--…...

力扣146 - LRU缓存

视频讲解 哈希 双向链表 为什么要用双向链表&#xff1f; 快速删除节点&#xff08;O(1&#xff09;&#xff09; 如果是单链表的话&#xff0c;删除一个节点时&#xff0c;需要从头遍历&#xff0c;找到前驱节点&#xff0c;才能修改 prev->next&#xff0c;导致 O(n)…...

单例模式:确保一个类只有一个实例

目录 引言 1. 单例模式的核心思想 2. 单例模式的实现方式 2.1 饿汉式单例 2.2 懒汉式单例 2.3 线程安全的懒汉式单例 2.4 双重检查锁定&#xff08;Double-Checked Locking&#xff09; 2.5 静态内部类实现单例 2.6 枚举实现单例 3. 单例模式的使用场景 4. 单例模式…...

doris: SQL Server

Doris JDBC Catalog 支持通过标准 JDBC 接口连接 SQL Server 数据库。本文档介绍如何配置 SQL Server 数据库连接。 使用须知​ 要连接到 SQL Server 数据库&#xff0c;您需要 SQL Server 2012 或更高版本&#xff0c;或 Azure SQL 数据库。 SQL Server 数据库的 JDBC 驱动…...

【ubuntu20】--- 搭建 gerrit 最新最详细

在编程的艺术世界里&#xff0c;代码和灵感需要寻找到最佳的交融点&#xff0c;才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里&#xff0c;我们将共同追寻这种完美结合&#xff0c;为未来的世界留下属于我们的独特印记。 【ubuntu20】--- 搭建 gerrit 最新最详细…...

RtlLookupAtomInAtomTable函数分析之RtlpAtomMapAtomToHandleEntry函数的作用是验证其正确性

第一部分&#xff1a; NTSTATUS RtlLookupAtomInAtomTable( IN PVOID AtomTableHandle, IN PWSTR AtomName, OUT PRTL_ATOM Atom OPTIONAL ) { NTSTATUS Status; PRTL_ATOM_TABLE p (PRTL_ATOM_TABLE)AtomTableHandle; PRTL_ATOM_TABLE_ENTRY a; …...