朋友们好,从这篇播客起我们正式进入C++的学习,现在对一些C++的入门知识做了些总结,整理出来一篇博客供我们一起复习和学习,如果文章中有理解不当的地方,还希望朋友们在评论区指出,我们相互学习,共同进步!
文章目录
一 :命名空间
目的:使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字就是针对这种问题而出现的。
1.1 命名空间的定义
什么意思呢?如一下代码:
int a = 0;
int main(){
int a = 1;
printf("%d\n", a);
//printf("%d\n", ::a);//::左边空白默认全局域,::域作用限定符,::对应域
system("pause");
return 0;
}
💡::左边空白默认全局域,::域作用限定符,::对应域
我们定义了一个同名的全局变量和局部变量,在我们打印时,编译器默认打印局部变量,这就是我们要解决的问题。当我们在打印a前面加::时,就告诉编译器这时打印全局变量a,指定他的空间域。
如我们定义一个空间域:
namespace pxl{
int rand = 0;
int f = 0;
}//同一个作用域不可以定义同一个变量,所以要用空间把它们隔离了
int main(){
printf("%d\n", rand);//函数名有没有地址符号都是取地址
printf("%d\n", pxl::rand);//输出限定在pxl空间域的rand
system("pause");
return 0;
}
2016803504
0
请按任意键继续. . .
这里第二个打印指定了空间域,就打印pxl空间域的rand值。
同一个作用域不可以定义同一个变量,所以要用空间把它们隔离了
1. 命名空间域,只能放在全局(也就是说不能在一个函数内部定义)。里面可以定义变量 、函数、 自定义类型,但是展开命名空间不要随便使用(可以展开局部:using pxl::f ),一般我们直接写using namespace std。
2. 命名空间可以嵌套。
3. 同一项目中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
4. 命名空间不影响变量的生命周期。
1.2 命名空间的使用
下面我们先看一个错误案例:
namespace pxl{
int a = 10;
int b = 20;
int Add(int left, int right){
return left + right;
}
int Sub(int left, int right){
return left - right;
}
}
int main(){
printf("%d\n", a);
system("pause");
return 0;
}
错误提示说:错误 1 error C2065: “a”: 未声明的标识符。
因为这里的a是在命名空间域的pxl中的,所以需要指定空间域!!!
⭐️命名空间使用的三种方式:
- 加命名空间名称及作用域限定符。
```cpp
int main(){
printf("%d\n", pxl::a);
return 0;
}
- 使用using将命名空间成员引入。
using pxl::a;
int main(){
printf("%d\n", a);
system("pause");
return 0;
}
- 使用using namespace命名空间名称引入。
using namespace pxl;
namespace pxl{
int a = 10;
int b = 20;
int Add(int left, int right){
return left + right;
}
int Sub(int left, int right){
return left - right;
}
}
int main(){
printf("%d\n", a);
system("pause");
return 0;
}
二:C++输入输出
注意:
- 使用cout标准输出(控制台)和cin标准输入(键盘)时, 必须包含头文件iostream以及std标准命名空间。
- 使用C++输入输出时更方便,不需要增加数据的格式控制,可自动识别。
int main()
{
int a;
double d;
cin >> a >> d;
cout << a <<" "<< d << endl;
cout << a <<":"<<d << '\n';
printf("%d %.2f\n", a, d);//当需要格式化输出时,还是可以采用C语言语法
system("pause");
return 0;
}
2 2.33333
2 2.33333
2:2.33333
2 2.33
请按任意键继续. . .
注:当需要格式化输出时,还是可以采用C语言语法
三:缺省参数
C++引入函数参数做备胎!!!
3.1 缺省参数的概念
缺省参数是声明或者定义函数时为函数参数指定的一个默认值(默认参数)。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定实参。
void Func(int a = 0)
{
cout << a << endl;
}
int main()
{
Func(); // 没有传参时,使用参数的默认值
Func(1);
//你若安好,备胎到老
return 0;
}
0
1
请按任意键继续. . .
没有传参时,使用参数的默认值。
3.2 函数缺省分类
- 全缺省参数
void TestFunc(int a = 10, int b = 20, int c = 30)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
int main()
{
TestFunc();
TestFunc(1);
TestFunc(1,2);
TestFunc(1,2,3);
return 0;
}
输出:
a = 10
b = 20
c = 30
a = 1
b = 20
c = 30
a = 1
b = 2
c = 30
a = 1
b = 2
c = 3
请按任意键继续. . .
- 半缺省参数
void TestFunc(int a, int b = 20, int c = 30)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl << endl;
}
int main()
{
//TestFunc();
TestFunc(1);
TestFunc(1,2);
TestFunc(1,2,3);
system("pause");
return 0;
}
a = 1
b = 20
c = 30
a = 1
b = 2
c = 30
a = 1
b = 2
c = 3
请按任意键继续. . .
这里b,c缺省,所以必须在调用函数时有一个实参传入!!!
注意:
- 半缺省参数必须是从右往左依次给出,不能间隔着来给。
- 缺省参数不可以在函数声明和定义中同时出现(在声明给),以避免两处缺省值不一样,导致编译器无法识别。
- 缺省值必须是常量或者全局变量。
- C语言不支持这种写法。
四:函数重载
extern “C” :有时候在C++工程中可能需要某些函数按照C的风格来编译,在函数前加extern “C”,意思是告诉编译器,将该函数按照C语言规则来编译!
4.1 函数重载概念
函数重载:是C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表必须不同,具体不同包括:参数个数,顺序,类型。
- 顺序不同:
// 顺序不同
void f(int i, double d)
{
cout << "void f(int i, double d)" << endl;
}
void f(double i, int d)
{
cout << "void f(double i, int d)" << endl;
}
- 类型不同
void swap(int* p1, int* p2)
{
int x = *p1;
*p1 = *p2;
*p2 = x;
}
void swap(double* p1, double* p2)
{
double x = *p1;
*p1 = *p2;
*p2 = x;
}
- 个数不同
4.2 C++调用C静态库
为什么不可以直接调用?
💡因为C++支持重载,C语言不支持重载,修饰函数名不一样,导致链接不上。
配置C语言静态库:
C++项目如何调用C库?
- 找到库所在的相对路径 :#include “…/…/Stack_C.lib/Stack_C.lib/Stack.h”(找.h文件所在的路径)
- 第二步:
- 在附加依赖项加上库名
- 声明 extern “C”
在C++项目里包含库的相对路径:
extern "C"{//告诉C++编译器extern"C"声明的函数是C库,要用C的方式取链接调用
#include "../../Stack_C.lib/Stack_C.lib/Stack.h"
}
//告诉C++编译器extern"C"声明的函数是C库,要用C的方式取链接调用,因为C++认识C编译器的规则。
4.3 C 调用 C++静态库
同样配置C++静态库:
配置结果:
链接配置:
💡💡💡然后在静态库的头文件引入条件编译。在静态库的头文件操作如下:
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endif
EXTERN_C void StackInit(ST* ps);
EXTERN_C void StackDestory(ST* ps);
EXTERN_C void StackPush(ST* ps, STDataType x);//压栈
EXTERN_C void StackPop(ST* ps);//
EXTERN_C bool StackEmpty(ST* ps);//判断栈区是否为空
EXTERN_C int StackSize(ST* ps);
EXTERN_C STDataType StackTop(ST* ps);//出栈
当在C++项目中时,定义了extern “C”, 当在C项目时,相当于没有定义EXTERN_C。
或者这么操作:
#ifdef __cplusplus
extern "C"
{
#endif
void StackInit(ST* ps);
void StackDestory(ST* ps);
void StackPush(ST* ps, STDataType x);//压栈
void StackPop(ST* ps);//
bool StackEmpty(ST* ps);//判断栈区是否为空
int StackSize(ST* ps);
STDataType StackTop(ST* ps);//出栈
#ifdef __cplusplus
}
#endif
因为:
- extern "C"可以加在函数声明的前面。
- 也可以括起来多个函数声明。
包含:
在C的项目里包含C++库的头文件:#include “…/…/Stack_CPP/Stack_CPP/Stack.h”