初识c++(命名空间,缺省参数,函数重载)

一、命名空间

1、namespace的意义

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全

局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名

冲突或名字污染,namespac关键字的出现就是针对这种问题的。

c语言项目类似下面程序这样的命名冲突是普遍存在的问题,C++引入namespac就是为了更好的解决

这样的问题:(因为我们设置的变量rand和stdlib.h中的rand函数冲突所以报错)

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

2、namespace的定义

1、定义命名空间,需要使用法到namespace关键字,后面跟命名空间的名字,然后接⼀对{}即可,{}中

即为命名空间的成员。命名空间中可以定义变量/函数/类型等。(注意{}后不跟“;”)

2、namespace本质是定义出⼀个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以下

面的rand不在冲突了。

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{int rand = 0;
}
int main()
{printf("%d\n", rand);return 0;
}

3、C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/

类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响

编译查找逻辑,还会影响变量的声明周期,命名空间域和类域不影响变量声明周期。

4、namespace只能定义在全局,当然他还可以嵌套定义。

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{int rand = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}}
int main()
{printf("%d\n", rand);return 0;
}

5、项目工程中多文件中定义的同名namespace会认为是⼀个namespace,不会冲突。

test.c文件

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include"test.h"
namespace tmp
{int rand = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}}
int main()
{printf("%d\n", tmp::d);return 0;
}

test.h文件

#pragma once
namespace tmp
{int d = 0;
}

可以发现在.c文件中可以使用tmp空间中的d变量 。

6、C++标准库都放在⼀个叫std(standard)的命名空间中。

7、如果想使用全局域中的变量我们可以这么操作:

int a = 3;
int main()
{int a = 0;printf("%d\n", ::a);return 0;
}

这样printf先打印的是3。

3、命名空间的使用

编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间里面去查找。所以

下面程序会编译报错。

namespace tmp
{int d = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
int main()
{int a = 0;printf("%d\n", d);//未定义标识符dreturn 0;
}

所以我们要使用命名空间中定义的变量/函数,有三种方式:

1、指定命名空间访问,项目中推荐这种方式。

tmp::d

2、using将命名空间中某个成员展开,项目中经常访问的不存在冲突的成员推荐这种方式。

namespace tmp
{int d = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
using tmp::d;
int main()
{int a = 0;printf("%d\n", d);//未定义标识符dreturn 0;
}

3、展开命名空间中全部成员,项目不推荐,冲突风险很大,日常小练习程序为了方便推荐使用。

namespace tmp
{int d = 0;namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
using namespace tmp;
int main()
{int a = 0;printf("%d\n", d);//未定义标识符dreturn 0;
}

二、输入和输出

1、 是 Input Output Stream 的缩写,是标准的输入、输出流库,定义了标准的输入、输

出对象。

2、std::cin 是 istream 类的对象,它主要面向窄字符(narrow characters (of type char))的标准输

入流。

3、std::cout 是 ostream 类的对象,它主要面向窄字符的标准输出流。

4、std::endl 是⼀个函数,流插入输出时,相当于插入⼀个换行字符加刷新缓冲区。

5、<<是流插入运算符,>>是流提取运算符。(C语言还用这两个运算符做位运算左移/右移)

6、使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动指定格式,C**++的输入**

输出可以自动识别变量类型(本质是通过函数重载实现的),其实最重要的是C++的流能更好的支持自定义

类型对象输入和输出。

#include<iostream>
#include <stdio.h>
#include <stdlib.h>
namespace tmp
{int a = 0;double b = 0.0;char c = '0';namespace tmp1{int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};}
}
using namespace tmp;
using namespace std;
int main()
{cin >> a >> b >> c;cout << a << b << c;return 0;
}

7、cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要

通过命名空间的使用方式去用他们。

8、⼀般日常练习中我们可以using namespace std,实际项目开发中不建议using namespace std。

三、 缺省参数

1、缺省参数的定义以及规定

缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调用该函数时,如果没有指定实参

则采用该形参的缺省值,否则使用指定的实参,缺省参数分为全缺省和半缺省参数。(有些地方把

缺省参数也叫默认参数)。

全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左

依次连续缺省,不能间隔跳跃给缺省值。

带缺省参数的函数调用,C++规定必须从左到右依次给实参,不能跳跃给实参。

函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省

值。

#include <iostream>
using namespace std;
void Func(int a = 0)
{cout << a << endl;
}
int main()
{Func(); // 没有传参时,使⽤参数的默认值Func(10); // 传参时,使⽤指定的实参return 0;
}

在这里插入图片描述

2、全缺省和半缺省

#include <iostream>
using namespace std;
// 全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
// 半缺省
void Func2(int a, int b = 10, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
int main()
{Func1();Func1(1);Func1(1, 2);Func1(1, 2, 3);Func2(100);Func2(100, 200);Func2(100, 200, 300);return 0;
}

半缺省不能这么写:

void Func2(int a = 10, int b, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
//或者
void Func2(int a = 10, int b, int c)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}

必须严格遵守:

半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。

3、缺省参数的实际应用

我们在没有学c++之前我们实现栈的初始化以及插人时我们是这么写的:

typedef int STDataType;
typedef struct Stack
{STDataType* a;int top;int capacity;
}ST;
// 栈顶
void STInit(ST* ps, int n)
{assert(ps);ps->a = (STDataType*)malloc(n * sizeof(STDataType));ps->top = 0;ps->capacity = n;
}
void STPush(ST* ps, STDataType x)
{assert(ps);// 满了, 扩容if (ps->top == ps->capacity){printf("扩容\n");int newcapacity = ps->capacity == 0 ? 4 : ps->capacity* 2;STDataType* tmp = (STDataType*)realloc(ps->a,newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}

如果我们要插入100个数据则就需要不断的扩容,有效率的损耗,但是我们在学习了缺省参数后我们可以这么写:

// 栈顶
void STInit(ST* ps, int n = 4)
{assert(ps);ps->a = (STDataType*)malloc(n * sizeof(STDataType));ps->top = 0;ps->capacity = n;
}
void STPush(ST* ps, STDataType x)
{assert(ps);// 满了, 扩容if (ps->top == ps->capacity){printf("扩容\n");int newcapacity = ps->capacity == 0 ? 4 : ps->capacity* 2;STDataType* tmp = (STDataType*)realloc(ps->a,newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity = newcapacity;}ps->a[ps->top] = x;ps->top++;
}
int main()
{ST a;STInit(&a, 100);//这里不传100也可以,因为规定必须从左到右依次给实参,不能跳跃给实参。刚好和缺省参数确定位置互补for (int i = 0; i < 100; i++){STPush(&a, i);}return 0;
}

这样就有效避免了重复开辟空间的问题。

四、函数重载

C++支持持在同⼀作用域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者

类型不同。这样C++函数调用就表现出了多态行为,使用更灵活。(但是返回值不同不能作为重载条件,

因为调用时也无法区分,如果返回值和参数类型或者个数同时变化则也为重载条件)。

1、参数类型不同

#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}

2、参数个数不同

// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}

特别的如果上面的用缺省参数那么在不传参数调用时就会报错,编译器不知道调用谁

// 下⾯两个函数构成重载
// f()但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁
void f1()
{cout << "f()" << endl;
}
void f1(int a = 10)
{cout << "f(int a)" << endl;
}

3、参数顺序不同(实际上就是参数类型不同)

// 3、参数类型顺序不同
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}
`#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}``

结果:
在这里插入图片描述

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

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

相关文章

路径规划 | 基于蜣螂优化算法的栅格地图机器人路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 路径规划 | 基于蜣螂优化算法的栅格地图机器人路径规划&#xff08;Matlab&#xff09; 1.利用蜣螂算法DBO优化栅格地图机器人路径规划&#xff0c;效果如图所示&#xff0c;包括迭代曲线图、栅格地图等等&#xff5e…

【智能算法改进】多策略改进的蜣螂优化算法

目录 1.算法原理2.改进点3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】蜣螂优化算法&#xff08;DBO&#xff09;原理及实现 2.改进点 混沌反向学习初始化 采用 Pwlcm 分段混沌映射&#xff0c;由于 Pwlcm 在其定义区间上具有均匀的密度函数&#xff0c;在特定的…

PyCharm中如何将某个文件设置为默认运行文件

之前在使用JetBrain公司的另一款软件IDEA的时候&#xff0c;如果在选中static main函数后按键altenter可以默认以后运行Main类的main函数。最近在使用PyCharm学习Python&#xff0c;既然同为一家公司的产品而且二者的风格如此之像&#xff0c;所以我怀疑PyCharm中肯定也有类似的…

day01:项目概述,环境搭建

文章目录 软件开发整体介绍软件开发流程角色分工软件环境 外卖平台项目介绍项目介绍定位功能架构 产品原型技术选型 开发环境搭建整体结构&#xff1a;前后端分离开发前后端混合开发缺点前后端分离开发 前端环境搭建Nginx 后端环境搭建熟悉项目结构使用Git进行版本控制数据库环…

【Mathematical14.0最新进阶教学】-1-基础计算拓展

我在真正使用Mathematica后&#xff0c;才发觉这个软件的神奇&#xff0c;但是又有对于不知道如何使用这个神奇软件&#xff0c;因此我将我学习《The Student’s Introduction to Mathematica and the Wolfram Language (Bruce F. Torrence, Eve A. Torrence) 》的一些心得进行…

【AI大模型】驱动的未来:穿戴设备如何革新血液、皮肤检测与营养健康管理

文章目录 1. 引言2. 现状与挑战3. AI大模型与穿戴设备概述4. 数据采集与预处理4.1 数据集成与增强4.2 数据清洗与异常检测 5. 模型架构与训练5.1 高级模型架构5.2 模型训练与调优 6. 个性化营养建议系统6.1 营养建议生成优化6.2 用户反馈与系统优化 7. 关键血液成分与健康状况评…

Appium Inspector介绍和使用

一、什么是Appium Inspector 官方介绍&#xff1a;Overview - Appium Inspector 检查器的主要目的是提供应用程序页面源代码的检查功能。它主要用于测试自动化开发&#xff0c;但也可用于应用程序开发 - 或者如果只是想查看应用程序的页面源代码&#xff01; 从本质上讲&…

谈大语言模型动态思维流程编排

尽管大语言模型已经呈现出了强大的威力&#xff0c;但是如何让它完美地完成一个大的问题&#xff0c;仍然是一个巨大的挑战。 需要精心地给予大模型许多的提示&#xff08;Prompt&#xff09;。对于一个复杂的应用场景&#xff0c;编写一套完整的&#xff0c;准确无误的提示&am…

力扣hot100-普通数组

文章目录 题目&#xff1a;最大子数组和方法1 动态规划方法2 题目&#xff1a;合并区间题解 题目&#xff1a;轮转数组方法1-使用额外的数组方法2-三次反转数组 题目&#xff1a;除自身以外数组的乘积方法1-用到了除法方法2-前后缀乘积法 题目&#xff1a;最大子数组和 原题链…

MICCAI 2024Centerline Boundary Dice Loss for Vascular Segmentation

MICCAI 2024 Centerline Boundary Dice Loss for Vascular Segmentation MICCAI 2024Centerline Boundary Dice Loss for Vascular Segmentation中心线边界Dice损失用于血管分割**摘要**:1. 引言相关工作&#xff1a; 2. 方法预备知识Dice的变化 3 实验3.1 数据集3.2 设置3.3 结…

虚拟机使用

1、安装 如何安装虚拟机&#xff1f;保姆级安装教程&#xff01; - 知乎 (zhihu.com) 2、使用 2.1 快照 作用&#xff1a;保留当前系统信息为快照&#xff0c;随时可以恢复&#xff0c;以防未来系统被你玩坏&#xff0c;就好比游戏中的归档&#xff01;每配置好一个就可以保…

C++ 类和对象 拷贝构造函数

一 拷贝构造函数的概念&#xff1a; 拷贝构造函数是一种特殊的构造函数&#xff0c;用于创建一个对象是另一个对象的副本。当需要用一个已存在的对象来初始化一个新对象时&#xff0c;或者将对象传递给函数或从函数返回对象时&#xff0c;会调用拷贝构造函数。 二 拷贝构造函…

【TB作品】51单片机 Proteus仿真00016 乒乓球游戏机

课题任务 本课题任务 (联机乒乓球游戏)如下图所示: 同步显示 oo 8个LED ooooo oo ooooo 8个LED 单片机 单片机 按键 主机 从机 按键 设计题目:两机联机乒乓球游戏 图1课题任务示意图 具体说明: 共有两个单片机,每个单片机接8个LED和1 个按键,两个单片机使用串口连接。 (2)单片机…

pygame 音乐粒子特效

代码 import pygame import numpy as np import pymunk from pymunk import Vec2d import random import librosa import pydub# 初始化pygame pygame.init()# 创建屏幕 screen pygame.display.set_mode((1920*2-10, 1080*2-10)) clock pygame.time.Clock()# 加载音乐文件 a…

CentOS 离线安装部署 MySQL 8详细教程

1、简介 MySQL是一个流行的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它基于SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;进行操作。MySQL最初由瑞典的MySQL AB公司开发&#xff0c;后来被Sun Microsystems公司…

若依前后端分离 前端路由登录页 如何进行跳转

路由守卫&#xff0c;看这篇文章 http://t.csdnimg.cn/HkypThttp://t.csdnimg.cn/HkypT

从nginx返回404来看http1.0和http1.1的区别

序言 什么样的人可以称之为有智慧的人呢&#xff1f;如果下一个定义&#xff0c;你会如何来定义&#xff1f; 所谓智慧&#xff0c;就是能区分自己能改变的部分&#xff0c;自己无法改变的部分&#xff0c;努力去做自己能改变的&#xff0c;而不要天天想着那些无法改变的东西&a…

【基础算法总结】分治—归并

分治—归并 1.排序数组2.交易逆序对的总数3.计算右侧小于当前元素的个数4.翻转对 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.排序数组 …

线性代数笔记

行列式 求高阶行列式 可以划上三角 上三角 余子式 范德蒙行列式 拉普拉斯公式 行列式行列对换值不变 矩阵 矩阵的运算 同型矩阵加减 对应位置相加减 矩阵的乘法 左边第 i 行 一次 相乘求和 右边 第 j 列 eg 中间相等 两边规模 矩阵的幂运算 解题思路 找规律 数学归纳…

青岛外贸建站公司wordpress网站模板

电子数码wordpress网站模板 电子数码wordpress网站模板&#xff0c;做数码电子的生产厂家或外贸公司官方网站模板。 https://www.jianzhanpress.com/?p3161 金属不锈钢wordpress外贸主题 适合从事金属不锈钢生产、加式或做外贸的公司&#xff0c;简洁wordpress外贸主题模板…