C++:入门详解(关于C与C++基本差别)
目录
一.C++的第一个程序
二.命名空间(namespace)
1.命名空间的定义与使用:
(1)命名空间里可以定义变量,函数,结构体等多种类型
(2)命名空间调用(::)与展开
(3)命名空间的嵌套
(4)具体使用场景
三.缺省参数
1.基本定义:
2.几个注意:
四.函数重载
1.定义与使用:
五.引用
1.定义:
2.引用的特性:
3.引用的使用(区别传值返回和传引用返回):
4.const引用:
六.inline内联
一.C++的第一个程序
C++作为C语言的升级版,除了可以无缝兼容C语言的各种语法结构和各种框架外,在很大程度上对C语言的许多代码进行了优化升级,在保持原有代码逻辑结构相同的情况下,C++的简便性和应用性相比C语言不可同日而语,以下我要阐述的就是在学完C语言然后进入C++后需要掌握的一些基础知识:首先来看第一个C++程序
#include<iostream>//C++需要包含的头文件 using namespace std;//展开对应的命名空间 int main() {cout << "hello world" << endl;//区别于C语言的输出方式 //cout<<输出内容,后面的endl是换行(endline),但和C语言里面的\n不用,endl是一个函数。return 0; }
基础结构大概就是这样,下面就是对每一部分的具体介绍:
二.命名空间(namespace)
1.命名空间的定义与使用:
书面上的定义简而言之是:namespace的本质是定义出一个域,这个域跟全局域各自独立,不同的域可以定义同名变量
(1)命名空间里可以定义变量,函数,结构体等多种类型
#include<iostream> namespace space { //定义变量int rand = 10;char time = 20; //定义函数int add(int a, int b){return a + b;} //定义结构体struct student{char name[20];char sex[6];int age;}; } int main() {return 0; }
(2)命名空间调用(::)与展开
在调用的时候,只要用空间名::函数名这样的格式来调用
#include<iostream> int main() {std::cout << "hello world" << std::endl;return 0; }
也可以只展开一个命名空间中的某个变量或函数,这样的话访问这个变量或函数就更简便
#include<iostream> using namespace std; namespace b {int test(int x, int y){return x + y;} } using b::test; int main() {int m = test(1, 5);cout << m;return 0; }
(3)命名空间的嵌套
#include<iostream> using namespace std; namespace a {int test(int x, int y){return x + y;}namespace b{int test(int x, int y){return x * y;}}} int main() {int m = a::test(2, 3);int n = a::b::test(2, 3);cout << m << " " << n;return 0; }
(4)具体使用场景
#include <stdio.h> #include <stdlib.h> int rand = 10; int main() {// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数” printf("%d\n", rand);return 0; }
这样写c语言会报错:报错的原因就是我们自己定的变量rand和C语言自带的库函数冲突了,这时候编译器就无法识别,这其实是C语言的不足之处。而c++中的命名空间就完美的解决这个问题
三.缺省参数
1.基本定义:
在函数定义时为参数指定的默认值,当调用函数时如果没有传递该参数,则使用默认值。这样可以提高函数的灵活性和可重用性
举例例如一个计算面积的函数,参数有长和宽,其中宽可以设为默认值1,这样调用时只传长就可以得到正方形的面积,这样的例子比较直观#include<iostream> using namespace std; int test(int x = 2, int y = 6) {return x + y; } //如果调用这个函数但是不传递参数,那么返回结果就是8,同样如果掺入参数1和2,那么返回结果就是3
2.几个注意:
(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; } //比如这样同时个给缺省值的函数是不合法的,一般只在声明中给缺省值
四.函数重载
1.定义与使用:
即重名函数可以通过识别传入的参数类型来自动选择相对应的函数,例如:
#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; }
五.引用
1.定义:
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间,但实际上在C++的底层逻辑里引用依旧是以指针的形式存在,但我们在实际使用中并不需要考虑那么多,就当引用是C++给我们带来的一种更加方便写代码的方法就行了,以下是引用使用的基本规则:
类型& 引用别名=引用对象
#include<iostream> using namespace std; int main() {int a = 30;//一个变量可以取多个别名int& b = a;//给a变量取别名int& c = a;//c也是a的别名int& d = b;//给b变量取别名,相当于d也是a的别名cout << &a << endl << &b << endl << &c << endl << &d << endl;//从地址中也可以看出来a,b,c,d占用同一块内存空间return 0;}
当然,引用相对指针是非常方便好理解的,我举个例子:
#include<iostream> using namespace std; //传址调用,指针 void swap(int* a, int* b) {int tmp = *a;*a = *b;*b = tmp; } //引用 void swap(int& a, int& b)//函数重载 {int tmp = a;a = b;b = tmp; } int main() {int a = 10;int b = 20;swap(a, b);swap(a, b);return 0; }
2.引用的特性:
(1)引用必须在定义时初始化。比如int& a=0;这句代码其实是不合法的
(在 C++ 中,引用必须在定义时初始化,这意味着当声明一个引用变量时,必须立即将其绑定到一个已存在的对象(变量、常量或表达式的结果),与普通变量不同,普通变量可以在后续赋值时初始化)
(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地址是相同的
3.引用的使用(区别传值返回和传引用返回):
引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被 引用对象
引用传参介绍过了,然后我们看一下引用做返回值(即传引用返回)与传值返回区别
int STTop(ST& rs)//注意这里是传值返回(因为返回类型是int二百元引用类型的int&) {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也无法改变原来的栈顶数据
以上发生的情况就是由传值引用引发的,传值引用简而言之就是为了保护源数据不被修改的场景二存在,通过返回对栈顶元素的值的拷贝,从而使实际上的栈顶元素不受改变
但如果代码这样改,就可以轻易改变栈顶元素的值:
(即传引用返回)
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; }
4.const引用:
const引用简而言之就是对引用范围的缩小:即 const对象必须用const引用,普通对象也可以用const引用,但普通引用引用不了const对象
#include<iostream> using namespace std; int main() {const int a = 10;//只可读//int& b = a;//发生错误,b可读可写,权限变大//应加上const const int& b = a;int c = 20;const int& d = c;//权限缩小,可以c++;//d++不可以;c可以改变,d不可以return 0; }
这些就涉及到权限的问题,普通对象是一个变量,可以被改变的,所以他的权限更低。而const对象不能被改变所以他的权限更高。普通引用引用const对象权限就放大了,所以编译器会报错,反过来const引用可以引用普通对象,因为权限是可以缩小的,总结来说:访问权限可以缩小,但是不能放大(访问权限只针对引用和指针)
六.inline内联
在 C++ 中,内联函数(Inline Functions)是一种优化机制,旨在通过在编译时将函数体直接替换到调用位置,减少函数调用的开销(如栈帧压入/弹出、参数传递等)
#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语言,还是由很多需要管制与在意的地方,那就先这样吧
全文终
相关文章:

C++:入门详解(关于C与C++基本差别)
目录 一.C的第一个程序 二.命名空间(namespace) 1.命名空间的定义与使用: (1)命名空间里可以定义变量,函数,结构体等多种类型 (2)命名空间调用(…...
服务器上的nginx因漏洞扫描需要升级
前言 最近客户联系说nginx存在安全漏洞 F5 Nginx 安全漏洞(CVE-2024-7347) F5Nginx是美国F5公司的一款轻量级Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like协议下发行。F5 Nginx存在安全漏洞,该漏洞源于可能允许攻击者使用特制的…...
1688商品列表商品详情API接口全面解析
1688作为中国领先的B2B电子商务平台,汇聚了海量的商品资源,为商家和采购商提供了丰富的交易机会。为了更方便地获取和利用这些商品信息,1688平台提供了商品列表API接口,允许第三方开发者通过编程方式获取平台上的商品列表数据。本…...

【爬虫】开篇词
一、网络爬虫概述 二、网络爬虫的应用场景 三、爬虫的痛点 四、需要掌握哪些技术? 在这个信息爆炸的时代,如何高效地获取和处理海量数据成为一项核心技能。无论是数据分析、商业情报、学术研究,还是人工智能训练,网络爬虫&…...
如何在SpringBoot中灵活使用异步事件?
在现代的应用开发中,事件驱动的架构越来越受到欢迎。当我们在使用SpringBoot时,了解如何实现异步事件变得尤为重要。通过事件机制,我们能够在系统中实现松耦合的组件,让不同模块之间能够有效沟通,而无需直接依赖。本文…...

S19文件格式详解:汽车ECU软件升级中的核心镜像格式
文章目录 引言一、S19文件格式的起源与概述二、S19文件的核心结构三、S19在汽车ECU升级中的应用场景四、S19与其他格式的对比五、S19文件实例解析六、工具链支持与安全考量七、未来趋势与挑战结语引言 在汽车电子控制单元(ECU)的软件升级过程中,S19文件(也称为Motorola S-…...
git安装(windows)+vscode配置
安装git for windows在使用 Git 之前,建议设置全局的用户名称和电子邮件地址,这样每次提交代码时就可以自动关联您的身份信息。设置一次后,您无需每次都输入这些信息,Git 将自动使用您配置的全局用户信息。如果需要针对特定项目使…...
Python性能优化面试题及参考答案
目录 解释字典与列表在查找操作中的时间复杂度差异,如何利用哈希表特性提升性能? 为什么在只读场景下使用元组(tuple)比列表(list)更高效? 如何用 collections.deque 优化频繁的队列插入 / 删除操作? defaultdict 相比普通字典在哪些场景下能减少冗余代码并提升效率…...

【十四】Golang 接口
💢欢迎来到张胤尘的开源技术站 💥开源如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 接口接口定义接口初始化接口嵌套空接口存储任意类…...
ngx_openssl_create_conf
ngx_openssl_create_conf 声明在 src\event\ngx_event_openssl.c static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); 定义在 src\event\ngx_event_openssl.c static void * ngx_openssl_create_conf(ngx_cycle_t *cycle) {ngx_openssl_conf_t *oscf;oscf ngx_…...

54-WLAN 无线局域网配置方案-三层
一、网络拓扑说明 本 WLAN 网络由交换机(LSW1)、无线控制器(AC1)、无线接入点(AP1\2)以及无线客户端(STA1)组成。 用途VLANAC100AP200业务300 二、设备配置 二、设备配置 &#x…...

JVM 类加载原理之双亲委派机制(JDK8版本)
对 Java 程序的运行过程而言,类的加载依赖类加载器完成,而在 Java 默认的类加载器又分为启动类加载器、扩展类加载器和应用程序类加载器三种,但是一个类通常仅仅需要被加载一次即可,双亲委派机制即规定各个类该被何种类加载器加载…...

Mysql快速学习——《一》: Mysql的基础架构
了解mysql的基础架构, 理解大概的实现思想, 更有利与我们知之所以然, 是我们学习mysql起来思路更清晰, 效率更高. 思维导图: mysql 基础架构 mysql基础架构.png 1. 连接器 Mysql作为服务器,一个客户端的Sql连接过来就需要分配一个线程进行处理,这个线程…...

【华为OD机试真题29.9¥】(E卷,100分) - 运维日志排序(Java Python JS C++ C )
最新华为OD机试 题目描述 [运维工程师]采集到某产品线网运行一天产生的日志n条,现需根据日志时间先后顺序对日志进行排序,日志时间格式为H:M:S.N。 H表示小时(0~23)M表示分钟(0~59)S表示秒(0~59)N表示毫秒(0~999) 时间可能并没有补全,也就…...

rust编程实战:实现3d粒子渲染wasm
源码 纯js实现 fps: wasm实现 通过对比可以看出来 wasm 实现的计算比纯js刷新相对稳定。...

本地部署Navidrome个人云音乐平台随时随地畅听本地音乐文件
文章目录 前言1. 安装Docker2. 创建并启动Navidrome容器3. 公网远程访问本地Navidrome3.1 内网穿透工具安装3.2 创建远程连接公网地址3.3 使用固定公网地址远程访问 前言 今天我要给大家安利一个超酷的私有化音乐神器——Navidrome!它不仅让你随时随地畅享本地音乐…...

Unity自定义区域UI滑动事件
自定义区域UI滑动事件 介绍制作1.创建一个Image2.创建脚本 总结 介绍 一提到滑动事件联想到有太多的插件了比如EastTouchBundle,今天想单纯通过UI去做一个滑动事件而不是基于Box2d或者Box去做滑动事件。 制作 1.创建一个Image 2.创建脚本 using UnityEngine; us…...

Redis7——进阶篇(五)
前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。 基础篇: Redis(一)Redis(二)Redis(三)Redis&#x…...
时序和延时
1、延迟模型的类型 verilog有三种类型的延迟模型:分布延迟 、 集总延迟 、 路径延迟(pin to pin) 1.1、 分布延迟 分布延迟是在每个独立元件的基础上进行定义的。 module M(output wire out ,input wire a …...

高效自动化测试:打造Python+Requests+Pytest+Allure+YAML的接口测试框架
一、背景 在快节奏的开发周期中,如何确保接口质量?自动化测试是关键。通过构建标准化、可复用的测试框架,能显著提升测试效率与准确性,为项目质量保驾护航[1][7]。 二、目标 ✅ 核心目标: ● 实现快速、高效的接口测试…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...

高效的后台管理系统——可进行二次开发
随着互联网技术的迅猛发展,企业的数字化管理变得愈加重要。后台管理系统作为数据存储与业务管理的核心,成为了现代企业不可或缺的一部分。今天我们要介绍的是一款名为 若依后台管理框架 的系统,它不仅支持跨平台应用,还能提供丰富…...

【汇编逆向系列】六、函数调用包含多个参数之多个整型-参数压栈顺序,rcx,rdx,r8,r9寄存器
从本章节开始,进入到函数有多个参数的情况,前面几个章节中介绍了整型和浮点型使用了不同的寄存器在进行函数传参,ECX是整型的第一个参数的寄存器,那么多个参数的情况下函数如何传参,下面展开介绍参数为整型时候的几种情…...

react更新页面数据,操作页面,双向数据绑定
// 路由不是组件的直接跳转use client,useEffect,useRouter,需3个结合, use client表示客户端 use client; import { Button,Card, Space,Tag,Table,message,Input } from antd; import { useEffect,useState } from react; impor…...
【2D与3D SLAM中的扫描匹配算法全面解析】
引言 扫描匹配(Scan Matching)是同步定位与地图构建(SLAM)系统中的核心组件,它通过对齐连续的传感器观测数据来估计机器人的运动。本文将深入探讨2D和3D SLAM中的各种扫描匹配算法,包括数学原理、实现细节以及实际应用中的性能对比,特别关注…...