文章目录
前言一.c++关键字二.命名空间1.命名空间的定义2.命名空间的使用 三.c++输入&输出四.缺省参数五.函数重载1.函数重载的概念2.编译链接和函数名修饰规则
前言
在之前的文章中,我们学完了初阶数据结构的线性表,栈和队列,堆,二叉树以及排序(详细可以看我之前的几篇文章),在接下来的一段时间内将重点学习c++,c++是在c的基础上,容纳进去了面向对象编程的思想,并且增加了许多有用的库,以及编程范式等。学习c++之前要有一定的C语言基础。本篇文章将讲解c++入门知识,也是对C语言不足的补充,为后序类和对象的学习打好基础。
一.c++关键字
在学习C语言中我们知道关键字之一概念,而在c++中同样也有关键字,甚至数量要比C语言的多,因为c++兼容C语言,所以C语言有的关键字,c++也有。
C语言共有32个关键字,而c++共有64个关键字。如图所示
二.命名空间
在之前c语言中,我们一定遇到过以下这种情况
#include<stdio.h>#include<stdlib.h>int rand = 10;int main() {printf("%d", rand);return 0;}
上面这种情况就是rand重定义,rand在库函数中是一个函数名,但是在这里我们将它定义为一个变量名,所以产生错误也就是命名冲突,而c++为了解决这一问题,引入了命名空间(namespace
)这一概念,而命名空间所在的区域又叫命名空间域。
1.命名空间的定义
定义命名空间,需要使用到namespace
关键字,后面加命名空间的名字,然后接一对{ },{ }中就是命名空间的成员。
命名空间的成员可以是变量,函数或结构体。
namespace N{ //变量 int rand; //函数 int Add(int a,int b){ return a+b; } //结构体 struct ListNode{ int data; struct ListNode*next; };}
命名空间也可以嵌套使用
namespace A1{ int a; int b; int Add(int left,int right){ return left+right; } //命名空间A1嵌套命名空间A2 namespace A2{ int c; int d; int Sub(int left,int right){ return left-right; } }}
在同一个工程中允许存在多个同名的命名空间(成员不同),编译器最后都会合成到同一个命名空间中。
比如下面的test.h文件中的命名空间A1和test.cpp文件中的命名空间A1最后会合并成一个。
//test.h文件中有namespace A1namespace A1{ int a; int b; int Add(int left,int right){ return left+right; }}//test.cpp文件中也有namespace A1namespace A1{ int c; int d; int Sub(int left,int right){ return left-right; }}
2.命名空间的使用
在c语言中如果我们直接定义一个变量并初始化,当我们想要打印这个变量的值时,我们可以直接访问
int main(){ int a=10; printf("a=%d\n",a); return 0;}//输出结果a=10
而在c++中,当我们将变量定义到命名空间中,再像C语言一样直接访问就会报错
namespace A{ int a=10; int b=0;}int main(){ printf("a=%d\n",a); return 0;}
这时候我们就要使用::
域作用限定符
在C语言中我们知道局部变量所在的为局部域,全局变量所在的叫全局域,在c++中还有命名空间域和类域;域影响的是编译时语法查找一个变量或函数或类型出处的逻辑,有了域隔离,就能解决命名冲突。
访问顺序:局部域>全局域>展开命名空间域or指定访问命名空间域
命名空间域展开会暴漏在全局域中,所以不能和全局域同时访问。因此命名空间只能定义在全局中。
当我们要展开命名空间域or指定访问命名空间域时就要用到::
命名空间的使用方法有三种
指定访问某个成员
int main(){ //指定访问命名空间A的变量a成员 printf("a=%d\n",A::a); return 0;}
使用using
全部展开命名空间
using namespace A;int main(){ printf("a=%d\n",a); printf("b=%d\n",b); return 0;}
使用using
部分展开
//注意:这里部分展开不带namespaceusing A::b;int main(){ printf("a=%d\n",A::a); printf("b=%d\n",b); return 0;}
三.c++输入&输出
在C语言中我们学过输入和输出函数scanf
,printf
,在c++中,同样也有输入输出。在这之前我们先来了解一下什么是std
前面我们学过c++为了解决命名冲突而引入了命名空间,而std
就是c++标准库命名空间,c++将标准库的定义实现都放在了这个命名空间中,所以在使用c++标准库函数时,我们要展开命名空间或者指定访问。
//和C语言不同的是,c++的头文件不需要加.hinclude<iostream>using namespace std;int main(){ //打印输出hello world cout<<"hello world"<<endl; //输入x,d的值 cin>>x>>d; //输出x,d的值 cout<<x<<" "<<d<<endl; return 0;}
cout
标准输出对象(控制台,可以理解为vs中的黑框),cin
标准输入对象(键盘),使用时,必须包含头文件,并且正确使用命名空间std
。<<
流插入运算符,<<
流提取运算符。cout
和cin
是全局流对象,endl
是特殊的c++符号,相当于C语言中的'\n'
换行符号。相比于C语言中的scanf
和printf
需要手动控制变量类型,c++的输入输出可以自动识别变量类型,更加方便。 std命名空间的使用惯例:
std是c++标准库的命名空间,如何展开std使用更合理:
日常练习中,直接展开using namespace std
即可。using namespace std
展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对 象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模 大,就很容易出现。所以建议在项目开发中使用,像std::cout
这样使用时指定命名空间 + using std::cout
展开常用的库对象/类型等方式。 四.缺省参数
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在函数调用时,如果没有指定实参则采用形参的缺省值,否则使用指定实参。
void Fun(int a=0){ cout<<a<<endl;}int main(){ //没有传参数时,使用参数默认值0 Fun(); //传参数时,使用指定的实参1 Fun(1); return 0;}
全缺省参数
using namespace std;void Fun(int a=0,int b=1,int c=2){ cout<<"a="<<a<<" "; cout<<"b="<<b<<" "; cout<<"c="<<c<<" "; cout<<endl;}int main(){ Fun(); Fun(10); Fun(10,20); Fun(10,20,30); return 0;}
半缺省参数
using namespace std;void Fun(int a,int b=10,int c=20){ cout<<"a="<<a<<" "; cout<<"b="<<b<<" "; cout<<"c="<<c<<" "; cout<<endl;}int main(){ Fun(1); Fun(1,2); Fun(1,2,3); return 0;}
注意:
半缺省参数必须从右往左依次来给出,不能间隔着给。缺省参数不能在函数声明和定义中同时出现,要在声明中给。缺省参数必须是常量或全局变量c++支持缺省参数,C语言不支持五.函数重载
在我们的日常生活中,我们经常遇到一词多义的情况,也就是多义词,即该词被重载了,在不同的场景下会有不同的含义。而在c++同样也有这一情况,也就是函数重载。
1.函数重载的概念
函数重载是一种特殊的函数情况,c++允许在同一作用域中声明几个功能相似的同名函数,函数的形参列表(参数个数,参数类型以及参数类型的顺序)不同,常用来处理功能类似但数据类型不同的问题。
参数个数不同
void f( ){ cout<<"f()"<<endl;}void f(int a){ cout<<"f(int a)"<<endl;}
参数类型不同
int Add(int a,int b){ return a+b;}int Add(double a,double b){ return a+b;}
参数类型的顺序不同
void f(int a,char b){ cout<<"f(int a,char b)"<<endl;}void f(char a,int b){ cout<<"f(char a,int b)"<<endl;}
特殊情况
void F(){ cout<<"F()"<<endl;}void F(int a=0){ cout<<"F()"<<endl;}int main(){ F(); return 0;}//构成重载//无参调用时存在歧义,调用不明确
2.编译链接和函数名修饰规则
为什么C语言不支持函数重载,c++支持函数重载,这涉及到编译链接过程以及函数名修饰规则
编译链接需要进行以下几个阶段:预处理,编译,汇编,链接。
c++在编译期间链接前会对函数名进行更复杂的修饰,编译器会生成一个包含函数名,返回类型,参数类型等信息的字符串作为修饰名,用于在链接阶段定位函数的正确位置。从而区分同名但参数不同的函数。(注意:不同的编译器函数名修饰格式不一样,以linux系统为例)
//函数名修饰为Addiivoid Add(int a,int b)//函数名修饰为Addddvoid Add(double a,double b)
而C语言的函数名修饰相对简单,通常只是加上一个下划线或者保持不变,所以当出现同名函数时,在链接阶段就会无法正确找到函数位置
以上就是关于c++入门部分的讲解,如果哪里有错的话,可以在评论区指正,也欢迎大家一起讨论学习,如果对你的学习有帮助的话,点点赞关注支持一下吧!!!