从“Hello,World”谈起(C++入门)

news2024/9/17 7:29:33

前言

c++的发展史及c++能干什么不能干什么不是我们今天的重点,不在这里展开,有兴趣的朋友可以自行查阅相关资料。今天我们主要是围绕c++的入门程序,写一个“hello,world”,并且围绕这个入门程序简单介绍一下c++和c++的一些语法,做一个简单的入门

c++是兼容c的

我们以前在学c的时候也写过c的入门程序

#include <stdio.h>

int main()
{
	printf("Hello,World");
	return 0;
}

在c++中这样写是完全支持的,但c++也有一套自己的输入输出体系。我们可以先简单看一下

#include <iostream>

using namespace std;

int main()
{
	cout << "Hello,World" << endl;
}

我们知道c++出现的背景就是为了解决c中不方便的部分。我们结合这个入门程序,看一下c中有哪些弊端,c++又是如何优化的

命名空间

在C语言中,有的时候我们会遇到一种情况

#include <stdio.h>
#include <stdlib.h>

int rand = 10;

int main()
{
	printf("%d", rand);
}

当我们运行这段代码时,我们发现报错了。我们可以来看一下报错信息

通过观察不难发现是因为rand重定义导致的。不对啊,我们只定义了一个全局的rand变量,怎么会有重定义的错误呢?原来是因为 stdlib.h 这个头文件会在编译时展开,这个头文件里包含了rand()函数导致重定义的问题。显然,这个问题在C语言中比较常见,也很隐蔽,我们不可能知道我们包含的头文件里有哪些被定义过的符号和名称,为了解决这个问题c++提出了命名空间的概念。

命名空间的关键字是namespace,我们使用的时候需要在namespace后面紧跟空间的名称,在用{}包裹空间,里面可以写变量和函数,不需要跟;号

namespace zzzyh {
	int a;
	int b();
}
//其中空间名称可以任意

使用时编译器默认会在局部和全局找,如果需要在命名空间内找需要使用 :: 指定

#include <iostream>
int a = 10;
namespace zzzyh {
	int a=20;
	int b();
}
using namespace std;

int main()
{
	cout << zzzyh::a << endl;
	return 0;
}

这里的输入是20,如果没有指定zzzyh::,则会在全局变量里找,输出10

namespace只能定义在全局,可以嵌套定义,嵌套定义也需要嵌套使用

c++的标准库都是在std这个命名空间中

可以在文件的多个地方定义多个同名的命名空间,最终会被整合到一起

前面应该有朋友注意到了,为啥cout,endl是std里的方法,我们没有使用std:: 的方式访问,而是直接访问?这是因为命名空间可以使用 using展开,当全局变量使用,当然也可选择展开特定的变量和函数

输入输出

c++和c一样需要包和输入输出有关的头文件,不过c++的输入输出头文件是这样包的

#include <iostream>

完整格式

#include <iostream>

int main()
{
	int i;
	std::cin >> i;
	std::cout << i << std::endl;
}

<iostream>是InputOutputStream的缩写,是标准的输⼊、输出流库,定义了标准的输⼊、输
出对象

std::cin是istream类的对象,标准输⼊流

std::cout是ostream类的对象,标准输出流

std::endl是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区

<<是流插⼊运算符,>>是流提取运算符。(C语⾔还⽤这两个运算符做位运算左移/右移)

c++的输入输出流相比于c而言简单了不少,这得益于c++实现自动识别类型,程序员不需要再输入输出中指定类型

如果再需要高性能的需求下,可以增加一下代码提高IO效率

ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);

 

缺省参数

缺省参数是c完全不支持,c++提出的概念,可以理解为在不知道具体传谁的时候为函数提供默认值。

在函数声明或者定义是,可以指定某些参数或者全部参数=某个值,如果后续在调用该函数时,对应的参数传参了则使用传入的参数,没有传参则使用默认的参数。可以分为全缺省和半缺省

规定半缺省只能从右往左连续缺省,不可跨越,这也是为了在编译时能准确确定调用的是哪个函数

传参也规定只能从左往右依次传入,不允许跨越,目的和上面一样方便编译时确定是哪个函数

如果函数的声明和定义,缺省值需要写在该函数声明处,函数定义处不写

函数重载

我们在c中,如果需要实现一个面对不同类型的加法函数往往需要起多个函数名来区分,函数重载就是为了结局这个问题的。函数重载要求函数名相同,函数的参数数量/顺序/类型不同,返回值不做要求。这样定义多个加法函数可以共用同一个函数名,但根据不同的函数参数来确定具体使用哪一个函数,降低使用成本,增加代码的可读性

引用

c中有指针的概念,就是开辟一块空间指向另一块空间,指向的空间存储被指向空间的地址,就叫指针,用指针间接操作被指向的空间

c++的引用我们认为是不开辟空间的,只是为这块空间取别名,通过别名直接操作原空间

类型& 引⽤别名 = 引⽤对象;
#include<iostream>
using namespace std;
int main()
{
int a = 0;
// 引⽤:b和c是a的别名
int& b = a;
int& c = a;
// 也可以给别名b取别名,d相当于还是a的别名
int& d = b;
++d;
// 这⾥取地址我们看到是⼀样的
cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
cout << &d << endl;
return 0;
}

特性

引用必须初始化,一块空间可以有多个引用,引用不能再更改指向

使用

在使用上,我们常用在函数传参和函数返回值上,可以提高效率的同时更加方便的修改被引用对象。

引⽤和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代
 

const引用

可以引⽤⼀个const对象,但是必须⽤const引⽤。const引⽤也可以引⽤普通对象,因为对象的访
问权限在引⽤过程中可以缩⼩,但是不能放⼤
在例如类型转换或者A*B这样的算式中,会有一个临时变量暂存结果的值,这个临时变量是具有常性的,可以理解为被const修饰

int main()
{
const int a = 10;
// 编译报错:error C2440: “初始化”: ⽆法从“const int”转换为“int &”
// 这⾥的引⽤是对a访问权限的放⼤
//int& ra = a;
// 这样才可以
const int& ra = a;
// 编译报错:error C3892: “ra”: 不能给常量赋值
//ra++;
// 这⾥的引⽤是对b访问权限的缩⼩
int b = 20;
const int& rb = b;
// 编译报错:error C3892: “rb”: 不能给常量赋值
//rb++;
return 0;
}
#include<iostream>
using namespace std;
int main()
{
int a = 10;
const int& ra = 30;
// 编译报错: “初始化”: ⽆法从“int”转换为“int &”
// int& rb = a * 3;
const int& rb = a*3;
double d = 12.34;
// 编译报错:“初始化”: ⽆法从“double”转换为“int &”
// int& rd = d;
const int& rd = d;
return 0;
}

 

inline

inline是一个内联函数的关键字,内联函数会在调用出展开,不建立栈帧以提高效率。但这也是建议编译器内联而已,具体内不内敛由编译器决定,内联一般需要函数体积足够小,调用足够频繁。这是为了替代c的宏函数。内联函数建议声明定义在一个文件中,否则容易造成链接错误

nullptr

在c/c++中的NULL是宏,在传统的C头⽂件(stddef.h)中,可以看到如下代码

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

c++的NULL定义为0,在实际使用中会混淆,因此引入nullprt关键字标识空指针

nullptr是⼀种特殊类型的字⾯量,它可以转换成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式地转换为指针类型,⽽不能被转换为整数类型

结语

以上便是今天的全部内容。如果有帮助到你,请给我一个免费的赞。

因为这对我很重要。

编程世界的小比特,希望与大家一起无限进步。

感谢阅读!

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

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

相关文章

事务的学习

一、什么是事务 事务 是一组操作的集合&#xff0c;是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销请求&#xff0c;这些操作要么同时成功&#xff0c;要么同时失败 一组操作集合&#xff0c;不可分割&#xff0c;一起向系统提交/…

7.2 AQS原理

AQS 原理 概述 全称是 AbstractQueuedSynchronizer&#xff0c;是阻塞式锁和相关的同步器工具的框架。 特点&#xff1a; 用 state 属性来表示资源的状态&#xff08;分独占模式和共享模式&#xff09;&#xff0c;子类需要定义如何维护这个状态&#xff0c;控制如何获取锁和…

Clion 使用gdbserver调试FreeSWITCH源码

1.准备环境 window安装clion安装好gdb、ssh、已经编译好的freeswitch可执行文件的docker镜像2.配置clion Settings -> Tools ->SSH Configurations Settings-Build, Execution, Deployment-Toolchains(其实设不设置都行,用默认也行的) Settings-Build, Execution, Depl…

JVM内存配置错误导致的线上服务问题

1.现象 大量用户反映不能正常使用服务&#xff0c;导致用户无法进行下一步工作。 2.检查 因为是休息日&#xff0c;初步听到这个消息的时候怀疑是自己的锅。一是因为项目刚刚进行了重构&#xff1b;二是对MySQL数据进行了迁移&#xff0c;并且对待迁移的旧数据进行了数据分析…

【qt】如何读取文件并拆分信息?

需要用到QTextStream类 还有QFile类 对于文件的读取操作我们可以统一记下如下操作: 就这三板斧 获取到文件名用文件名初始化文件对象用文件对象初始化文本流 接下来就是打开文件了 用open()来打开文件 用readLine()来读取行数据 用atEnd()来判断是否读到结尾 用split()来获取…

LabVIEW中modbusTCP怎样才能和profibusDP通信?

在LabVIEW中&#xff0c;Modbus TCP和Profibus DP是两种不同的工业通信协议&#xff0c;要实现这两者之间的通信&#xff0c;可以采用网关设备进行协议转换&#xff0c;或者通过一个中间设备&#xff08;如PLC&#xff09;进行数据桥接。以下是实现此通信的一些方法&#xff1a…

王牌站士Ⅵ--人工智能集成商的崛起

前言 系统集成商 (SI) 具有独特的优势&#xff0c;可以利用 GenAI 的变革力量。通过综合各种数据并重新定义客户获取见解和采取行动的方式&#xff0c;SI 可以发展成为AI 集成商&#xff0c;彻底改变企业的运营方式和与技术的互动方式&#xff0c;当然&#xff0c;还可以保留长…

[人工智能]对未来建筑行业的影响

作者主页: 知孤云出岫 目录 引言1. 人工智能在建筑行业的应用场景1.1 设计阶段1.2 施工阶段1.3 运营和管理 2. 关键技术2.1 机器学习2.2 计算机视觉2.3 自然语言处理2.4 大数据分析 3. 实际案例分析3.1 案例1&#xff1a;利用GAN生成建筑设计方案3.2 案例2&#xff1a;利用计算…

在ROS中控制机器人运动

一、安装Arbotix 输入指令&#xff1a;sudo apt install ros-noetic-arbotix 找到下载的文件&#xff1a;roscore,roscd arbotix 安装好后&#xff0c;不需要按照教程里面的操作&#xff0c;复制进工作空间。 二、在config中建立配置文件&#xff0c;control.yaml # 该文件…

了解并缓解 IP 欺骗攻击

欺骗是黑客用来未经授权访问计算机或网络的一种网络攻击&#xff0c;IP 欺骗是其他欺骗方法中最常见的欺骗类型。通过 IP 欺骗&#xff0c;攻击者可以隐藏 IP 数据包的真实来源&#xff0c;使攻击来源难以知晓。一旦访问网络或设备/主机&#xff0c;网络犯罪分子通常会挖掘其中…

给 「大模型初学者」 的 LLaMA 3 核心技术剖析

编者按&#xff1a; 本文旨在带领读者深入了解 LLaMA 3 的核心技术 —— 使用 RMSNorm 进行预归一化、SwiGLU 激活函数、旋转编码&#xff08;RoPE&#xff09;和字节对编码&#xff08;BPE&#xff09;算法。RMSNorm 技术让模型能够识别文本中的重点&#xff0c;SwiGLU 激活函…

敏捷开发笔记(第10章节)--Liskov原则(LSP)

目录 1&#xff1a;PDF上传链接 10.1 Liskov替换原则&#xff08;LSP&#xff09; 10.2 一个违反LSP的简单例子 10.6 启发式规则和习惯用法 10.7 结论 1&#xff1a;PDF上传链接 【免费】敏捷软件开发(原则模式与实践)资源-CSDN文库 OCP背后的主要机制是抽象(abstraction…

CSS【详解】边框 border,边框-圆角 border-radius,边框-填充 border-image,轮廓 outline

边框 border border 是以下三种边框样式的简写&#xff1a; border-width 边框宽度 —— 数值 px&#xff08;像素&#xff09;,thin&#xff08;细&#xff09;,medium&#xff08;中等&#xff09;,thick&#xff08;粗&#xff09;border-style 边框线型 —— none【默认值…

数据库MySQL下载安装

MySQL下载安装地址如下&#xff1a; MySQL :: Download MySQL Community Server 1、下载界面 2、点击下载 3、解压记住目录 4、配置my.ini文件 未完..

整洁架构SOLID-里氏替换原则(LSP)

文章目录 定义LSP继承实践正例反例 LSP软件架构实践反例 小结 定义 1988年&#xff0c;Barbara Liskov在描述如何定义子类型时写下了这样一段话&#xff1a; 这里需要的是一种可替换性&#xff1a;如果对于每个类型是S的对象o1都存在一个类型为T的对象o2&#xff0c;能使操作T…

树莓派PICO使用INA226测量电流和总线电压(1)

TI的INA226是一款不错的16位电流测量芯片&#xff0c;拥有非常高的性价比&#xff0c;而且测量精度能够覆盖我们大多数的应用场景&#xff0c;INA226的接线也比较简单&#xff0c;通过I2C读取数据会稍微麻烦一点。 INA226可以在淘宝上直接买开发板&#xff0c;非常的便宜&#…

本地部署,去除动漫图像背景Anime Remove Background

目录 摘要 引言 深度学习在动漫角色中的应用 1.​U-Net 2.Mask R-CNN 3.ISNet 模型 4.MODNet 模型 5.InSPyReNet 模型 本地部署 运行效果 测验结果​ Tip&#xff1a; 摘要 动漫图像背景去除是一项在图像处理和计算机视觉领域具有重要应用的技术&#xff0c;广泛应用于…

「Pytorch」roLabelImg 图像异常旋转 bug

在进行Yolo-obb 模型训练的时候需要标注旋转框&#xff0c;roLabelImg 是比较推荐的一款旋转框标注工具&#xff0c;既可以标注正常的矩形框&#xff0c;还可以标注旋转框 roLabelImg Github 地址&#xff1a;https://github.com/HumanSignal/labelImg 但是在使用过程中遇到了…

Word中使用LaTeX编辑公式

在日常学术写作过程中&#xff0c;公式输入必不可少。然而使用Word传统的公式编辑器往往无法满足高标准的排版要求&#xff0c;如排版不专业、编辑效率低、兼容性差等问题。LaTeX相比Word&#xff0c;在公式输入及排版方面更为强大&#xff0c;但是对于轻量级的任务&#xff0c…

Vivado 2020.1 HLS IP在BD模式无法生成问题

折腾了一周整整&#xff0c;记录一下&#xff0c;希望对大家有用。 各种找、各种操作&#xff0c;也问了FAE&#xff0c;都没搞定。 最后看到如下博文的方法3&#xff0c;管用。 vivado综合hls类ip核报错问题解决方案_vivado ip synth checkpoint mode-CSDN博客 报错描述 m…