【C++】初识C++基础篇·一(命名空间,函数重载,缺省参数,引用);

文章目录

  • 前言
  • 1.输入与输出
    • 输出
    • 输入
      • cin和scanf的对比
  • 2.命名空间
  • 2.1namespace存在的意义
  • 2.2namespace的使用
  • 3.缺省参数
  • 4.函数重载
    • 重载函数的调用规则
  • 5.引用

在这里插入图片描述

前言

我们先通过一段简单的代码来拉开C++的序幕;

//text.cpp
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{printf("hello world");return 0;
}//int main()
//{
//	cout << "hello world" << endl;
//	return 0;
//}

在上述代码中,**printf(“hello world”);所实现的效果。与下面的cout << “hello world” << endl;**的效果相同,我们要知道在C++当中他是兼容C语言的语法的,所以代码中C语言的语法也能运行成功;
而在这里面就涉及到了我们下面要说的在C++中的输入与输出;

1.输入与输出

• < iostream > 是 Input Output Stream 的缩写,是标准的输⼊、输出流库,定义了标准的输⼊、输
出对象。
• std::cin 是 istream 类的对象,它主要⾯向窄字符(narrow characters (of type char))的标准输
⼊流。
• std::cout 是 ostream 类的对象,它主要⾯向窄字符的标准输出流。
• std::endl 是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区。
<<是流插⼊运算符,>>是流提取运算符。(C语⾔还⽤这两个运算符做位运算左移/右移)
• 使⽤C++输⼊输出更⽅便,不需要像printf/scanf输⼊输出时那样,需要⼿动指定格式, C++的输⼊输出可以⾃动识别变量类型其实最重要的是C++的流能更好的⽀持⾃定义类型对象的输⼊输出。
cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要通过命名空间的使⽤⽅式去⽤他们
• ⼀般⽇常练习中我们可以using namespace std,实际项⽬开发中不建议using namespace std。
• 这⾥我们没有包含<stdio.h>,也可以使⽤printf和scanf, 因为在 < iostream >中间接包含了。vs系列编译器是这样的,其他编译器可能会报错。

对于输入和输出两种操作来说,最重要的就是流插入运算符和流提取运算符;

输出

输出:cout << “hello world” << endl;
"<<"符号表示的是将该字符串传给cout(传的只是地址),该符号指出了信息流动的方向;而且它不单单可以只传输一段字符串,甚至是多段、不同类型的多次拼接传输。例如:

#include<iostream>
#include<stdio.h>
using namespace std;
//int main()
//{
//	printf("hello world");
//	return 0;
//}int main()
{cout << "hello world" << "  " << "123" << endl;return 0;
}

在这里插入图片描述
从结果中就可以验证我们上面所说的话;
而且在这里如果熟悉C语言的我们可以看出来流插入运算符,与我们C语言中的按位左移运算符相同,由于C++兼容C语言,区分就成了问题,所以就有了我们下面要讲的运算符重载

通过重载,同一个运算符将有不同的含义。编译器通过上下文来确定运算符的含义。C本身也有一些运算符重载的情况。例如,&符号既表示地址运算符,又表示按位AND运算符;*既表示乘法,又表示对指针解除引用。这里重要的不是这些运算符的具体功能,而是同一个符号可以有多种含义,而编译器可以根据上下文来确定其含义。C++扩展了运算符重载的概念,允许为用户定义的类型(类)重新定义运算符的含义。

输入

2.输入:cin >> a;

#include <iostream>int main() {int num;std::cout << "Enter an integer: ";std::cin >> num;std::cout << "The number you entered is " << num << std::endl;return 0;
}

这个示例中,我们使用 std::cin 来从键盘读取一个整数,并将该整数存储在变量 num 中。我们还使用 std::cout 向用户输出提示信息和最终的整数值。
cin 可以读取各种类型的输入值,包括整数、浮点数、字符和字符串。

cin和scanf的对比

cin 支持所有 C++ 内置类型的数据输入,包括 int, float, double 等。 它还支持用户定义的数据类型,例如类和结构。另一方面,scanf 函数只支持 C 语言的基本类型,如 int, char, float, double 等。它不支持 C++ 类和结构体。
错误处理:
cin 使用构造函数抛出异常来处理输入错误。当您尝试读取不合适的类型或不是具有所需范围的类型的值时,会抛出一个异常。这使得可以在程序的其他部分捕获该异常,并对用户做出适当的反应。另一方面,scanf 使用返回值来指示输入的成功与否,并且没有异常。
性能:

1.cin 的性能可能比 scanf 高,因为前者通常使用循环和条件语句来处理输入,而后者通过从输入流中查找特定的字符进行输入。因此,使用 cin 可以更高效地读取大量的输入数据。
可读性和便携性:
2.cin 的语法和功能比 scanf 更易于理解和编写。 cin 使用各种工具,例如流插入和流提取符,使读取和写入数据的操作更直观。此外,cin 在 C++ 标准中定义,因此可在所有的 C++ 编译器中使用。

2.命名空间

2.1namespace存在的意义

在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全局作⽤域中,可能会导致很多冲突。
使⽤命名空间的⽬的是对标识符的名称进⾏本地化,以避免命名冲突或名字污染,
namespace关键字的出现就是针对这种问题的。

namespace(命名空间)是一种用于组织代码中命名的机制。它提供了一种方法来避免命名冲突,并允许您创建多个具有相同名称的独立实体。
定义命名空间
可以使用以下语法来定义命名空间并指定其名称:

//text.cpp
namespace my_namespace {// 在这里定义命名空间的成员
}

我们通过一个C语言中错误的代码来理解:

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

而在C++中我们可以通过在命名空间中定义它来更好的解决;

2.2namespace的使用

• 定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中
即为命名空间的成员。命名空间中可以定义变量/函数/类型等。
• namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以下
⾯的rand不在冲突了。
• C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/
类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响
编译查找逻辑,还会影响变量的⽣命周期,命名空间域和类域不影响变量⽣命周期。

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

2.项⽬⼯程中多⽂件中定义的同名namespace会认为是⼀个namespace,不会冲突。
3.C++标准库都放在⼀个叫std(standard)的命名空间中。

在使用命名空间的成员时,我们需要使用名称空间的名称将其导入到当前范围。

#include<iostream>
using namespace std;
namespace study
{//变量int arr = 1;//函数int ADD(int left, int right){return left + right;}//结构体struct Node{struct Node* next;int val;};
}int main()
{cout << study::ADD(1, 2) << endl;return 0;
}

编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间⾥⾯去查找。所以
下⾯程序会编译报错。所以我们要使⽤命名空间中定义的变量/函数,有三种⽅式:

• 1.指定命名空间访问,项⽬中推荐这种⽅式。
• 2.using将命名空间中某个成员展开,项⽬中经常访问的不存在冲突的成员推荐这种⽅式。
• 3.展开命名空间中全部成员,项⽬不推荐,冲突⻛险很⼤,⽇常⼩练习程序为了⽅便推荐使⽤。

// 指定命名空间访问
int main()
{printf("%d\n", N::a);return 0;
}// using将命名空间中某个成员展开
using N::b;
int main()
{printf("%d\n", N::a);printf("%d\n", b);return 0;
}
//展开整个命名空间中的全部成员;
#include <iostream>namespace my_namespace {void some_function() {std::cout << "Hello from my_namespace!" << std::endl;}
}
using namespace my_namespace;
int main() {some_function();return 0;
}

这里还有一个问题,当我们有两个命名空间,它们都定义了一个名为 sayHello 的函数。

// 在命名空间 `test` 中定义 `sayHello` 函数
namespace test {void sayHello() {std::cout << "Hello from test!" << std::endl;}
}// 在命名空间 `test2` 中定义 `sayHello` 函数
namespace test2 {void sayHello() {std::cout << "Hello from test2!" << std::endl;}
}int main() {using namespace test;using namespace test2;sayHello();return 0;
}

在这个示例中,我们使用 using 语句导入了 test 命名空间中的 sayHello 函数和 test2 命名空间中的 sayHello 函数。当我们调用 sayHello 函数时,C++ 编译器并不知道是调用 test::sayHello 还是 test2::sayHello。 在运行期间与两个函数冲突。
为了避免这种情况,您可以在每个命名空间中导入只自己需要的成员,或者在使用命名空间成员时显式引用命名空间,以确保编译器知道调用哪个函数。例如,
在这里插入图片描述
这时的解决方法就是显式引用了每个命名空间中的 sayHello 函数,以确保编译器知道我们正在调用哪个函数:

#include <iostream>namespace test {void sayHello() {std::cout << "Hello from test!" << std::endl;}
}namespace test2 {void sayHello() {std::cout << "Hello from test2!" << std::endl;}
}int main() {test::sayHello();test2::sayHello();return 0;
}

3.缺省参数

• 缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调⽤该函数时,如果没有指定实参
则采⽤该形参的缺省值,否则使⽤指定的实参,缺省参数分为全缺省和半缺省参数。(有些地⽅把
缺省参数也叫默认参数)
• 全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左
依次连续缺省,不能间隔跳跃给缺省值。
• 带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参。
• 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。

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

在这里插入图片描述

4.函数重载

C++支持在同一作用域中定义多个同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者类型不同。这样C++函数调⽤就表现出了多态⾏为,使⽤更灵活。C语⾔是不⽀持同⼀作⽤域中出现同名函数的。

#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;
}
// 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;
}
// 返回值不同不能作为重载条件,因为调⽤时也⽆法区分
//void fxx()
//{}
//
//int fxx()
//{
// return 0;
//}
// 下⾯两个函数构成重载
// f()但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁
void f1()
{cout << "f()" << endl;
}
void f1(int a = 10)
{cout << "f(int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}

在这里插入图片描述

重载函数的调用规则

1.参数数量(或参数的顺序)应与函数定义匹配。
2.参数类型应与函数定义中参数类型匹配(考虑到 C++ 的类型转换基本原则)。如果函数定义中提供有默认的参数值,则重载函数调用时可以省略该描述符所引用的参数。

#include <iostream>// 无参数的原型
void sideFunction() {std::cout << "Call with no parameters" << std::endl;
}// 双参数原型,整型和双精度型参数
void sideFunction(int num, double num2) {std::cout << "Call with int and double arguments: " << num << " " << num2 << std::endl;
}int main() {sideFunction();           // 调用无参数版本的 sideFunction()sideFunction(10, 3.14);   // 调用 int 和 double 参数版本的 sideFunction()return 0;
}

5.引用

引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名,编译器不会为引⽤变量开辟内存空间,
它和它引⽤的变量共⽤同⼀块内存空间。
形式表现为:类型& 引用别名 = 引用对象;
并且它可以有多个引用别名;

int& a = b;
int& c = a;
此时a是b的引用别名;(**不要把引用符号“&”和取地址符号混淆**)
对别名a取别名c,c相当于还是a的别名;

它是与变量相关联的指针,但与其他指针不同,引用必须初始化指向某个已存在的对象,并且在整个其生命周期中都必须指向那个对象。引用就像指针一样,但是它们的一些优点是:

1.引用不像指针那样需要显式解引用操作。引用允许直接访问其引用的值,而不需要使用""运算符。
2.由于引用必须在初始化时被绑定到某个对象,因此不会出现悬空引用问题。
3.由于引用初始化不能更改,因此避免了错误的引用传递问题,即在函数调用传递引用时未提供有效的引用

引用必须在定义的同时初始化,并且在之后的程序里不能改变引用的指向;
对于这句话的理解,我们看下面一段代码;

#include<iostream>
using namespace std;
int main()
{int a = 10;// 编译报错:“ra”: 必须初始化引⽤//int& ra;int& b = a;int c = 20;// 这⾥并⾮让b引⽤c,因为C++引⽤不能改变指向,// 这⾥是⼀个赋值b = c;cout << &a << endl;cout << &b << endl;cout << &c << endl;return 0;
}

这里面的b = c并非改变了引用指向,而是赋值,因为如果是改变了引用指向,根据我们上面给出的定理,引用别名和变量共用一块地址,所以我们只需要看它们的地址是否相同就能够判断出;
在这里插入图片描述
从地址中我们可以看出b 和 c 的地址并不相同,所以b = c只是赋值;

而下面这段代码中的形式,才是改变了引用指向;

#include <iostream>
using namespace std;int main() {int a = 99, b = 32;int &r = a;a = 67;cout << a << ", " << r << endl; //67,67&r=b;//不能重新引用其他数据b = 88;cout << b << ", " << r << endl;return 0;
}

结果会报错为表达式必须为可修改的左值;在这里插入图片描述
最后对于引用中另外的关键知识点和问题,后面我会再写一篇文章专门讲解
在这里插入图片描述

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

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

相关文章

链路聚合加单臂路由

一、实验目的及拓扑 实验目的&#xff1a;在路由器及交换机之间建立链接聚合&#xff0c;交换机接入两台主机并通过路由器子接口自动分配IP地址&#xff0c;通过单臂路由实现两台主机互联 二、基本配置 1、交换机配置 [S1]vlan batch 10 20 [S1-Eth-Trunk1]dis th # interf…

matlab simulink 混合式VTOL-UAV动力学模型

1、内容简介 略 可以交流、咨询、答疑 2、内容说明 略混合式VTOL UAV是简单的将四旋翼和固定翼无人机结合在一起,不仅具备四旋翼飞行器的垂直起降,可悬停的特点,还具备固定翼飞行器的航程远,平飞速度快等特点,具有很重要的应用价值,在该飞行器布局中,四旋翼负责提供升力,工作…

《昇思25天学习打卡营第6天|ResNet50图像分类》

写在前面 从本次开始&#xff0c;接触一些上层应用。 本次通过经典的模型&#xff0c;开始本次任务。这里开始学习resnet50网络模型&#xff0c;应该也会有resnet18&#xff0c;估计18的模型速度会更快一些。 resnet 通过对论文的结论进行展示&#xff0c;说明了模型的功能&…

Ubuntu 22.04如何设置中文输入法

前言 近期整理了一下之前在ubuntu 22.04 中如何设置中文输入法的过程&#xff0c;对于本人比较适应读中文写中文来说&#xff0c;这是我安装后的第一步。 一、流程 1.1 安装中文语言包&#xff08;如果还未安装&#xff09; 首先是安装中文语言包&#xff0c;直接在终端输入…

全能Ai助手:写作到设计,宝藏神器帮你事半功倍

今天&#xff0c;就让我们一起踏上这场寻找“隐藏”宝藏的旅程&#xff0c;探索这些AI工具如何改变我们的生活&#xff01; 一、高效生产力的提升之道 1. 文案创作助手 案例&#xff1a;某位自媒体博主使用了一款智能写作工具&#xff0c;不仅大大节省了写作时间&#xff0c;…

数据库(MySQL)-视图、存储过程、触发器

一、视图 视图的定义、作用 视图是从一个或者几个基本表&#xff08;或视图&#xff09;导出的表。它与基本表不同&#xff0c;是一个虚表。但是视图只能用来查看表&#xff0c;不能做增删改查。 视图的作用&#xff1a;①简化查询 ②重写格式化数据 ③频繁访问数据库 ④过…

【React学习打卡第四天】

ReactRouter 一、概念二、创建路由开发环境三、快速开始四、抽象路由模块实际开发中的router配置 五、路由导航1.声明式导航2.编程式导航 六、路由导航传参1.searchParams 传参2.params 传参 七、嵌套路由配置八、默认二级路由九、404路由配置十、俩种路由模式 一、概念 一个路…

使用Python爬虫采集亚马逊新品榜商品数据

一、引言 1.1 亚马逊新品榜的重要性 亚马逊是全球最大的电商平台之一&#xff0c;亚马逊新品榜展示了最新上架并受欢迎的产品。对于电商卖家和市场分析师来说&#xff0c;了解这些新品榜单可以帮助他们捕捉市场趋势&#xff0c;了解消费者喜好&#xff0c;从而优化产品策略和营…

视频怎么加密?常见的四种视频加密方法和软件

视频加密是一种重要的技术手段&#xff0c;用于保护视频内容不被未经授权的用户获取、复制、修改或传播。在加密过程中&#xff0c;安企神软件作为一种专业的加密工具&#xff0c;可以发挥重要作用。 以下将详细介绍如何使用安企神软件对视频进行加密&#xff0c;并探讨视频加密…

block_size设置过大错误分析(查看CUDA设备线程块大小)

block_size设置过大错误分析&#xff08;查看CUDA设备线程块大小&#xff09; 1 问题描述2 问题分析3 解决方法4 调试和验证5 查看设备线程块大小 1 问题描述 本人作为CUDA编程初学者&#xff0c;在学习编写使用CUDA计算矩阵相乘代码时发现&#xff0c;如果我的 block_size &g…

可能是最好的工具网站

前些苏音在刷视频&#xff0c;发现了一堆好用的宝藏网站&#xff0c;这就赶快分享给大家。 工具网站 这个网站类似于网址导航&#xff0c;集合了包括工具类、资源类、软件类、AI类的合集 并且站长表示励志做体验感最好的工具网&#xff0c;聚焦最快解决用户的需求 首先就是办…

数据库安全综合治理方案(可编辑54页PPT)

引言&#xff1a;数据库安全综合治理方案是一个系统性的工作&#xff0c;需要从多个方面入手&#xff0c;综合运用各种技术和管理手段&#xff0c;确保数据库系统的安全稳定运行。 方案介绍&#xff1a; 数据库安全综合治理方案是一个综合性的策略&#xff0c;旨在确保数据库系…

【8月EI会议推荐】第四届区块链技术与信息安全国际会议

一、会议信息 大会官网&#xff1a;http://www.bctis.nhttp://www.icbdsme.org/ 官方邮箱&#xff1a;icbctis126.com 组委会联系人&#xff1a;杨老师 19911536763 支持单位&#xff1a;中原工学院、西安工程大学、齐鲁工业大学&#xff08;山东省科学院&#xff09;、澳门…

一天搞定React(3)——Hoots组件【已完结】

Hello&#xff01;大家好&#xff0c;今天带来的是React前端JS库的学习&#xff0c;课程来自黑马的往期课程&#xff0c;具体连接地址我也没有找到&#xff0c;大家可以广搜巡查一下&#xff0c;但是总体来说&#xff0c;这套课程教学质量非常高&#xff0c;每个知识点都有一个…

数据结构经典测试题4

1. #include <stdio.h> int main() { char *str[3] {"stra", "strb", "strc"}; char *p str[0]; int i 0; while(i < 3) { printf("%s ",p); i; } return 0; }上述代码运行结果是什么&#xff1f; A: stra strb strc B: s…

Rocky/Centos Linux安装Code-server,并注册成服务自启动

文章目录 Rocky/Centos Linux安装Code-server&#xff0c;并注册成服务自启动介绍安装1. 下载压缩包2. 解压缩3. 执行启动命令4. 浏览器访问5. 开机自启动 Rocky/Centos Linux安装Code-server&#xff0c;并注册成服务自启动 介绍 VS Code Server是微软推出的VSCode风格的Web…

谷歌AI拿下IMO奥数银牌!6道题轻松解出4道~

本周四&#xff0c;谷歌DeepMind团队宣布了一项令人瞩目的成就&#xff1a;&#xff1a;用 AI 做出了今年国际数学奥林匹克竞赛 IMO 的真题&#xff0c;并且距拿金牌仅一步之遥。这一成绩不仅标志着人工智能在数学推理领域的重大突破&#xff0c;也引发了全球范围内的广泛关注和…

私域电商丨软件系统开发中,一定要避开的几个坑,看懂少很多弯路

文丨微三云胡佳东&#xff0c;点击上方“关注”&#xff0c;为你分享市场商业模式电商干货。 - 大家好&#xff0c;我是软件开发胡佳东&#xff0c;每天为大家分享互联网资讯干货&#xff01; 在数字化时代的今天&#xff0c;软件开发是已经成为推动科技进步和商业发展的重要…

vmware虚拟机安装linux没有IP地址

直接设置固定IP 1、在虚拟机菜单栏选择编辑&#xff0c;然后点击虚拟网络编辑器 2、选择Vmnet8 Net网络连接方式&#xff0c;随意设置子网IP 3、点击NAT设置页面&#xff0c;查看子网掩码和网关&#xff0c;修改静态IP会用到 4、打开电脑控制面板–网络和Internet–网络连…