C++入门篇(1)之关键字,命名空间,输入输出和函数重载


typora-copy-images-to: upload


前言

历经3个月,博主逐渐更需完毕C语言的大部分知识,又耗费两个月左右,博主又更新完毕初阶的数据结构,终于到了今天,那就是我们期待已久的c++知识,此次文章是将会是c++的领头羊


介绍

由于C++就是在C的基础上发展而来,所以博主只会介绍C++中具有的知识,而C中没有的知识,因为最基础的分支,循环,函数等,c++和c是一模一样的.

C++关键字

在C语言中我们也学习过关键字,譬如int double typedef sizeof等等,而C++中同样也有关键字,读者会说,上面不是才说不会再提及C语言中也有的知识吗?为何C++还是提及呢?因为C++有C语言中没有的关键字.在C++中,关键字的数量达到了63个,而C语言中只有32个.多了几乎一倍,那么在C++中到底有哪些关键字呢?请看下表.

asmdoifreturntrycontinue
autodoubleinlineshorttypedeffor
booldynamic_castintsignedtypeidpublic
breakelselongsizeoftypenamethrow
caseenummutablestaticunionwchar_t
catchexplicitnamespacestatic_castunsigneddefault
charexportnewstructusingfriend
classexternoperatorswitchvirtualregister
constfalseprivatetemplatevoidtrue
const_castfloatprotectedthisvolatilewhile
deletegotoreinterpret_cast

表格中的内容只是让大家知道有这些东西,现阶段不会过多介绍,等到后面,博主会一一介绍.


命名空间

学习过C++的读者,可能会经常看到且并经常向下面一样code.

#include <iostream>
using namespace std;

但是读者们有没有想过using namespace std;是什么意思呢?又到底有何作用?下面博主将会详细介绍(命名空间)

命名空间来由

在学习c语言过程中,读者一定碰到过这种情况:

  • 在不同作用域,可以声明不同名字变量,函数等
  • 在不同作用域,也可以声明相同名字变量,函数等

但是,如果在相同作用于声明相同名字变量,函数等编译器将会报错,于是为了解决这种情况,C++提出了命名空间的概念.也许有人会说,为什么有这种需求呢?这是因为当大家在公司工作时候,一个工程的实现不是由一个人而是很多伙伴,每个人负责的板块不一样,而由于很多人的良好素养,比如要实现一个加法函数,大家可能都会想到起名为add,就会导致函数重名.所以有命名空间需求.


命名空间定义

命名空间的定义语法如下:

namespace 名字
{
    modules;
}

其中名字是我们自定义的命名空间名,modules是我们想要自定义的各种内容,比如变量,函数,宏,甚至嵌套命名空间.

下面我们会简单展示命名空间使用:

#include <cstdio>  //我们仍然用c语言输入输出,不要问为什么,博主下面会讲到,请耐心看下去哦~

namespace myself
{
    int rand = 100;
}
 int rand = 1000;

int main()
{
    printf("命名空间中的rand值:%d\n", myself::rand);   //myself::是命名空间的使用方法,类似于结构体访问成员
    printf("全局变量中的rand值:%d\n",rand);
    return 0;
}

结果显示如下:

image-20210926152114044

可以清楚的看到,我们使用了相同名字的rand,并且都在全局域,但是并没有影响.

命名空间可合并

命名空间是可以同名的,当有多个一样的命名空间时,编译器会自动将他们整合在一起.这也就暗示了一点—相同的命名空间中不可有相同的成员名,比如下面这样:

namespace my
{
    int rand = 0;
    int six = 6;
}

namespace my
{
    int rand = 0;
}

image-20210926154538416

注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中


命名空间的三种使用方法

第一种

使用using namespace 命名空间名称;展开到全局

我们知道,想要使用一个命名空间中的成员,就必须在前面加上命名空间名::,而人类的天性就是懒惰,所以肯定不想写前面那个,而这种使用方法就是解决此种困扰,当我们在全局中使用此语句,就可以在任何地方直接使用命名空间中的成员,如下:

#include <cstdio>

namespace my
{
    int rand = 0;
    int six = 6;
}
using namespace my;  //展开到全局 
int  main()
{
    printf("rand值为:%d\n",rand);
    printf("six值为:%d\n",six);
    return 0;
}
    

测试结果:

image-20210926155845900

优缺点:

  • 优点: 使用成员方便
  • 缺点:由于是展开到全局,如果全局也有相同名字变量或函数名等,会造成命名污染,编译器报错

第二种

加命名空间使用,如命名空间名::成员名. 这种就不介绍了,最开始就介绍了.

优缺点:

  • 优点:不会造成命名污染
  • 缺点:使用麻烦

第三种

我们可以发现,上面两种使用方法优缺点互逆,那么有没有一种方法可以折中一下呢?答案是:有!

对于使用比较频繁的成员,我们可以利用using 命名空间名::使用频繁成员名; 展开到全局,其他的使用第二种方法.

如下:

namespace N
{
    int a =  100;
    int b = 200;
}

using N::b;

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

C++输入&输出

c语言中使用scanf 和 printf进行输入输出,而C++也有输入输出,那就是cin 和 cout,其中cin是输入,搭配>>使用;cout是输出,搭配<<使用.

我们现在开始使用c++的输入输出:

#include <iostream>   //C++输入输出头文件
int  main()
{
    int n = 0;
    cin >> n;
    cout << n;
    return 0;
}

测试:

image-20210926162635459

嗯, 为什么会显示未定义的标识符呢?明明引入头文件了呀,其实这就是博主最开始讲解命名空间的原因,在C++中,C++标准库的的实现代码,是放到std命名空间中的.

所以我们可以通过std::cin 和 std::cout 或者using namespace std;(现在大家懂了这句话的意思吧)使用C++的输入输出语句

cin简单使用

cin可以不再像scanf那样该一个变量输入值需要取地址且按照相应的格式,比如%d,cin的输入格式为cin >> 变量名;

#include <iostream>
using namespace std;

int main()
{
	int n  =0;
    double f  =0;
    char s  =0;
    cin >> n;
    cin >> f;
    cin >> s;
}

测试:

image-20210926164631888

同时cin还支持连续输入,上面的n f s输入等价于cin >> n >> f >> s


cout简单使用

cout的使用不像c语言中的printf一样需要按照各种格式输出,而是直接按照格式cout << 变量名;

例:

#include <iostream>
using namespace std;

int main()
{
    int n = 100;
    double p = 123.123;
    
    cout<<n<<endl;  //endl是换行
    cout<<p<<endl;  
    
    printf("还可以混合使用,效果如下:\n");
    
    cout<< n << "  " << p << endl; 
    return 0;
}

测试结果:

image-20210926170514755


缺省参数

概念

缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该
默认值,否则使用指定的实参

void TestFunc(int a = 0)
{
	cout<<a<<endl;
}
int main()
{
	TestFunc(); // 没有传参时,使用参数的默认值,输出0
	TestFunc(10); // 传参时,使用指定的实参,输出10
}

全缺省参数

所有的参数都设置了一个默认值.

void TestFunc(int a = 10, int b = 20, int c = 30)
{
	cout<<"a = "<<a<<endl;
	cout<<"b = "<<b<<endl;
	cout<<"c = "<<c<<endl;
}

半缺省参数

从右到左挨个缺省,数量自由

void TestFunc(int a, int b = 10, int c = 20)
{
	cout<<"a = "<<a<<endl;
	cout<<"b = "<<b<<endl;
	cout<<"c = "<<c<<endl;
}

**注: **

  • 除了上面的两种默认形式外,其他形式的默认参数都会报错,原因是会造成歧义
  • 缺省参数不能在函数声明和定义中同时出现,原因一样,所以一般是在声明中写默认参数

函数重载

自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了。
比如:以前有一个笑话,国有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个是男足。前
者是“谁也赢不了!”,后者是“谁也赢不了!”

函数重载概念

函数的一种特殊情况,即在同一作用域下,定义了多个同名的函数,而每个函数的参数顺序,参数类型,参数数量都不同,而我们在调用该函数时,函数会根据参数情况进行选择相应的函数.

int Add(int left, int right)
{
	return left+right;
}

double Add(double left, double right)
{
	return left+right;
}

double Add(double left, long right)
{
	return left+right;
}

int main()
{
	cout << Add(10, 20) <<endl;//会自选择第一个函数
	cout << Add(10.0, 20.0)<<endl;//会选择第二个函数
	cout << Add(10.1, 20L) <<endl;//会选择第三个函数
	return 0;
}

测试:

image-20210926200743053

重载注意

请问下面两个例子算重载吗?

short Add(short left, short right)
{
	return left+right;
}
int Add(short left, short right)
{
	return left+right;
}

答:不算,重载条件只和参数有关,即 参数顺序,参数数量,参数类型


c为何没重载,c++为何有?怎么实现的?

在c语言章节,博主讲解过c程序在运行之前是怎么进行实现的(预处理过程).我们知道,在链接阶段,程序会把所有目标文件进行整合,最终形成.exe文件,而在整合过程中,会有一步符号表汇聚.

所以,如果在c语言中,有多个相同名字的函数,链接阶段将不知道我们所调用的函数到底是同名函数中的具体哪一个,进而导致编译器报错.

但是在c++中,形成符号表的时候,会对重名函数进行修饰,修饰原则是_Z n name t.其中n是函数名长度,name是函数名,t是所有参数类型的首字母缩写.

比如我们上面写的三个函数add重载函数,修饰后的名字分别是:_Z3Addii,_Z3Adddd_Z3Adddl,所以当我们写的参数类型不同时候,在C++中编译器可以顺利找到我们需要的函数.


更新完毕!

  • 50
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

捕获一只小肚皮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值