【C++】入门基础知识(精简)

目录

C++关键字(C++98)

 命名空间的三种方式

1.指定,加命名空间名称及作用域限定符

2.展开常用的,使用using引入命名空间中的成员

3.全部展开,使用using namespace引入命名空间名称

缺省参数

函数重载

引用

内联函数 

auto关键字

nullptr


C++关键字(C++98)

C++总共63个关键字,C语言32个

【C++】入门基础知识(精简)_第1张图片

 命名空间的三种方式

命名空间主要解决名字冲突,作用就是定义一个新的作用域

1.指定,加命名空间名称及作用域限定符

namespace ps
{
   int rand = 0;
}
int main()
{
    printf("%d\n", ps::rand);
    return 0;
}

2.展开常用的,使用using引入命名空间中的成员

namespace gf
{
    int rand = 0;
    int sqrtt = 1;
}

using gf::sqrtt;

int main()
{
    printf("%d\n", sqrtt);
    return 0;
}

3.全部展开,使用using namespace引入命名空间名称

namespace gf
{
    int rand = 0;
    int sqrtt = 1;
}

using namespace gf;

int main()
{
    printf("%d\n", sqrtt);
    return 0;
}

全部展开相当于把这个命名空间暴露在全局域中,命名冲突的风险更大

建议:

1.项目中,尽量不要使用using namespace std;

2.日常练习用using namespace std;

3.项目中,指定命名空间访问+展开常用

缺省参数

缺省参数是声明定义函数时为函数的参数指定一个默认值

在调用有缺省参数的函数时,如果没有指定实参则采用该默认值,否则使用指定实参

如果没有传参数,缺省参数就会起作用

void Func(int a = 0)
{
   cout << a << endl;
}

int main()
{
   Func();
}

半缺省,必须从右往左连续缺省,不能间隔

void Func(int a, int b = 20; int c = 30)
{
    
}

缺省参数不能在函数声明和定义中同时出现

分离定义时:声明给缺省参数

函数重载

C++允许同一作用域声明功能类似的同名函数

这些同名函数形参列表(参数个数 或 类型 或 顺序)必须不同

int Add(int p1, int p2)
{
}

int Add(int p1, double p2)
{
}

int Add(double p1, int p2)
{
}

 注意:返回值不同并不构成重载

C++有函数名修饰规则所以支持重载

C++函数名修饰规则是拿函数名+参数类型的首字母去调用(不同编译器可能会有所不同)

而C语言是直接拿函数名去调用,所以不支持

引用

引用给已存在的变量取一个别名,编译器不会为引用变量开空间

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

//给a取个别名b
int main()
{
   int a = 0;
   int& b = a;
}

int a = 1;
//int& b;    //1.引用在定义时必须初始化

int& b = a;  //2.一个变量可以有多个引用
int& c = a;
int& d = c;

//引入一旦引用一个实体,就不能引用其他实体

引用的好处

//做输出型参数
void Swap(int& p1, int& p2)
{
  int tmp = p1;
  p1 = p2;
  p2 = tmp;
}

int main()
{
  int a = 0, b = 2;
  Swap(a, b);
}

注意:出了函数的作用域,返回对象就销毁了

那么一定不能用引用返回,要用传值返回

int Count() //传值返回
{
  int n = 1;
  return n;
}

int& Count() //引用返回
{
  int n = 1;
  retrun n;
}

传值返回会统一生成一个返回对象临时拷贝作为函数调用返回值

返回对象临时拷贝会随着函数调用的结束而销毁

如果返回值小拷贝会放到寄存器里面

寄存器只能存4/8个字节

如果大会在main函数里面提前开好空间

下面就可以使用引用返回,把q放到静态区,就不会随着函数调用的结束而销毁

int& Count()
{
   static int q = 1;
   
   return n;
}

引用权限不能放大,但是可以缩小 

 【C++】入门基础知识(精简)_第2张图片

不同类型间的赋值会先创建一个临时变量

而临时变量具有常性,所以被赋值的变量必须加const

(常性指变量所属类型是否为const或volatile类型)

 const引用具有很强的接收度,如果使用引用传参,函数内不改变传过来的参数,那么建议尽量用const引用传参

引用和指针的不同 

1.引里在定义时必须初始化,指针没有要求
2.引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
3.没有NULL引用,但有NULL指针
4.在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
5.引用自加即引用的实体增加1,指针自加即指针向后偏移一全类型的大小
6.有多级指针,但是没有多级引用
7.访问实体方式不同,指针需要解引用,引用编译器自己处理
8.引用比指针使用起来相对更安全

引用表面好像是传值,其本质也是传地址,只是这个工作由编译器来做 (某大厂有考过)

内联函数 

概念:以inline修饰的函数叫内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率

适合短小的函数(1-10行)且频繁调用(10万次)

适合场景:堆排和快排,排序10w数据,里面swap函数 

 C的宏函数的优点:a、复用性变强 b、宏函数提高效率,减少栈帧建立

宏函数的缺点:a、可读性差 b、没有类型安全检查 c、不方便调试

而C++ inline的出现便是用来替换C的宏函数,解决宏函数缺点的同时兼顾宏函数的优点

//inline 符合条件的情况,在调用的地方展开
inline int Add(int a, int b)
{
    return a + b;
}

C++中不建议使用宏,尽量使用const,enum,inline替换宏

1.inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不宜使用作为内联函数
2.inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有函数内部实现代码指令长度比较长(10行左右)/递归等等,编译器优化时会忽略掉内联。
3.inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。(建议在声明里面定义)

auto关键字

auto的原理就是根据后面的值,来自己推测前面的类型是什么。

auto的作用就是为了简化变量初始化,如果这个变量有一个很长很长的初始化类型,就可以用auto代替

在声明符列表中,“auto”必须始终推导为同一类型
//auto x1 = 5, x2 = 3.0, x3='s';
auto = 3.0, 5.5, 6.3;

 例如:

std::vector ve;
std::vector::iterator it = ve.begin();
// 可以用auto代替初始化类型:
auto it = ve.begin();
int main()
{
    int a[] = { 1,2,3,4,5 };
    for (auto& s : a)
    {
        s--;
        std::cout << s << " ";
    }
    return 0;
}

注意:1.用auto声明的变量必须初始化(auto是根据定义的值自动匹配变量类型,如果后面没有值,就会报错)

2.函数和模板参数不能被声明为auto(原因同上)

3.因为auto是一个占位符,并不是一个他自己的类型,因此不能用于类型转换或其他一些操作,如sizeof和typeid

4.定义在一个auto序列的变量必须始终推导成同一类型 

5.auto不能作为函数参数类型,也不能作为数组类型 

nullptr

NULL是一个宏定义,而nullptr是C++的一个关键字

C++新标准中建议使用nullptr代替NULL来声明空指针

因为在早期设计 NULL 空指针时,NULL 实际上就是 0,所以导致有些地方使用 NULL 会造成不明确的函数调用 

void Coun(char *){}
void Coun(int){}

int main()
{
   Coun(NULL);    // 调用Conc(int)
}

我们经常用NULL来初始化空指针,从惯性思维看,Coun应该调用的是void Coun(char *)

但C++中NULL的值是0,所以调用的是void Coun(int)。考虑如上问题,nullptr关键字便引入了。

 nullptr关键字用于标识空指针。它可以转换成任何指针类型和bool布尔类型(主要是为了兼容普通指针可以作为条件判断语句的写法),但是不能被转换为整数。

你可能感兴趣的:(C++,c++,开发语言,c语言,程序人生,职场和发展,学习方法)