文章目录
前言
本文总结学习C++小白篇—01基础_1。
一、命名空间
1.1 产生背景
-
在C语言中,一般会发生命名冲突的地方有:
-
创建的变量名与库函数命名冲突
-
创建的变量名和同一个项目中其他成员创建的变量名冲突
C语言没有解决此问题,因此在C++升级补充
- 在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
1.2 定义
- 定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员
1.2.1 举例:
冲突代码:
#include <stdio.h>
#include <stdlib.h>// 该头文件展开会包含一个rand函数
int rand = 0;// 重复定义rand,发生命名冲突
int main()
{
printf("%d\n", rand);
return 0;
}
修改后:
#include <stdio.h>
#include <stdlib.h>
namespace gsy // 定义命名空间,对定义的rand全局变量名称进行本地化
{
int rand = 0;
}
int main()
{
printf("%d\n", rand);
return 0;
}
注:这里为什么打印的不是0呢?
因为我们将头文件#include <stdlib.h>包含后,展开产生一个名为rand的函数。因为我们的全局变量是放在命名空间内的,所以直接以%d打印rand,其实是打印函数名,相当打印函数地址,以%d打印的结果即为地址的十进制数。
那么我们如何才能将全局变量rand打印呢?(域作用限定符::)
#include <stdio.h>
#include <stdlib.h>
namespace gsy
{
int rand = 0;
}
int main()
{
printf("%d\n", gsy::rand);// 打印gsy命名空间中的rand
return 0;
}
补充:
#include <stdio.h>
#include <stdlib.h>
namespace gsy
{
int rand = 0;
}
int main()
{
printf("%d\n", ::rand);// 左边空白,没有任何字符,默认指定全局变量/函数名
return 0;
}
1.3 注意事项
1.3.1 命名空间的内容
- 命名空间中的内容,既可以定义变量,也可以定义函数,还可以定义类型
namespace gsy
{
// 定义变量
int rand = 0;
// 定义函数
void fun()
{
printf("hello\n");
}
// 定义类型
struct stu
{
char name[5];
char sex;
int num[10];
};
}
1.3.2 命名空间的嵌套
- 命名空间可以嵌套,调用嵌套命名空间中的变量/函数/类型也应嵌套调用
namespace gsy
{
// 定义变量
int rand = 0;
// 定义函数
void fun()
{
printf("hello\n");
}
// 定义类型
struct stu
{
char name[5];
char sex;
int num[10];
};
// 嵌套命名空间
namespace gsy2
{
int num = 123;
}
}
int main()
{
printf("%d\n", gsy::gsy2::num);//嵌套命名空间中变量的调用
return 0;
}
1.3.3 同名命名空间
- 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中
left.h头文件
#include <stdio.h>
// 同名命名空间
namespace gsy
{
int a = 0;
// 嵌套命名空间
namespace left
{
// 同名变量
int num = 111;
}
}
right.h头文件
#include <stdio.h>
// 同名命名空间
namespace gsy
{
int b = 0;
// 嵌套命名空间
namespace right
{
// 同名变量
int num = 999;
}
}
test.c测试源文件
#include "left.h"
#include "right.h"
int main()
{
// 同名命名空间合并
printf("%d\n", gsy::left::num);
printf("%d\n", gsy::right::num);
return 0;
}
1.3.4 命名空间对成员的影响
- 命名空间不影响成员的生命周期,隔离的是命名冲突,本质如果成员为变量,他仍然为一个全局变量(会分配空间)
1.3.5 命名空间放置位置
- 命名空间只能放在全局,一般放在头文件位置
1.4 命名空间的引入
- 相当将这个命名空间定义的成员放出来,恢复全局
1.4.1 命名空间使用方式
- 加命名空间名称及作用域限定符
#include "left.h"
#include "right.h"
int main()
{
printf("%d\n", gsy::left::num);
printf("%d\n", gsy::right::num);
return 0;
}
- 使用using namespace 命名空间名称引入(最佳方式 ,需要用什么成员,就引入什么成员。
因为->
全引入:可能部分成员冲突;
不引入:调用复杂,每次都需要用作用域限定符)
#include "left.h"
#include "right.h"
using namespace gsy;
int main()
{
printf("%d\n", left::num);
printf("%d\n", right::num);
return 0;
}
- 使用using将命名空间中成员(不包括嵌套命名空间)引入
#include "left.h"
#include "right.h"
using gsy::left::num;
int main()
{
printf("%d\n", num);
printf("%d\n", gsy::right::num);
return 0;
}
#include "left.h"
#include "right.h"
using gsy::a;
int main()
{
printf("%d\n", a);
printf("%d\n", gsy::right::num);
return 0;
}
1.4.2 C++常见using namespace std的原理
#include <iostream>
using namespace std;
int main()
{
cout << "hello" << endl;
return 0;
}
这里的using namespace std;是为了封C++库的命名空间(方便使用)
如果不加此代码,上述代码必须写为:
#include <iostream>
//using namespace std;
int main()
{
std::cout << "hello" << std::endl;
return 0;
}
二、C++的输入输出
2.1 如何say“hello world”
#include <iostream>
using namespace std;
int main()
{
cout << "hello world" << endl;
return 0;
}
2.2 与C语言输入输出的异同
- 使用cout标准输出(控制台)和cin标准输入(键盘)时,必须包含< iostream >头文件以及std标准命名空间
说明:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文
件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用< iostream > + std的方式。
- 使用C++输入输出更方便,不需增加数据格式控制,比如:浮点型–%lf,整形–%d,字符–%c等等
- 使用C++输入输出,一行可多个输入输出
#include <iostream>
using namespace std;
int main()
{
int a = 0;
double b = 0.0;
cin >> a >> b;
cout << a << "+" << b << endl;
return 0;
}
- C++可兼并C语言的输入输出,二者可以混着用
#include <iostream>
using namespace std;
int main()
{
int a = 0;
double b = 0.0;
cin >> a >> b;
cout << a << "+" << b << endl;
cout << a << "+" << b << "\n";// 与上等价
printf("%d+%lf\n", a, b);
return 0;
}
三、缺省参数(默认参数)
3.1 定义
- 缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参
3.2 分类及使用
3.2.1 全缺省参数
#include <iostream>
using namespace std;
void fun(int a = 1, int b = 2)
{
cout << a << "+" << b << endl;
}
int main()
{
fun();// 不指定实参值,两个参数分别使用缺省参数a,b
fun(99);// 指定第一个实参为99,第二个参数默认使用缺省参数b
fun(99, 100);// 指定第一个实参为99,第二个实参为100
return 0;
}
注意:
fun(, 100)是错误的,必须想传第一个参数,再传第二个参数
3.2.2 半缺省参数
#include <iostream>
using namespace std;
void fun(int a, int b = 2)
{
cout << a << "+" << b << endl;
}
int main()
{
fun(99);// 指定第一个实参为99,第二个参数默认使用缺省参数b
fun(99, 100);// 指定第一个实参为99,第二个实参为100
return 0;
}
注意:
- 函数参数必须从右往左缺省,并且连续(这样才能保证传参无 歧义)
- 缺省参数不能在函数声明和定义中同时出现(因为,如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值)
声明给,定义不给,可以
声明不给,定义给,不可以(如果不传参数(默认使用缺省参数),则先包声明,声明使得编译阶段通过,如果声明没有缺省参数,在定义给了缺省参数,去找参数地址就会出问题)
- 缺省值必须是常量或者全局变量
- C语言不支持(编译器不支持)
总结
这里对文章进行总结:
以上就是今天总结的内容,本文包括了C++小白篇—01基础_1,分享给大家。
真💙欢迎各位给予我更好的建议,欢迎访问!!!小编创作不易,觉得有用可以一键三连哦,感谢大家。peace
希望大家一起坚持学习,共同进步。梦想一旦被付诸行动,就会变得神圣。
欢迎各位大佬批评建议,分享更好的方法!!!🙊🙊🙊