C++——基础语法(1)

news2024/11/15 10:42:23

前言

        一路磕磕绊绊,也算是走到了C++的大门下。C++从名字上就可以看出是C语言的“plusplus版本”,C++在兼容C语言的基础上又加入了许多方便又高深的特性与机制,便于我们更容易处理C语言中的棘手问题。不得不提的一点是C++为我们打开了面向对象思想的大门,过去我们写过的C语言都是遵循面向过程的思想,而C++的面型对象在面对复杂的问题,规模较大的 程序,需要高度的抽象和建模时,相较于C语言要方便很多,所以是一门很值得学习的语言。

        废话就不多说了,我们直接步入正题,踏入C++的世界吧。

1. 命名空间

        命名空间的提出主要是解决C语言中命名冲突的问题。在C语言中第三方库、标准库、自己定义的名字等等之间不可避免的存在命名相同的情况,这个时候只能对命名进行修改。

int main()
{
	int rand = 2;//在C语言中会出现重命名的情况,因为rand是一个库函数名
	return 0;
}

         在C++中,引入了命名空间的概念,通俗理解就是将各种标识符的名称汇集起来放在一个命名空间中,而许多这样不同空间就可以使得虽然名字相同,但处在不同的命名空间内,不会产生冲突。

1.1 命名空间的定义

        命名空间的定义使用关键字namespace,然后接命名空间的名字,然后使用{}包含所有命名空间的成员。需要注意:①命名空间中可以定义变量、函数、类型;②命名空间可以嵌套定义;③如果定义了相同名称的命名空间,编译器会将其合并为一个。

//命名空间的定义
namespace np1
{
	//命名空间内可以定义变量、函数、类型,也可以嵌套其他命名空间
	int a = 9;
	int Add(int a, int b)
	{
		return a + b;
	}
	struct Node
	{
		struct Node* next;
		int val;
	};
	namespace np2
	{
		int a = 8;
		char c;
		int Sub(int a, int b)
		{
			return a - b;
		}
	}
}
//相同名称的命名空间最后会被编译器合并成为一个
namespace np1
{
	int b;
}
namespace np2 //该命名空间不会和np1中的np2合并
{
	int b = 6;
	short a = 7;
}

1.2 命名空间的使用

         命名空间的使用有三种方式:①命名空间 + ::(域作用限定符);②using引入某个成员;③using namespace引入整个命名空间。

namespace np1
{
	int a = 9;
	int Add(int a, int b)
	{
		return a + b;
	}
	struct Node
	{
		struct Node* next;
		int val;
	};
	namespace np2
	{
		int a = 8;
		char c;
		int Sub(int a, int b)
		{
			return a - b;
		}
	}
}
namespace np1
{
	int b;
}
namespace np2
{
	int b = 6;
	short a = 7;
}

//命名空间的使用
//1.命名空间 配合 ::
// :: -- 域作用限定符
int main()
{
	printf("%d ", np1::a);
	printf("%d ", np1::Add(2,6));
	return 0;
}

//2.通过using引入命名空间的某个成员
using np1::np2::a;
using np2::b;
int main()
{
	printf("%d ", a);
	printf("%d ", b);
	return 0;
}

//3.通过using namespace引入整个命名空间
using namespace np1;
int main()
{
	printf("%d ", Add(7, 9));
	printf("%d ", a);
	printf("%d ", np1::np2::a);//因为np1被展开了,所以np2的指向不明确,np1::np2表示np1中的np2
	printf("%d ", ::np2::a);//::np2表示全局域下的np2
	return 0;
}

1.3 变量名搜索顺序

        我们首先要理解域的概念。在C语言的学习过程中,我们知道全局域和局部域的概念,在此处我们再介绍一个命名空间域,很明显就是命名空间内的区域。除此之外还有类域的概念我们以后会接触到。

        对于一个变量,如果指定了域则会直接到域中搜索该名称;否则就遵循先搜索局部,后搜索全局的顺序。在C++中,可以使用域作用限定符来表示全局变量。

//域:全局域、局部域、命名空间域、类域
//对于一个变量名:如果没有指定域则先搜索局部,后搜索全局
//				  如果指定了域则直接去对应域中搜索
namespace np1
{
	int a = 9;
	namespace np2
	{
		int a = 8;
		char c;
	}
}
namespace np2
{
	int b = 6;
	short a = 7;
}
int a = 4;
int main()
{
	int a = 2;
	printf("%d\n", a); //2
	{
		printf("%d\n", a); //2
	}
	printf("%d\n", ::a); //4 此处的::表示全局变量
	printf("%d\n", np1::a); //9
	printf("%d\n", np2::a); //7
	return 0;
}

2. 输入输出

        在想要学习一门语言时,我们的第一步自然就是用它向世界问号,那么C++如何打印hello world呢?

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

        我们来逐行对这个简单的代码进行理解。

        第一行是包含头文件的操作,iostream就是一个标准输入输出流文件。但是我们发现和C语言不同的是没有了后缀.h,这是为了和C语言区分。

        第二行是使用命名空间std。std是C++标准库的命名空间,C++标准库的定义都在这个命名空间中。由此我们发现,头文件中有的只是函数、变量的声明,而定义部分都位于std命名空间内。

        main函数内就是打印hello world的部分。cout是标准输出对象(控制台),对应的cin是标准输入对象(键盘),endl表示输出换行。而<<则是流插入运算符,cout<<"hello world"表示向cout(控制台)插入字符串。同样的,>>就是流提取运算符。

        在C++的输入输出是,不再像printf和scanf一样需要输入%d等规定类型,C++可以自动识别变量类型。

#include<iostream>
using namespace std;
int main()
{
	// <<
	//1.左移
	int a = 2;
	int b = a << 2;
	//2.流插入
	const char* str = "ccc\n";
	cout << "hello world" << a << str << b << endl;
	// >>
	//1.右移
	//2.流提取
	cin >> a >> b;
	cout << a << b;
	return 0;
}

3. 缺省参数

        缺省参数就是在声明或定义函数时,为函数的参数设定一个缺省值。在调用函数的时候,如果指定了参数,则用实参;如果没有给定实参,就使用缺省值作为参数。

void func(int a = 10, int b = 33)
{
	cout << a << ' ' << b << endl;
}
int main()
{
	func(7, 9); //7 9
	func(23);   //23 33
	func();     //10 33
	return 0;
}

        缺省分为全缺省和半缺省两种。全缺省就是所有参数都有缺省值,而半缺省则是部分参数有缺省值。缺省值必须是常量或者全局变量。

void func1(int a = 10, int b = 33) //全缺省
{
	cout << a << ' ' << b << endl;
}
void func2(int a, int b = 79, int c = 88) //半缺省
{
	cout << a << ' ' << b << ' ' << c << endl;
}
int main()
{
	func1(7, 9); //7 9
	func1(23);   //23 33
	func1();     //10 33
	func2(1,62,35);  //1 62 35
	func2(48,29);    //48 29 88
	func2(12);       //12 79 88
	//func2();       //error
	return 0;
}

        函数调用时会传参,这时实参会按顺序传给形参,知道实参全部使用完毕。如果这时发现还有参数没有值,那么就使用给出的缺省值。因此我们得到结论:传递的参数是从前向后依次传递,缺省值应从后向前覆盖,即一个参数有缺省值就说明其后的参数都有缺省值。值得再次强调的是传参不会跳着传,缺省值也不可以跳着给。

void func(int a = 10, int b) //error
{
	cout << a << ' ' << b << endl;
}

        另一个需要明确的事情是当定义和声明分离,缺省值应该给定义还是声明还是两个都有,不同该怎么办?

        首先给出答案,在定义和声明分离时,缺省值必须且只能在声明时给出

对于这样的代码:

        test.cpp

#include"test.h"
int main()
{
	func(1);
	return 0;
}

        func.cpp

#include"test.h"
void func(int a, int b)
{
	cout << a + b << endl;
}

         test.h

#pragma once
#include<iostream>
using namespace std;
void func(int a = 2, int b = 7);

        首先明确的一点是,链接前各个源文件各自编译生成可重定位目标文件。之所以称为可重定位是因为其中的汇编出来的函数地址并不是真正的地址,所以需要链接后再确定。但是我们知道在生成可重定位目标文件后,其机器码需要改变的只是重定位后的地址。换言之,就是调用函数前调用参数已经被压入了栈中。所以缺省值如果在定义处给出,那么此处的调用参数就难以确定,所以必须在声明处给出缺省值,这样参数才可以顺利压入栈。

         对于定义和声明在同一个源文件的情况,缺省值不可以在声明和定义同时出现,换言之,任何一者有缺省值,另一个没有都是正确的。

void func1(int a, int b = 10) //correct
{
	cout << a + b << endl;
}
void func1(int a,int b);

void func2(int a, int b) //correct
{
	cout << a + b << endl;
}
void func2(int a,int b = 10);

void func3(int a, int b = 10) //error
{
	cout << a + b << endl;
}
void func3(int a,int b = 10);

        在借鉴前辈们的心得时发现还有类中等其他情况下的缺省,暂时还接触不到,未来学习到了再做以总结。

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

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

相关文章

【ACM出版】第五届计算机信息和大数据应用国际学术会议(CIBDA 2024)

第五届计算机信息和大数据应用国际学术会议&#xff08;CIBDA 2024&#xff09; 2024 5th International Conference on Computer Information and Big Data Applications 重要信息 大会官网&#xff1a;www.ic-cibda.org 大会时间&#xff1a;2024年3月22-24日 大会地点&#…

Java中哪些很容易出现的坑

文章目录 1空指针2小数的计算3包装类型4Java8 Stream5日期格式化 先来一个简单一点&#xff0c;就从空指针开始吧 1空指针 //多级调用空指针userService.getUser("张三").getUserInfo().getUserName(); //例如getUser("张三")、getUserInfo&#xff08;&a…

基于SpringBoot的景区旅游管理系统

项目介绍 本期给大家介绍一个 景区旅游管理 系统.。主要模块有首页&#xff0c;旅游路线&#xff0c;旅行攻略&#xff0c;在线预定。管理员可以登录管理后台对用户进行管理&#xff0c;可以添加酒店&#xff0c;景区&#xff0c;攻略&#xff0c;路线等信息。整体完成度比较高…

【Java面试系列】JDK 1.8 新特性之 Stream API

目录 一、Stream 简介二、Stream 特点&#xff1a;Stream 注意点&#xff1a;1、什么是聚合操作2、Stream 流1、什么是流2、流的构成3、stream 流的两种操作4、惰性求值和及早求值方法5、Stream 流的并行 三、Stream操作的三个步骤1、创建流第一种&#xff1a;通过集合第二种&a…

2024全球网络安全展望|构建协同生态,护航数字经济

2024年1月&#xff0c;世界经济论坛发布《2024全球网络安全展望》报告&#xff0c;指出在科技快速发展的背景下&#xff0c;网络安全不均衡问题加剧&#xff0c;需加强公共部门、企业组织和个人的合作。 报告强调&#xff0c;面对地缘政治动荡、技术不确定性和全球经济波动&am…

Vue知识学习

Vue 是什么&#xff1f; 概念&#xff1a;Vue 是一个用于构建用户界面的渐进式框架 Vue 的两种使用方式: ① Vue 核心包开发 场景:局部 模块改造 ② Vue 核心包& Vue插件工程化开发 场景:整站开发 创建Vue 实例&#xff0c;初始化渲染的核心步骤: 1.准备容器 2.引包(官…

哪些软件可以把试卷照片转换成电子版?试试这些软件

哪些软件可以把试卷照片转换成电子版&#xff1f;在数字化时代&#xff0c;纸质试卷的保存和传输都显得不太方便。为了解决这个问题&#xff0c;我们可以将试卷照片转换成电子版。下面&#xff0c;我将为大家介绍5款可以轻松实现这一功能的软件&#xff0c;让你轻松应对各种试卷…

吸虫塔的工作原理是什么?

吸虫塔虫情智能测报分析系统是一款专门用于长期动态监测蚜虫等小型迁飞性害虫的大型植保设备&#xff0c;由装置上方的空气动力装置、上下两层远红外虫体处理装置、高清图像采集装置、虫体收集装置等部分组成。昆虫在经由设备上方的吸风装置后会被吸入设备内部&#xff0c;上下…

【超实用!游戏主程必须掌握的必杀技!】

超实用&#xff01;游戏主程必须掌握的必杀技&#xff01; 大家有没有发现&#xff1f;以上问题都存在共性&#xff1a;那就是跨部门的沟通与协作&#xff0c;这是一个必须高度重视的问题。正是因为这些问题的存在&#xff0c;造成初入职场的焦虑和不适应。 那么产生这些问题的…

【大厂AI课学习笔记】【2.2机器学习开发任务实例】(1)搭建一个机器学习模型

今天学习的是&#xff0c;如何搭建一个机器学习模型。 主要有以上的步骤&#xff1a; 原始数据采集特征工程 数据预处理特征提取特征转换&#xff08;构造&#xff09;预测识别&#xff08;模型训练和测试&#xff09; 在实际工作中&#xff0c;特征比模型更重要。 数据和特征…

01_02_mysql06_(视图-存储过程-函数(变量、流程控制与游标)-触发器)

视图 使用 视图一方面可以帮我们使用表的一部分而不是所有的表&#xff0c;另一方面也可以针对不同的用户制定不同的查询视图。比如&#xff0c;针对一个公司的销售人员&#xff0c;我们只想给他看部分数据&#xff0c;而某些特殊的数据&#xff0c;比如采购的价格&#xff0…

flink 任务提交流程源码解析

flinkjob 提交流程 任务启动流程图1客户端的工作内容1.1解析命令1.2 执行用户代码 2集群工作内容2.2启动JobManager和 ResourceManager2.3 申请资源 启动 taskmanager 3分配任务3.1 资源计算3.2 分发任务 4 Task 任务调度执行图5 任务提交过程总结 任务启动流程图 可以先简单看…

【Vue3】toRefs和toRef在reactive中的一些应用

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

如何在debian上实现一键恢复操作系统?

在Debian或任何其他Linux发行版上实现一键恢复操作系统&#xff0c;需要创建一个系统镜像或快照&#xff0c;并设置一个简单的方法来从该镜像恢复。以下是创建和恢复系统的基本步骤&#xff1a; 1. 创建系统镜像&#xff1a; 使用像dd&#xff0c;rsync或专门的备份工具&#…

详细分析UML的10种图(全)

目录 前言1. 基本知识2. 结构图2.1 类图2.2 对象图2.3 组件图2.4 部署图2.5 包图 3. 行为图3.1 用例图3.2 活动图3.3 状态图 4. 行为图4.1 顺序图4.2 协作图 前言 在软考高级中常见的一种题型&#xff0c;对此补充这方面的知识&#xff0c;并将其归入软考的专栏 1. 基本知识 …

全网最最最详细DataEase源码Docker方式部署教程

1.源码获取 有条件的小伙伴可以使用GitHub方式获取&#xff0c;要是没有条件的小伙伴可以去码云上面获取也是一样的&#xff0c;或者可以联系博主&#xff0c;博主手把手教学~ GitHub地址 Gitee地址 2.配置源码信息 1.配置单机版的配置文件中的数据库信息 2.下载前端的依赖包…

顺序表经典算法及其相关思考

27. 移除元素 - 力扣&#xff08;LeetCode&#xff09; 思路一 利用顺序表中的SLDestroy函数的思想&#xff0c;遇到等于val值的就挪动 思路二 双指针法&#xff1a;不停的将和val不相等的数字往前放。此时的des更像一个空数组&#xff0c;里面存放的都是和val不相等、能够存…

java面试JVM虚拟机篇

1 JVM组成 1.1 JVM由那些部分组成&#xff0c;运行流程是什么&#xff1f; 难易程度&#xff1a;☆☆☆ 出现频率&#xff1a;☆☆☆☆ JVM是什么 Java Virtual Machine Java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 好处&#xff1a; 一次编写&a…

常见消息中间件

ActiveMQ 我们先看ActiveMQ。其实一般早些的项目需要引入消息中间件&#xff0c;都是使用的这个MQ&#xff0c;但是现在用的确实不多了&#xff0c;说白了就是有些过时了。我们去它的官网看一看&#xff0c;你会发现官网已经不活跃了&#xff0c;好久才会更新一次。 它的单机吞…

Unity Meta XR SDK 快捷配置开发工具【Building Block/Quick Action/OVRCameraRigInteraction】

文章目录 &#x1f4d5;教程说明&#x1f4d5;Building Block&#x1f4d5;Quick Action&#x1f4d5;OVRCameraRigInteraction 此教程相关的详细教案&#xff0c;文档&#xff0c;思维导图和工程文件会放入 Spatial XR 社区。这是一个高质量 XR 社区&#xff0c;博主目前在内…