C++基础特性

简介: c++基础特性

> “青青子衿,悠悠我心。但为君故,沉吟至今。”


@[TOC](这里是目录)

# 前言

1.C++很难学?——是的

C++整体学习难度和Java整体学习难度是一样的

不要想着精通C++。

![请添加图片描述](https://ucc.alicdn.com/images/user-upload-01/adfb8adabc9042b2af4cf7d76168eefb.jpeg)


# 一、命名空间

命名空间是为了防止冲突,有时候全局变量定义了好多,这时候会导致命名冲突,这时候的命名空间的作用就是给文件定了一个作用域,在这里就可以限定**变量,函数**的名称。

## 1.什么是命名空间?

命名空间就是namespace 后面跟的一串字符。这一串字符就叫做命名空间。命名空间的名字可以随便起。


代码举例定义:

命名空间里的变量a,和函数Add是独立的。和其他命名空间隔开的。


```cpp

namespace N1//N1就是命名空间

{

int a;

int Add(int x, int y)

{

 return x + y;

}

}

```

# 二、C++输入输出

C++的输入输出函数是cin和cout。从英语可以看出,in就是输入,out就是输出。cin输入就相当于C语言中的sancf,cout就相当于C语言中的输出。

这两个函数学习起来成本有点高现在学了不一定能学懂,以后再说。

# 三、缺省参数

## 1.什么是缺省参数?

缺省参数就相当于C语言中的形参可以赋初始值,也就是为形参指定了默认值。

规则:如果没有实参穿过去,则使用该默认值。否则使用形参的值。

## 2.全缺省参数

全缺省就是全部形参都设置默认值


```cpp

void Print(int a = 10, int b = 20)

{

cout <<a << endl;

cout << b << endl;

}

```

## 3.半缺省参数

半缺省参数是有的形参没有设置初始值。但是缺省只能从右往左缺省。

```cpp

void Print(int a, int b = 20)

{

cout <<a << endl;

cout << b << endl;

}

```

# 四、函数重载

函数重载是什么?

## 1.什么是函数重载?

函数重载也是为了解决C语言的不便。假如需要调用Add加法的函数,如果没有函数重载的话就需要写不止一个Add函数。因为数有整数int,有浮点数float,有double类型的。这样就需要写三个版本的Add函数了。

但是C++的函数重载解决了这个问题。你想要不同类型的任何的数字相加都可以。都可以实现调用Add这一个名字,而不需要写为其他名字。


## 2.重载规定

函数重载的这些同名函数必须 **形参列表不同**。形参列表不同指的是:**形参顺序不同,形参类型不同,形参个数不同。**

# 五、重载原理

## 1.为什么C语言不支持函数重载,而C++支持?

不论是C/C++,都要经历,预处理,编译,汇编,链接。在编译的阶段,C语言会将函数名形成一个符号表,假如函数是Add(int x, double y);那么C语言形成的符号表里的函数名也是Add。但是C++他不一样呀,他为了弥补C语言这个小傻瓜的空白,在编译后形成的符号是:_ZAddid。格式是什么呢?格式是:_Z + 函数名 + 类型首字母,这就是C++支持函数重载的原因。


这样我们就理解函数重载要求 参数不同,和返回值没关系。


# 六、extern "C"

extern C是在C++工程中想让代码按照C语言的方式编译,或者想调用C语言工程时所用的。函数前面加extern C 是高数编译器,该代码或者函数需要按照C语言的规则编译。

# 七、引用

引用就是取别名

引用就是重用了C语言的取地址符号&。

代码举例:


```cpp

#include <iostream>

using namespace std;

int main()

{

int a = 10;

int& b = a;

return 0;

}


```

b称为a的引用。

引用格式:类型& 引用变量名 = 引用实体。

## 1.引用特性

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

2.引用只能引用一个实体。什么意思呢?意思就是b引用了a之后,就不能再引用其他变量了。

## 2.常引用(重点)

什么是常引用?

在前面加了const修饰的就是常引用。

常引用涉及到了权限放大缩小的问题。权限指的是变量的读和写。

被const修饰的变量不能改变其值。所以只能读取。

读就相当于你看书,写就相当于你在书上做笔记。


代码举例:


```cpp

int main()

{

const int a = 10;

//int& ra = a;错误,权限放大。因为a是只读的,而int是可以读写的。

const int& ra = a;

}

```

## 3.引用做形参

引用做形参就可以不用传指针了。

这样就方便了我们写程序的效率。

代码举例:

这里的x和y是实参的引用。

```cpp

//交换函数

void Swap(int& x, int& y)

{

int t = 0;

t = x;

x = y;

y = t;

}

```

## 4.引用作返回值

引用可以做返回值。但是要注意:只有出了作用域,被返回的值没有销毁,才可以用引用做返回值。所以我们定义的变量必须是static修饰的或者是动态开辟的,或者是全局变量等不会随着函数调用的结束而销毁的变量。

代码举例:


```cpp

int& Add(int a, int b)

{

static int c = a + b;

return c;

}

```

注意:如果函数返回时,出了函数作用域,返回对象未还给系统,则可以使用引用返回;如果已经还给系统了,则必须使用传值返回。

# 八、内联函数

## 1.什么是内联函数?

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用的地方展开。使用时只用在函数前面加上inline,但是inline只是一种建议,具体实现还是看编译器。

## 2.内联函数特性

1.函数会在调用的地方展开没有函数压栈的开销,内联函数的使用可以提升程序的运行效率。频繁调用的小函数建议定义成内联函数

2.inline对于编译器只是一个建议,编译器会自动优化。

3.inline不建议声明和定义分离,因为inline是在函数调用的地方展开,编译的时候不会给函数分配地址,所以会导致连接错误。

# auto关键字(C++11)

## 1.什么是auto

在C++11中,标准委员会赋予了auto全新的含义:auto不再是一个存储类型的指示符,而是作为一个新的类型指示符来指示编译器,auto生命的变量必须有编译器在编译使其推导而得。


## 2.auto使用规则

1.使用auto变量时必须初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型,编译器在编译期间会将auto替换为变量实际类型。


代码举例

```cpp

#include <iostream>

using namespace std;

double Fun()

{

return 3.14;

}

int main()

{

int a = 10;

auto b = a;

auto c = 'A';

auto d =Fun();

cout << typeid(b).name() << endl;

cout << typeid(c).name() << endl;

cout << typeid(d).name() << endl;

return 0;

}


```

## 3.auto与指针引用结合起来使用

用auto声明指针类型时,用auto和auto*没有任何区别,**但用auto声明引用类型时必须加&。**


```cpp

#include <iostream>

using namespace std;

int main()

{

int a = 10;

auto b = &a;

auto* c = &a;

auto& d = a;

cout << typeid(b).name() <<endl;

cout << typeid(c).name() <<endl;

cout << typeid(d).name() <<endl;

return 0;

}

```

## 4.如何在同一行定义多个变量?


在同一行声明多个变量时,这一行的变量必须是相同的类型,否则编译器会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

```cpp

int main()

{

auto a= 1, b = 2;

auto c = 3, d = 4.0;

return 0;

}

```

## 5. auto不能推导的场景

1.auto不能作为函数的参数


因为无法知道实参的类型

```cpp

void TestAuto(auto x)

{


}

```

2.auto不能直接用来声明数组


```cpp

int main()

{

int a[] = {1,2,3};

auto b[] = {4, 5, 6};

return 0;

}


```

# 九、基于范围的for循环(c++11)

不同于平时的for循环。C++11引入了基于范围的for循环。

概念:for循环后的括号由冒号分为两部分:前半部分是**范围内用于迭代的变量,**后半部分**是表示被迭代的范围**。


代码举例


```cpp

int arr[] = { 1,2,3,4,5};

//将数组元素的值都乘以2

for(auto& e : arr)

{

e *= 2;

}

//打印数组中的所有元素

for(auto e : arr)

{

cout << e << " ";

}

cout << endl;

```

可以用continue来结束本次循环,也可以用break来跳出整个循环。


## 1.范围for的使用条件

1.for循环迭代的范围必须是确定的。

对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围。

2.迭代的对象要实现++和==的操作。

以后再详细了解

# 十、空指针nullptr(C++11)特性

1.在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为关键字引入的。

2.在C++11中,sizeof(nullptr)和sizeof((void*)0)所占字节数相同。

3.为了提高代码的健壮性,在以后的代码中表示指针空值时最好使用nullptr。不建议用C语言中NULL。



相关文章
|
2月前
|
编译器 程序员 定位技术
C++ 20新特性之Concepts
在C++ 20之前,我们在编写泛型代码时,模板参数的约束往往通过复杂的SFINAE(Substitution Failure Is Not An Error)策略或繁琐的Traits类来实现。这不仅难以阅读,也非常容易出错,导致很多程序员在提及泛型编程时,总是心有余悸、脊背发凉。 在没有引入Concepts之前,我们只能依靠经验和技巧来解读编译器给出的错误信息,很容易陷入“类型迷路”。这就好比在没有GPS导航的年代,我们依靠复杂的地图和模糊的方向指示去一个陌生的地点,很容易迷路。而Concepts的引入,就像是给C++的模板系统安装了一个GPS导航仪
123 59
|
18天前
|
安全 编译器 C++
【C++11】新特性
`C++11`是2011年发布的`C++`重要版本,引入了约140个新特性和600个缺陷修复。其中,列表初始化(List Initialization)提供了一种更统一、更灵活和更安全的初始化方式,支持内置类型和满足特定条件的自定义类型。此外,`C++11`还引入了`auto`关键字用于自动类型推导,简化了复杂类型的声明,提高了代码的可读性和可维护性。`decltype`则用于根据表达式推导类型,增强了编译时类型检查的能力,特别适用于模板和泛型编程。
18 2
|
2月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(三)
【C++】面向对象编程的三大特性:深入解析多态机制
|
2月前
|
存储 编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(二)
【C++】面向对象编程的三大特性:深入解析多态机制
|
2月前
|
编译器 C++
【C++】面向对象编程的三大特性:深入解析多态机制(一)
【C++】面向对象编程的三大特性:深入解析多态机制
|
2月前
|
存储 安全 编译器
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(一)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
|
2月前
|
C++
C++ 20新特性之结构化绑定
在C++ 20出现之前,当我们需要访问一个结构体或类的多个成员时,通常使用.或->操作符。对于复杂的数据结构,这种访问方式往往会显得冗长,也难以理解。C++ 20中引入的结构化绑定允许我们直接从一个聚合类型(比如:tuple、struct、class等)中提取出多个成员,并为它们分别命名。这一特性大大简化了对复杂数据结构的访问方式,使代码更加清晰、易读。
41 0
|
3月前
|
编译器 C++ 计算机视觉
C++ 11新特性之完美转发
C++ 11新特性之完美转发
54 4
|
3月前
|
Java C# C++
C++ 11新特性之语法甜点1
C++ 11新特性之语法甜点1
34 4
|
3月前
|
安全 程序员 编译器
C++ 11新特性之auto和decltype
C++ 11新特性之auto和decltype
45 3