C++入门前菜

本文介绍了C++中的命名空间,包括其定义与使用,如何解决命名冲突问题。接着讲解了C++的输入输出机制,使用cout和cin进行屏幕输出和键盘输入。此外,还探讨了函数的缺省参数和函数重载的概念,以及在实际编程中如何应用。

🐧1.命名空间

💥在C++中,我们可能都会看到这样一段代码:

#include<iostream>
using namespace std;
int main()
{
	cout<<"hello word"<<endl; //cout是C++中用来打印输出的类,这里先不介绍,明白意思即可
	return 0;
}
using namespace std;

这一句是什么意思呢,又在上述代码中充当了什么作用?
那么这里,我们就要了解命名空间这个概念了. 我们先来看一段C语言的代码

#include<stdio.h>
#include<string.h>

int strlen = 0;
int main()
{
	printf("%d", strlen);
	return 0;
}

上述代码中定义了一个名为strlen的变量,并在屏幕上打印,当我们将这段代码去运行时,会发现它就会报错,在C语言中,我们都了解过,变量名不能够与C语言中关键字的名字冲突.但是,如果我们想要定义一个名为strlen的变量该怎么办呢?

在C++中,为了解决这个问题,就引入了命名空间这一概念.

1.1命名空间的定义

1.要定义一个命名空间,需要用到namespace关键字,后面跟上命名空间的名字,然后接上一对花括号{ }即可,{ }即为命名空间的成员.

#include<iostream>
#include<cstring>
namespace A  //A为命名空间的名称
{
    //命名空间的内容,既可以定义变量,也可以定义函数
	int strlen = 0;
}
int main()
{
	printf("%d\n", strlen);
	return 0;
}

因为C++是兼容C的,所以C语言中的输入输出函数printf在C++中也是可以使用的,此时当我们再次在编译器上运行这段代码时,会发现
在这里插入图片描述
我们会发现,此时它就不再报错,而是在屏幕上打印出一串数字,这串数字就是strlen函数的地址.
此时就不再有错误,是因为当我们在命名空间中去定义变量时,这个命名空间就给变量限定的一个作用域即将它与strlen函数的名字分离开来,这样就避免了命名冲突.

2.除了这样单独定义一个命名空间之外,命名空间还支持嵌套定义:

namespace A
{
	int a = 0; //定义变量
	
	int Add(int x, int y) //定义函数
	{
		return x + y;
	}
	
    struct Node //定义类型
    {
    	int val;
    	struct Node* next;
    };
	namespace B //B嵌套在A中
	{
		int b = 0;
		int Sub(int x, int y)
		{
			return x - y;
		}
		
	}
}

3.在同一工程中如果存在多个同名的命名空间,编译器最终会将它们合并成一个命名空间.

namespace A
{
	int a = 0;
	void Print()
	{
		cout<<"C++ is prefect"<<endl;
	}
}

namespace A
{
	int b = 0;
}

这两个命名空间最终会被合并成一个

1.2命名空间的使用

1.在上面的代码中,我们定义了一个命名空间A,那么我们怎样去使用它里面的内容呢?例如

#include<iostream>

namespace B
{
    //定义变量
	int a = 0;
	int b = 1;
	定义函数
	int Add(int x, int y)
	{
		return x + y;
	}
}
int main()
{
	printf("%d\n", B::a);
    printf("%d\n", B::b);
    printf("%d\n", B::Add(10, 20));
    
	return 0;
}

在这里插入图片描述
可以看到,屏幕上打印出了我们想要的结果,也就是说,当我们想使用命名空间中定义的变量或函数时,在前面加上命名空间的名字 + :: 作用域运算符即可.

我们在文章开头中提出了using namespace std;是什么作用,通过namespace其实就大概可以猜到,这是声明命名空间的,这也是命名空间的一种使用方法:

#include<iostream>

namespace B
{
    //定义变量
	int a = 0;
	int b = 1;
	定义函数
	int Add(int x, int y)
	{
		return x + y;
	}
}
int main()
{
	printf("%d\n", B::a);
    printf("%d\n", B::b);
    printf("%d\n", B::Add(10, 20));
    
	return 0;
}

2.在这里,我们使用命名空间是通过命名空间名称+作用域运算符使用的,对于使用命名空间,C++中还可以使用using namespace + 命名空间名称来引入命名空间,可以看作是将命名空间在全局中展开.

using namespace std;就是把C++库中名为std的命名空间展开,这样就可以使用C++库中的一些类类型.

#include<iostream>
using namespace std;
int main()
{
	cout<<"C++"<<endl; //cout和endl都是C++库中定义的类,这里我们不详细说
	
	return 0;
}

这段代码的作用就是在屏幕上输出C++,当我们去掉那句using namespace std;时,此时程序就会出错,就是因为coutendl被定义在std这个命名空间中,如果我们不展开这个命名空间,也就无法使用其中定义的内容.
那么我们就得到了命名空间的第二个使用方法:使用using namespace + 命名空间名;来将这个命名空间展开.

但这种使用方法还是有一些缺陷:

#include<iostream>
using namespace std;

int cout = 0; //cout是C++的一个内置类类型,用于打印输出
int main()
{
	cout<<cout<<endl;
	return 0;
}

当我们去编译这段代码时
在这里插入图片描述
我们会看到这样的错误,cout不明确,也就是说,当我们把std这个命名空间展开时,它又会与我们自己命名的cout这个全局变量发生冲突,那这样命名空间岂不是没有作用了吗?

所以在实际用C++时,我们不会将这个命名空间一次性都展开,这样会带来命名冲突的问题.那我们难道必须每次在使用时,用命名空间+::指定它的命名空间吗?

3.其实是不需要的,C++中还提供了第三种方法使用命名空间:只将常用的名称展开

#include<iostream>

using std::cout;
using std::endl;
int main()
{
	cout<<"学习C++"<<endl;
	return 0;
}

也就是只将我们平时一些比较常用的类名展开,其他未展开的名称依然需要指定命名空间.
这种方法比较合理,既不用每次都指定命名空间,也可以避免发生命名冲突.

🐋2.C++输入输出

在C语言中,我们使用printf函数来在屏幕上打印输出结果,那在C++中,我们用什么去实现输入输出功能呢?

其实上面已经见过了,那就是coutcin,来看一段代码:

#include<iostream>
using namespace std; //在这里为了方便,就将命名空间全部展开

int main()
{
	cout<<"hello world"<<endl; //endl作用是换行
	return 0;
}

这样,C++版本的hello world就实现了.
同时,既然有输出,也一定有输入:

#include<iostream>
using namespace std;

int main()
{
	int a = 0;
	int c;
	char c = 0;
	
	cin>>a>>c; //从键盘上读取数据输入到a变量中,支持连续输入
	cout<<a<<" "<<c; //输出a变量的值,支持连续输出
	cout<<c<<endl;
	
	return 0;
}

此时,可能会有一个疑问,为什么C++没有像C语言那样在输入输出时需要指定数据的类型和格式,这就是C++方便之处,输入输出时不需要指定数据类型,不需要增加数据格式控制,如%d%c.

使用cout标准输出和cin标准输入时,必须包含<iostream>头文件,以及std标准命名空间.

注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件
即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文
不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用
<iostream>+std的方式。

🦢3.缺省参数

3.1缺省参数概念

缺省参数概念:缺省参数是指在函数的声明或定义时为函数的参数提供一个默认值,在调用该函数时,如果没有传入实参,就用这个默认的参数.

void Test(int a = 10)
{
	cout<<a<<endl;
}

int main()
{
	Test(); //如果没有传参数,就用默认的a = 10
	Test(20); //如果手动传参,就用传入的这个参数
	return 0;
}

3.2 缺省参数的分类:

  • 全缺省参数
void Test(int a = 10, int b = 20, int c = 30)
{
	cout<<"a = "<<a<<endl;
	cout<<"b = "<<b<<endl;
	cout<<"c = "<<c<<endl;
}
  • 半缺省参数
void Test(int a, int b = 20, int c = 30)
{
	cout<<"a = "<<a<<endl;
	cout<<"b = "<<b<<endl;
	cout<<"c = "<<c<<endl;
}

注意:1.缺省参数只能从右向左给,不能从左向右,上面全缺省参数的那个例子就是正确用法.

2.缺省参数不能在声明和定义中同时出现,如果同时出现且恰巧两个位置的值不同,那编译器就分不清到底用哪个了

void func(int a = 10);

void func(int a = 20)
{}

3.缺省值必须是常量或者全局变量

4.C语言不支持(编译器不支持)

🦉4.函数重载

1.函数重载概念:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数(参数个数类型顺序)必须不同,常用来处理实现功能类似数据类型不同的问题.

2.例如,在C语言中我们想实现加法函数来对不同的数据类型进行相加,我们必须定义三个加法函数来实现此操作:

int add(int x, int y)
{
	return x + y;
}

float addFloat(float x, float y)
{
	return x + y;
}

double addDouble(double x, double y)
{
	return x + y;
}

但是会发现,如果这样,我们实现一个加法功能,就必须给这个函数起三个不同的名称,很麻烦.
所以C++中提供了函数重载的语法来避免这样的问题:

int add(int x, int y)
{
	return x + y;
}

float add(float x, float y)
{
	return x + y;
}

double add(double x, double y)
{
	return x + y;
}

即我们可以在同一作用域下定义三个参数不同(个数,类型,顺序),功能类似,且同名的函数来实现对三个不同数据类型的加法,这样避免了起名的麻烦,还可以让名字更统一,因为它们所实现的功能都是相同的.

在这里要注意一点: 函数重载中的参数顺序不同指的是参数类型顺序的不同

int add(int x, int y)
{
	return x + y;
}

int add(int y, int x)
{
	return x + y;
}

例如这段代码,它把类型相同的参数x和y的顺序颠倒,这样是不能够重载的!!
而正确的应该是这样:

int add(int x, float y)
{
	return x + y;
}

int add(float y, int x)
{
	return x + y;
}

即参数类型的顺序不同.
最后还有一点: C语言是不支持函数重载的,那么C语言为什么不支持函数重载呢?下篇文章中会详细给大家讲解,如果觉得这篇文章对你有帮助的话,别忘了点个赞哈🌞🌞🌞🌞🌞

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沉默.@

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

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

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

打赏作者

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

抵扣说明:

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

余额充值