【C++】---基础特性

简介: 【C++】---基础特性

C++是一门在C语言的基础上改进后的语言,从面向过程过渡到面向对象

因此在C++的使用过程中同样保留了C语言的特性,在一份C++代码中也可与去使用C语言的语法进行编写

命名空间

在使用C语言的过程就会发现,同一样的代码里面并不能出现同名的变量或者函数,如果是一个多人合作的项目难免会出现同名的状况。C++为了避免这种状况就引入了命名空间这个概念。

使用命名空间的目的就是避免命名冲突。将定义的变量或者函数放在不同的空间里,不同空间里的变量或者函数不会引起冲突,需要用到某个空间里的某个成员时再将其调用出来,这样就可以有效的避免上述情况的发生。

命名空间可以由用户自由定义,当然C++本身也定义了空间,基本上能够使用到的库函数都在空间std里面。如果需要自己去定义一个空间就需要以下代码格式。

//namespce是命名空间的关键字
//name代表命名空间的名字可以自己定义
//后面必须要带上{},定义好后{}里面的内容就是这个空间的内容
namespace name{
    //空间里的成员
  void print(){}
    int a;
}

那么定义好了空间后就可以对空间里的成员进行调用了

//指定某个空间里的成员需要用带 :: 空间名字::空间成员
name::print();
name::a;
std::string s;

当然如果每一个函数都要用这种方式的话就会略微有些麻烦,因此在平常写小项目时不太会有冲突的情况下也可以将整个空间都放开

//using namespace 是代表将整个空间都放开
//name 代表需要放开的空间的名字
using namespace name;
//放开整个空间后就不再需要指定去调用
print();
a;

补充:

  1. 同一个工程里可以有多个相同名称的空间,编译器会自动将它们合成为同一个空间
  2. 一个空间就定义了一个新的作用域,空间中的所有内容都局限于其中
  3. using namespace代表放开整个空间,而也可以使用 using name::a 代表仅放开一个成员

输入/输出

C语言的输入输出可以使用函数 printf()\scanf()

同样C++也有属于自己独特的输入输出,其输入和输出并不用像C语言那样需要指定数据类型,而是会自动的去识别数据类型

cout 表示标准输出,cin 表示标准输入,endl 表示换行

在使用cout和cin时还需要搭配对应的运算符,<< 是流插入运算符,>> 是流提取运算符

并且使用是还需包含上头文件以及它们都是存放在std命名空间里的

#include<iostream>
using namespace std;
int main() {
  int a = 10;
  cout << a << endl;
  cout << "hello world" << endl;
  cin >> a;
  cout << a << endl;
  return 0;
}

cb54b2502c92656ac92540414c828ebb.png

缺省参数

缺省参数实际上就是在定义或者声明一个函数时为函数的参数指定一个值,调用函数时如果没有给函数传值那函数就默认使用缺省值

#include<iostream>
using namespace std;
int Add(int a = 10, int b = 20) {
  return a + b;
}
int main() {
    //没有传参时默认使用缺省值,因此结果为10 + 20
  int i = Add();
  cout << i << endl;
    //只传一个参数时,默认根据顺序传参因此a此时接收参数,5 + 20
  i = Add(5);
  cout << i << endl;
    //两个都传参时,5 + 5
  i = Add(5, 5);
  cout << i << endl;
  return 0;
}

98f9932f1118ccc976148e1932844fb6.png


缺省参数分类:

  1. 全缺省:也就是函数所有的参数都给定缺省值
  2. 半缺省:只有某些个参数给定缺省值,这个需要特别注意,半缺省的参数必须依照从右到左的顺序给定,也就是说如果指定某个参数为缺省值时它的右边那个参数也必须要有左边的可以没有

对于缺省参数,不能同时在声明和定义的时候存在,给定的缺省值必须是常量或者全局变量不能是局部变量

函数重载

函数重载是指一个同名的函数执行不一样的结果,也就是说同一个作用域里可以有同名的函数,这里和上面所讲的命名冲突是有区别的。

一个作用域里想要出现同名的函数必须要构载重载,而重载是有前提条件的。

同名函数的参数类型不同

同名函数的参数个数不同

同名函数的参数顺序不同

#include<iostream>
using namespace std;
//同名函数参数类型不同
int Add(int a, int b) {
  return a + b;
}
double Add(double a, double b) {
  return a + b;
}
//同名函数参数个数不同
int Reduce(int a, int b) {
  return a - b;
}
int Reduce(int a, int b, int c) {
  return a - b - c;
}
//同名函数参数顺序不同
void print(char c, int a) {
  cout << a << " " << c << endl;
}
void print(int a, char c) {
  cout << c << " " << a << endl;
}
int main() {
  cout << Add(10, 20) << endl;
  cout << Add(5.5, 4.5) << endl;
  cout << Reduce(10, 5) << endl;
  cout << Reduce(15, 5, 5) << endl;
  print('a', 10);
  print(10, 'a');
  return 0;
}


85e1226161958399d5a2a35c26f1ca6c.png

上述情况就可以构造函数的重载。

引用

引用是指给一个已有的变量取一个别名,但不是定义一个新的变量,它与它引用的那个变量共用一块内存空间。也就是说对这个引用操作也就是对那个已有变量操作。

#include<iostream>
using namespace std;
int main() {
  int a = 10;
  int& b = a;
  cout << a << "->" << b << endl;
  b = 20;
  cout << a << "->" << b << endl;
  return 0;
}

80c489e74bbdea35b0e56269cf8a329d.png

引用在定义时必须初始化

一个变量可以有多个

引用引用一旦引用一个实体,再不能引用其他实体

const变量要用const引用才可以

引用的使用场景

一个函数在传参或者返回值的过程中都需要进行拷贝的,当函数返回一个值的时,由于该值是一个局部变量除了函数后就会被销毁因为编译器会创建一个临时变量将返回值拷贝给它,然后再将临时变量的值拷贝给接收值的变量。如果这个返回值很大的时候性能就会大大降低。传参也是类似的情况,因此引用做返回值和参数的作用就出现了。

当使用引用传参时,参数就会变成传入的那个变量的别名就可以减少拷贝,修改这个引用也就会修改变量和指针类似不过指针是传入地址。做返回值时也是可以减少拷贝,返回的那个变量就是接收的那个变量的别名。

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

引用和指针的区别

在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间,但实际上在底层引用是按照真真的方式实现的是具有空间的。没有NULL引用,但有NULL指针。有多级指针,但是没有多级引用。

内联函数

调用函数是需要建立栈帧的,如果一个函数被多次调用就会多次建立栈帧开销就会很大。因此内联函数就是将函数展开变成一个函数体而不是一个单独的函数,这样就可以减少栈帧的开销提高效率。

这是一种以空间换时间的做法,会使得目标文件变大。当一个函数需要多次调用并且函数的内容不是很大时就可以使用内联函数

inline修饰的函数就是内联函数

便捷操作(C++11)

范围for

for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。

#include<iostream>
using namespace std;
int main() {
  int a[] = { 1,2,3,4,5,6 };
  for (auto e : a)
    cout << e << " ";
  cout << endl;
  return 0;
}

image.png

有迭代器的容器并且迭代的对象实现了++和==的操作都可以使用范围for

auto

有一些类型很长导致写起来容易出错,auto就可以自动识别类型。

#include<iostream>
using namespace std;
int main() {
  int a[] = { 1,2,3,4,5,6 };
  auto b = a[4];
  cout << b << endl;
  return 0;
}

9c486bc0a26aee745b13ff11e0e41dd0.png

目录
相关文章
|
1月前
|
设计模式 安全 算法
【C++ 基础】超越边界:C++中真正不受访问修饰符限制的特性
【C++ 基础】超越边界:C++中真正不受访问修饰符限制的特性
36 0
|
1月前
|
设计模式 存储 缓存
【C++ 基本概念】深入探索C++ RTTI 特性
【C++ 基本概念】深入探索C++ RTTI 特性
61 0
|
1月前
|
算法 Java 编译器
【C++ 14新特性 】C++14 数字分隔符:深入理解与实践
【C++ 14新特性 】C++14 数字分隔符:深入理解与实践
54 2
|
1月前
|
自然语言处理 编译器 C语言
【C++ 20 新特性】参数包初始化捕获的魅力 (“pack init-capture“ in C++20: A Deep Dive)
【C++ 20 新特性】参数包初始化捕获的魅力 (“pack init-capture“ in C++20: A Deep Dive)
41 0
|
1月前
|
算法 安全 编译器
【C++20 新特性Concepts 概念】C++20 Concepts: Unleashing the Power of Template Programming
【C++20 新特性Concepts 概念】C++20 Concepts: Unleashing the Power of Template Programming
47 0
|
1月前
|
存储 算法 编译器
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
47 0
|
1月前
|
Linux C++ iOS开发
【C++ 17 新特性 文件管理】探索C++ Filesystem库:文件和目录操作的全面指南(二)
【C++ 17 新特性 文件管理】探索C++ Filesystem库:文件和目录操作的全面指南
262 2
|
1月前
|
Linux API C++
【C++ 17 新特性 文件管理】探索C++ Filesystem库:文件和目录操作的全面指南(一)
【C++ 17 新特性 文件管理】探索C++ Filesystem库:文件和目录操作的全面指南
324 2
|
1月前
|
算法 网络协议 编译器
【C++ 14 新特性】C++14二进制字面量:深度探索与实践
【C++ 14 新特性】C++14二进制字面量:深度探索与实践
39 1
|
29天前
|
存储 安全 编译器
【C++】类的六大默认成员函数及其特性(万字详解)
【C++】类的六大默认成员函数及其特性(万字详解)
35 3