【C++】C++入门基础

✨✨欢迎大家来到Celia的博客✨✨

🎉🎉创作不易,请点赞关注,多多支持哦🎉🎉

所属专栏:C++

个人主页:Celia's blog~

目录

一、C++简介

二、第一个C++程序

三、namespace 命名空间

3.1 namespace的定义

3.2 命名空间中成员的访问

3.2.1 域作用限定符 ::

 3.3 命名空间的使用

四、C++的输入输出

五、缺省参数

5.1 缺省参数的使用规定

 六、函数重载

七、引用

7.1 引用的概念

​编辑 7.2 引用的特性

7.3 引用的使用

7.4 const引用

7.5 引用和指针的关系

八、inline 内联函数

九、nullptr


 

一、C++简介

  C++(c plus plus)是一种计算机高级程序设计语言,由C语言扩展升级而产生 ,最早于1979年由本贾尼·斯特劳斯特卢普在AT&T贝尔工作室研发。 

  C++既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计。 C++几乎可以创建任何类型的程序:游戏、设备驱动程序、HPC、云、桌面、嵌入式和移动应用等。 甚至用于其他编程语言的库和编译器也使用C++编写。 

  C++拥有计算机运行的实用性特征,同时还致力于提高大规模程序的编程质量与程序设计语言的问题描述能力。

二、第一个C++程序

   C++由C语言演变而来,有着自己的一套全新语法,同时也兼容了C语言的绝大部分语法。在创建C++新文件时,文件的后缀要改成xxx.cpp

//C语言版本
#include<stdio.h>
int main()
{printf("%s", "Celia");return 0;
}
//C++版本
#include<iostream> //io流 可以类比于C语言的<stdio.h>进行理解
using namespace std;
int main()
{cout << "Celia" << endl;  //输出字符串并换行return 0;
}

三、namespace 命名空间

  在C语言中,每一个变量都有属于自己的作用域。例如下面的代码:

#include<stdio.h>int rand = 10;
int main()
{printf("%d", rand);return 0;
}

这段代码定义了一个全局变量rand 并赋值为10,在main函数中可以正常打印这个全局变量的值。这时我们新加上一个头文件<stdlib.h>,就会出现如下编译报错,让人费解:

出现这个报错的原因是由于<stdlib.h>这个头文件中包含了一个rand函数,与全局变量名字相同,编译器进行识别时就出现了错误,无法判断rand是全局变量还是函数。

#include<stdio.h>
#include<stdlib.h>//errorint rand = 10;
int main()
{printf("%d", rand);return 0;
}

在实际的项目开发中,如果两人的代码块中某个函数、变量的名字相同,在合并两个代码块的时候就会出现报错,这不利于实际开发。至此,C++中额外引入了一个关键字namespace

3.1 namespace的定义

  • 定义一个命名空间,需要用到关键字namespace,后面加上空间名,然后加上一对花括号{}。在花括号中可以定义变量、函数、结构体。
  • namespace本质上是定义了一个全新独立的域,在不同的域中可以有相同的变量名/函数名。
  • namespace只能定义成全局,也可以嵌套定义。
  • 在C++中,有全局域局部域类域命名空间域。域会影响编译时的语法查找逻辑,有了域的隔离,在不同的域中相同名字的函数/变量报错的问题就得到了很好的解决。全局域和局部域会影响生命周期,类域和命名空间域不会影响生命周期。
  • 如果定义了多个同名的namespace,这些同名的namespace会被认为是一个namespace,不会冲突。
  • C++的标准库都放在一个叫做std的命名空间中。
//定义了一个叫Celia的命名空间
namespace Celia
{int a = 10;char b = 'x';
}

3.2 命名空间中成员的访问

3.2.1 域作用限定符 ::

 我们来看下面的代码示例:

#include<iostream>
using namespace std;int a = 5;namespace Celia
{int a = 10;char b = 'x';
}int main()
{int a = 3;cout << a << endl;  //结果是什么?return 0;
}

这段代码会优先在局部域中寻找变量a并输出 ,如果我们想要访问到全局变量a,就需要用到域作用限定符 ::

cout << ::a << endl;//输出全局变量a

域作用限定符 :: 默认访问全局的变量/函数。只需要在变量名/函数名前加上 :: 即可。若是想访问到Celia命名空间的变量a,就需要在 :: 前加上Celia。

cout << Celia::a << endl;//输出Celia命名空间中成员整型变量a

 3.3 命名空间的使用

我们想要使用命名空间中的成员,主要有以下三个方法:

  1. 指定命名空间访问,如:Celia::a
  2. 使用using将命名空间的某个成员展开,如 using Celia::a
  3. 展开命名空间中的全部成员,如 using namespace Celia

展开的成员不需要再重复使用域作用限定符 :: 修饰即可访问。如果使用域作用限定符,语法上也不算错。

#include<iostream>
using namespace std;
namespace Celia
{int a = 10;char b = 'x';
}using Celia::a;  //仅仅展开Celia命名空间成员变量a
using namespace Celia;	//展开Celia命名空间全部成员int main()
{cout << a << endl;  //已展开,直接访问即可。如果局部有变量a,仍优先访问局部变量cout << Celia::a << endl; //指定域名访问return 0;
}

注意:如果在同一个域中,展开的成员和域中现有的成员同名,会报错。

在之前的代码中,曾出现以下语句:

using namespace std;

这段代码是展开了C++语言标准库中的所有成员,为了编程的便利性,在进行简单代码的书写时,会加上这句话。在实际开发中,不建议这样做,因为这样可能会导致重名的现象。在实际开发中使用指定域名访问展开域名空间的一部分成员的做法较为常见。


如果未出现这段语句,由于cout(输出)、cin(输入)、endl(换行)这些函数是定义在std命名空间内的,不能直接使用,必须使用指定域名进行访问。

int main()
{int a;  //定义变量astd::cin >> a;  //输入astd::cout << a << std::endl; //输出a并换行return 0;
}

四、C++的输入输出

  • <iostream>是InputOutputStream的缩写,是标准的输入、输出流库,定义了标准的输入、输出对象。
  • std::cin是istream类的对象,它主要面向窄字符(narrowcharacters(oftypechar))的标准输入流。
  • std::cout是ostream类的对象,它主要面向窄字符的标准输出流。
  • std::endl是⼀个函数,流插入输出时,相当于插入⼀个换行字符加刷新缓冲区。
  • << 是流插入运算符,>> 是流提取运算符。
  • C++的输入、输出可以自动检测变量类型(本质上是函数重载),不需要像C语言指定类型进行操作。
  • cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要通过命名空间的使用方式去用他们。
  • 有一些编译器的<iostream>包含了<stdio.h>,有一些则没有包含。
  • 如果对于输入输出的效率有要求,可以在代码中加入以下代码段,以提高输入输出效率:
    //需要展开std命名空间
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

五、缺省参数

  缺省参数是在声明或定义函数时,将该函数的某个或多个参数给定一个缺省值。如果在调用函数传参时,未传入指定的实参,则该参数为指定的缺省值;如果传入指定实参,则该参数为传入的实参值。缺省参数分为全缺省和半缺省(参数列表中不完全都是缺省参数)。缺省参数多用于某些函数在没有指定传参时,仍需要一个默认参数的情况

#include<iostream>
using namespace std;void Init(int *a, int size = 4) //size为缺省参数
{//开辟空间a = (int*)malloc(sizeof(int) * size);
}
int main()
{int* a = NULL;Init(a);	//这里没有传入size,size默认为缺省值4free(a);return 0;
}

5.1 缺省参数的使用规定

  • 全缺省就是形参全部都给定缺省值,半缺省就是部分形参给定缺省值。C++规定在给定缺省值时,半缺省必须从右到左依次连续给定,不能间隔跳跃给定缺省值。
  • 带缺省参数的函数调用,C++规定必须从左到右依次传参,不能跳跃传参
  • 函数定义和声明分离时,缺省参数不能在声明和定义中同时出现。C++规定,函数定义和声明分离时,必须在声明时给定缺省值
void Init(int v = 9,int *a, int size = 4) //error 跳跃给定缺省值
{//开辟空间a = (int*)malloc(sizeof(int) * size);
}
void Init(int* a, int size = 4);
void Init(int *a, int size = 4) //error
{//开辟空间a = (int*)malloc(sizeof(int) * size);
}/*===============================================================*/void Init(int* a, int size = 4);
void Init(int *a, int size)  //√
{//开辟空间a = (int*)malloc(sizeof(int) * size);
}

 六、函数重载

  如果两个函数同名,但是它们的参数列表不同(包括顺序,个数,参数数据类型。和返回值无关),这种情况称为函数重载,调用该函数时,会根据传参的不同,在编译时确定具体调用哪个函数。C++支持函数重载,能更灵活的应对不同的调用情况。

int Add(int a, int b)
{return a + b;
}
double Add(double a, double b)
{return a + b;
}
int main()
{cout << Add(1, 1) << endl;    //输出2cout << Add(1.5, 1.9) << endl;//输出3.4return 0;
}
//参数类型不同
void func(int a){}
void func(double a){}//参数个数不同
void func(){}
void func(int a){}//参数数据类型顺序不同
void func(int a, char b){}
void func(char a, int b) {}

 还有一种情况下,两个函数构成重载,但是在调用时会报错:

void func(int a = 9){}
void func(){}
int main()
{func();  //error,如果传参,可以编译通过,若不传参,会产生歧义return 0;
}

此时编译器不知道调用的到底是哪个函数。 

七、引用

7.1 引用的概念

  引用,相当于对一个对象起了一个别名。在定义引用时,不同于定义变量,定义引用并不会开辟新的空间,而是与它引用的对象共用一块内存空间。

类型& 别名 = 被引用对象
int main()
{int a = 0;//定义引用p,p是a的别名int& p = a;//定义引用pp,pp是p的别名int& pp = p;p++;pp++;cout << a << endl;//输出2//以下输出三个地址是一样的,都是a的地址cout << &a << endl;cout << &p << endl;cout << &pp << endl;return 0;
}

 7.2 引用的特性

  1. 引用必须初始化
  2. 引用一旦有了引用的对象,将不能引用其他对象。
  3. 一个对象可以有多个引用。

7.3 引用的使用

  • 引用主要用于传参和返回值,以减少拷贝增加效率,或在改变引用时改变被引用的对象。
  • 引用和指针类似,但使用起来比指针更加的方便。
  • 由于引用不可改变指向,所以引用是不能完全替代指针的。

7.4 const引用

  • 有const修饰的对象必须用const引用,const引用也可以引用普通对象,但通过这个引用访问该对象的权限缩小了(通过const引用不能改变该对象)。
  • 在某些情况下,比如表达式、隐式类型转换的结果,会产生一个临时对象,而临时对象具有常性,如果使用非const引用来引用这些结果,会放大该引用的访问权限(具有常性的对象不可变,非const引用是可以改变被引用的对象的),这是不被允许的。这种情况下,只能使用const引用。
int main()
{const int a = 10;const int& p = a;int b = 20;const int& pp = b;pp++;//error,权限被缩小b++;//√double c = 7.0;const int& p2 = (a + b);//表达式const int& p3 = c;//隐式类型转换return 0;
}

7.5 引用和指针的关系

  • 语法概念上引用是⼀个变量的取别名不开空间,指针是存储⼀个变量地址,要开空间。
  • 引用在定义时必须初始化,指针建议初始化,但是语法上不是必须的。
  • 引用在初始化时引用⼀个对象后,就不能再引用其他对象;而指针可以在不断地改变指向对象。
  • 引用可以直接访问指向对象,指针需要解引用才是访问指向对象。
  • sizeof中含义不同,引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位下是8byte)
  •  指针很容易出现空指针和野指针的问题,引用很少出现,引用使用起来相对更安全⼀些。

八、inline 内联函数

  • 被inline修饰的函数叫做内联函数。内联函数在被调用时,不会在栈上额外开辟空间,而是在当前函数的栈帧中展开内联函数,这样可以提高效率。
  • 如果该函数是递归函数,或者函数中语句过多,加上inline也会被编译器忽略。
  • C语言实现宏函数也会在预处理时替换展开,但是宏函数实现很复杂很容易出错的,且不方便调试,C++设计了inline目的就是替代C的宏函数。
  • inline不建议声明和定义分离到两个文件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错。
inline void Swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}
int main()
{int a = 10;int b = 20;Swap(a, b);cout << a << endl << b << endl;return 0;
}

九、nullptr

我们来观察下面的代码:

void func(int* a)
{printf("int*\n");
}
void func(int a)
{printf("int\n");
}
int main()
{func(NULL);  //会输出什么呢?return 0;
}

明明传入的是空指针NULL,为什么会调用参数为整型的函数呢?这是由于在C++中NULL是一个值为0的宏。 那么如果传入(void*)NULL,结果会报错:

为了解决这个从C语言遗留的歧义问题,C++引入了一个新的关键字nullptrnullptr是⼀种特殊类型的字面量,它可以转换成任意其他类型的指针类型,而不能转换成整型

void func(int* a)  //调用这个函数
{printf("int*\n");
}
void func(int a)
{printf("int\n");
}
int main()
{func(nullptr);return 0;
}

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

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

相关文章

UART 通信协议

文章目录 一 简介二 电平标准三 引脚定义四 数据格式五 波特率 一 简介 ​ UART (Universal Asynchronous Receiver/Transmitter)&#xff0c;通用异步收发器&#xff0c;是一种串行、异步、全双工通信协议。 串行&#xff1a;利用一条传输线&#xff0c;将数据一位一位地传送…

一整套开箱即用的前端管理后台解决方案,基于 Vue.js搭配使用 iView UI 组件库形成的,私活神器

前言 在现代Web应用开发中&#xff0c;后台管理系统的构建常常面临诸多挑战&#xff0c;如复杂的权限管理、多语言支持、响应式设计等。现有解-决方案可能存在功能不丰富、定制难度大、开发效率低等问题。 为了解决这些痛点&#xff0c;一款新的软件——iView Admin&#xff…

【Docker】Windows11环境下的安装

前置依赖环境配置 确保虚拟化开启 搜索栏直接搜索如下功能 勾选下面两个选项&#xff0c;确定 重启电脑&#xff0c;以管理员身份打开PowerShell wsl --status wsl --update打开微软应用商店选择一个Ubuntu版本下载并打开 输入一个用户名和密码 然后就可以在Windows下使…

Flink-CDC解析(第47天)

前言 本文主要概述了Flink-CDC. 1. CDC 概述 1.1 什么是CDC&#xff1f; CDC是&#xff08;Change Data Capture 变更数据获取&#xff09;的简称 &#xff0c;在广义的概念上&#xff0c;只要是能捕获数据变更的技术&#xff0c;都可以称之为 CDC。 核心思想是&#xff0c…

昇思MindSpore 应用学习-GAN图像生成-CSDN

模型简介 生成式对抗网络(Generative Adversarial Networks&#xff0c;GAN)是一种生成式机器学习模型&#xff0c;是近年来复杂分布上无监督学习最具前景的方法之一。 最初&#xff0c;GAN由Ian J. Goodfellow于2014年发明&#xff0c;并在论文Generative Adversarial Nets中…

超逼真AI生成电影来了!《泰坦尼克号》AI重生!浙大阿里发布MovieDreamer,纯AI生成电影引爆热议!

视频生成领域的最新进展主要利用了短时内容的扩散模型。然而&#xff0c;这些方法往往无法对复杂的叙事进行建模&#xff0c;也无法在较长时间内保持角色的一致性&#xff0c;而这对于电影等长篇视频制作至关重要。 对此&#xff0c;浙大&阿里发布了一种新颖的分层框架Mov…

图解分布式事务中的2PC与Seata方案

文章目录 文章导图什么是2PC解决传统2PC方案XA方案DTP模型举例&#xff1a;新用户注册送积分总结&#xff1a; Seata方案设计思想执行流程举例&#xff1a;新用户注册送积分 Seata实现2PC事务&#xff08;AT模式&#xff09;前提整体机制写隔离读隔离实际案例理解要点说明核心代…

uniapp小程序中富文本内容渲染图片不展示的问题

文章目录 1.从后端请求的数据中图片是这样的2.前端我是用Uview中的u-parse组件3.这样修改去掉富文本中的所有反斜杠4.完美解决 1.从后端请求的数据中图片是这样的 <p><img src\\\"https://zhangsanfengcode.cn:8084/images/2024-06-28a257befe.jpg\\\" alt…

如何使用 SQLite ?

SQLite 是一个轻量级、嵌入式的关系型数据库管理系统&#xff08;RDBMS&#xff09;。它是一种 C 库&#xff0c;实现了自给自足、无服务器、零配置、事务性 SQL 数据库引擎。SQLite 的源代码是开放的&#xff0c;完全在公共领域。它被广泛用于各种应用程序&#xff0c;包括浏览…

关于 OSPF 序列号范围 0x80000001-0x7FFFFFFF 正本清源

注&#xff1a;机翻&#xff0c;未校对。 正本&#xff1a;RFC 2328 OSPF Version 2 中相关解释 April 1998 12.1.6. LS sequence number 12.1.6. 序列号 The sequence number field is a signed 32-bit integer. It is used to detect old and duplicate LSAs. The space …

【OSS对象存储】Springboot集成阿里云OSS + 私有化部署Minio

【OSS对象存储】Springboot集成阿里云OSS 私有化部署Minio 一、摘要二、POM依赖三、配置文件四、表结构设计五、代码实现5.1 代码包结构5.2 API封装5.3 增删改查 六、扩展6.1 Minio配置https访问 一、摘要 掌握阿里云OSS、私有化部署Minio两种对象存储的使用方式运用工厂策略…

【C++指南】内存管理(上)

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法》 期待您的关注

vue上传Excel文件并直接点击文件列表进行预览

本文主要内容&#xff1a;用elementui的Upload 组件上传Excel文件&#xff0c;上传后的列表采用xlsx插件实现点击预览表格内容效果。 在项目中可能会有这样的需求&#xff0c;有很多种方法实现。但是不想要跳转外部地址&#xff0c;所以用了xlsx插件来解析表格&#xff0c;并展…

总结一些vue3小知识3

总结一些vue3小知识1&#xff1a;http://t.csdnimg.cn/C5vER 总结一些vue3小知识2&#xff1a;http://t.csdnimg.cn/sscid 1.限制时间选择器只能选择后面的日期 说明&#xff1a;disabled-date属性是一个用来判断该日期是否被禁用的函数&#xff0c;接受一个 Date 对象作为参…

科普文:分布式架构中的三高:高并发、高性能、高可用

关于高并发 高并发场景 互联网应用以及云计算的普及&#xff0c;使得架构设计和软件技术的关注点从如何实现复杂的业务逻 辑&#xff0c;转变为如何满足大量用户的高并发访问请求。 一个简单的计算处理过程&#xff0c;如果一旦面对大量的用户访问&#xff0c;整个技术挑战就…

DP 整数拆分不同的二叉搜索树 DAY21

整数拆分&#xff1f; 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。示例 2: 输入: n 10 输…

实验2-2-1 温度转换

#include<stdio.h> #include <math.h> int main(){int c,f150;c5*(f-32)/9;printf("fahr 150, celsius %d",c); }

sqlilabs解题方法

Lass1 查询id为1的用户名和密码 查询id为2的用户名和密码 没有回显&#xff0c;不含id-1的行 判断字段数&#xff0c;字段数为3 查询数据库用户名&#xff0c;和数据库名 查询时id必须超出数据库以外&#xff0c;一般用-1 用户名&#xff1a;user() 数据库名&#xff1a;databa…

redis:清除缓存的最简单命令示例

清除redis缓存命令(执行命令列表见截图) 1.打开cmd窗口&#xff0c;并cd进入redis所在目录 2.登录redis redis-cli 3.查询指定队列当前的记录数 llen 队列名称 4.清除指定队列所有记录 ltrim 队列名称 1 0 5.再次查询&#xff0c;确认队列的记录数是否已清除

opencascade AIS_Manipulator源码学习

前言 AIS_Manipulator 是 OpenCASCADE 库中的一个类&#xff0c;用于在3D空间中对其他交互对象或一组对象进行局部变换。该类提供了直观的操控方式&#xff0c;使用户可以通过鼠标进行平移、缩放和旋转等操作。 详细功能 交互对象类&#xff0c;通过鼠标操控另一个交互对象…