c++入门

目录

命名空间

命名空间定义

命名空间的使用

std命名空间

输入 输出

缺省参数

函数重载

函数重载概念

函数重载原理

引用

内联函数

auto关键字

基于范围的for循环

nullptr指针空值


命名空间

在c++如果大量的变量、函数和类的名称都存放在全局作用域中的话,可能对导致很多命名冲突问题,比如自己定义的函数名和库里的函数名相同了。

c++引入了一个关键字namespace来解决这个问题

命名空间定义

namespace 命名空间名字{}
命名空间中可以定义变量/函数/类型

namespace n1
{
   int a;
   int b;
   int fun(int x,int y)
   {
      return x+y;
   }
}

命名空间也可以嵌套

namespace N1
{
   int a;
   namespace N2
   {
     int b;
   }

}

一个命名空间定义了一个新的作用域,命名空间中所有的内容都局限域改命名空间中

命名空间的使用

  • 加命名空间加作用域限定符 ::
printf("%d",N1::a);
  • using将命名空间中的成员引入
using N1::a;
printf("%d",a);
  • using namespace 命名空间 将命名空间名称引入
using namespace N1;

std命名空间

std是C++标准库的命名空间,C++将标准库的定义实现都放到这个命名空间中。

  1. 在日常练习中,建议直接using namespace std即可,这样就很方便。
  2. 在项目开发中最好使用第二种方法。指定命名空间 +using std::cout展开常用的库对象/类型等方式。

c++输入 输出

在c++中可以用cout输出cin输入

#include<iostream>

using namespace std;
int main()
{
cout<<"Hello world!!!"<<endl;
int a=0;
cin>>a;
return 0;
}
  1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件
    以及按命名空间使用方法使用std。
  2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含<
    iostream >头文件中。
  3. <<是流插入运算符,>>是流提取运算符。
  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型

缺省参数

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

其实就是默认参数
在定义函数的时候给参数一个默认的值,如果函数调用时没有传参就使用参数的默认值。

缺省参数分为全缺省、半缺省

  • 全缺省参数
void Func(int a = 10, int b = 20, int c = 30)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
  • 半缺省参数
void Func(int a, int b = 10, int c = 20)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现
    3.缺省的值必须时常量或者全局变量

函数重载

函数重载概念

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

函数的参数个数 类型 和顺序不同都可以构成函数重载

函数重载原理

要理解函数重载的原理首先要理解编译器编译的过程
编译器编译的过程:

  1. 预处理:完成头文件展开 宏替换 条件编译 去掉注释等功能 最后生成 .i文件
  2. 编译:语法分析 语法检查 符号汇总 生产汇编代码 .s文件
  3. 汇编:形成符号表 把汇编代码转化成二进制机器码 生产可重定位目标文件.o文件
  4. 链接:合并段表 符号表合并和符号表重定为

在编译链接的过程中,编译器在编译阶段会根据函数的名字将函数转化成符号,在汇编阶段形成符号表 表里面包含函数的地址。链接时再到符号表中找到这个函数的地址。
在C语言直接使用函数名来标识和查找函数,如果连个函数名相同在符号表中就会存在歧义,同时链接的时候也会冲突。所以C语言不支持重载。
而在c++中有函数名修饰规则,不是直接根据函数名来标识函数。 比如g++编译器会根据函数的长度 函数名 类型首字母来修饰函数名 这样就算函数名一样修饰后的名称也不一样。在符号表里重载的函数就不存在二义性和冲突了,链接查找地址时也很明确。

引用

应用就是给已经存在的变量取一个别名,引用不开空间 ,他和引用的变量使用同一块空间

类型&  引用变量名=引用实体

int a=10;
int& ra=a;

ra 就是a的引用,引用的类型必须和实体时同一类型的 

引用的特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用引用了一个实体后就不能在引用其他实体

注意:

在引用时权限不能放大,但是权限可以不变或缩小。

比如一个变量是只读的引用也要是只读的就要使用const引用

const int a=10;
const int& ra=a;

 引用的使用场景

  1. 引用做参数
void Swap(int& left, int& right)
{
  int temp = left;
  left = right;
  right = temp;
}

引用时变量的别名共用同一快空间,引用做参数时当引用改变实参也会改变。不用再传地址。

如果不改变参数建议使用const引用

2.引用做返回值

int& Count()
{
  static int n = 0;
  n++;
  // ...
  return n;
}

传值返回时:会创建一个临时变量,返回临时变量

传引用返回:返回返回对象的引用

注意:

函数返回时出了函数的作用域,如果返回对象还在(还没有还给系统)就可以用引用返回,如果还给操作系统了就不能用引用返回

引用和指针的区别

1.引用是别名,不开空间

2.引用在定义时必须初始化

3.引用再初始化后就不能改变其指向

4.sizeof引用是实体大小 sizeof指针4或8

5.没有空引用

6.没有多级引用

7.引用自加是实体自加,指针自加是向后偏移一个类型大小

8.访问实体的方式不同

9.引用更安全,指针需要考虑空指针、野指针

内联函数

以inline修饰的函数

c++在编译时会在调用内联函数处将函数展开,不会建立函数栈帧,提升函数的运行效率。

1.inline是一种空间换时间的做法,在编译阶段会用函数体替换函数调用。可能会造成目标问价过大

2.inline对编译器而言只是一个建议。具体取决去编译器。不是递归且调用频繁可以使用inline

3.inline不要声明定义分开。因为符号表中不会生产inline函数的地址,会导致链接错误。

auto关键字

作用:根据右边的值自动推导类型

类型声明成auto,可以根据a的类型自动推导b的类型

int a = 10;
auto c = &a;
auto* d = &a;
//用这两个当成指针都可以,都是int*类型
int& y = a;
//类型为int,是a的引用
auto& z = a;
//类型为int,但z为a的引用

注意:

当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导

auto不能推导的场景

1.不能用来声明数组

int a = {1,2,3};
auto b = {4,5,6};//不行

2.不能做参数

void TestAuto(auto a)//不行

基于范围的for循环

//c++11范围for
int arry[10]={1,2,3,4,5,6,7,8,9}
for (auto e:arry)
{
   cout<<e<<endl;
}

自动依次取数组中的元素,赋值给e

范围for   后面必须是数组名 

nullptr指针空值

NULL实际上是一个宏定义如下

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

可以看出 NULL和常量0是等价的 所以再某些情况下可能会发生混淆

void f(int)
{
  cout<<"f(int)"<<endl;
}
void f(int*)
{
  cout<<"f(int)"<<endl;
}
int main()
{
  f(0);
  f(NULL);
  f((int*)NULL);
  return 0;
}

程序实际上想通过f(NULL)调用指针版本的(int*)函数,但是由于NULL被定义为0。所以会调用第一个函数。那么我们如果就想传一个空指针就要用(int*)NULL

所以c++y引入nullptr表示空指针

1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入
的。
2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lilvic

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

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

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

打赏作者

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

抵扣说明:

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

余额充值