在学习C++前,我们首先需要了解一些C++独有的特性,方便我们后续的学习。
上篇会介绍:命名空间namespace、C++的输入和输出、缺省参数
一、命名空间
我们来看下面一段代码:
#include<stdio.h>
#include<stdlib.h>
int rand = 0;
//命名空间
//命名冲突
int main()
{
printf("%d\n", rand);
return 0;
}
我们编译时,就会提示这样的错误:"rand" : 重定义; 以前的定义是“函数”
这是因为我们包含了头文件 <stdlib> ,在这个头文件中,有名字为 rand 的函数,而我们又定义了一个名为rand的变量,最后导致了冲突,这样的问题在C语言中无法解决。
在未来的使用中,我们经常会遇到类似的情况 : 变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
1.1 命名空间的定义
接下来我们来看如何使用namespace关键字(定义类似于结构体):
1.1.1 正常的命名空间定义
namespace Zhangj
{
// 命名空间中可以定义变量/函数/结构体
int a = 0;
int b = 1;
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
1.1.2 命名空间的嵌套
命名空间同时支持嵌套使用:
namespace Zhangj_1
{
int rand = 0;
int a = 0;
int add(int a, int b)
{
return a + b;
}
//命名空间的嵌套
namespace ZhangJ_2
{
int rand = 0;
int a = 0;
}
}
1.1.3 同名的命名空间处理
同一个工程中允许同名的命名空间的存在,最后会合成在同一个命名空间中:
namespace ZhangJ
{
int a = 0;
}
namespace ZhangJ
{
int b = 0;
}
//上面的代码可以同时存在
//编译器最后会处理,效果等同于
//namespace ZhangJ
//{
// int a = 0;
// int b = 0;
//}
1.2命名空间的使用
一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中
所以我们在使用其中的内容时,需要指定这个内容是来自哪一个命名空间
我们定义下面这样的命名空间:
namespace ZhangJ
{
int a = 0;
int b = 0;
int Add(int left, int right)
{
return left + right;
}
struct Node
{
struct Node* next;
int val;
};
}
int main()
{
printf("%d\n", a);//error:“a”:未定义的标识符
return 0;
}
这样的 变量a 是无法使用的,如果我们不指定他的命名空间,编译器是不会去命名空间里去找的
下面是三种命名空间的使用方式:
需要注意的是,第二种和第三种方式都会存在风险,适用于我们佩服使用的变量/函数/结构体,通常我们会选择第一种方式。
//第一种:加命名空间名称及作用域限定符
int main()
{
printf("%d\n", ZhangJ::a);
return 0;
}
//第二种:使用using将命名空间中某个成员引入
using ZhangJ::a;
int main()
{
printf("%d\n", a);
return 0;
}
//第三种:使用using namespace 命名空间名称引入
using namespace ZhangJ;
int main()
{
printf("%d\n", a);
return 0;
}
二、C++的输入和输出
学习一门语言首先就是 “ hello world !”
我们来看看C++是怎么向世界问好的:
#include<iostream>
using namespace std;
//为了演示简洁,使用了直接展开命名空间的方式
int main()
{
cout << "hello world !" << endl;
return 0;
}
再来看看其他的输入和输出:
#include<iostream>
using namespace std;
int main()
{
int a = 0;
double b = 0;
//输入 相当于scanf
cin >> a;
cin >> b;
//输出 相当于pritnf
cout << a << endl;
cout << b << endl;
return 0;
}
说明:
1. C++中,输入cin和输出cout以及endl换行符都包含在头文件<iostream>中,所以使用时必须包含这个头文件。
2. 同时cin、cout、endl都被放在了名为std的命名空间中,使用时需要注意展开。
3. << 是流插入运算符 , >> 是流提取运算符
4. C++的输入和输出更方便,观察上面的代码可以发现,在输入和输出时,cin和cout不用像 scanf 和 printf 一样指定类型,C++的输入输出可以自动识别变量类型。
注意:using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用std::cout这样指定命名空间 + using std::cout展开常用的库对象/类型等方式
三、缺省参数
让我们来看看C++另一个大有用处的新玩意:缺省参数
3.1缺省函数的概念
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实 参则采用该形参的缺省值,否则使用指定的实参。
void Show(int a = 10)//给参数一个缺省值 10
{
cout << a << endl;
}
int main()
{
Show();//如果不传值,则会使用缺省值
Show(100);//传了值,那么就会使用指定的实参
return 0;
}
3.2缺省函数的分类
3.2.1 全缺省
void show(int a = 1, int b = 2, int c = 3)
{
cout << a <<":" << b <<":" << c << endl;
}
3.2.2半缺省
//以下两个都是半缺省
void show(int a = 1, int b = 2, int c = 3);
void show(int a, int b=2, int c = 3);
注意:
1.半缺省时:缺省值只能从右向左给出,不能间隔着给
2.调用时:不能间隔给值,只能从左向右给
int main()
{
show();
show(10);
show(10,20);
show(20,30);
show(10, 20, 30);
return 0;
}
输出的结果:
3.3.3 缺省参数声明和定义
C++中,缺省参数不能再声明和定义中同时给出,防止不同而导致不确定使用哪一个缺省值。
我们需要在声明中给出缺省值,定义中不给。
//.h中
#include<iostream>
using namespace std;
void show(int a = 1, int b = 2, int c = 3);
//.cpp中
void show(int a, int b, int c)
{
cout << a <<":" << b <<":" << c << endl;
}
如果两边都有缺省参数就会报错:
下集再见~~
你的点赞和关注是作者前进的动力!
最后,作者主页有许多有趣的知识,欢迎大家关注作者,作者会持续更新有意思的代码,在有趣的玩意儿中成长!