C++初阶------------------入门C++(三)

简介: C++初阶------------------入门C++(三)

C++初阶------------------入门C++(二)

https://developer.aliyun.com/article/1499032


常性

当我们如果使用使用不同的引用类型去引用一些不同类型的变量

int i = 10;
double j = i;
const double& rj = i;

如果是使用 double&就会报错,为啥? 因为我们在使用不同类型进行接收的时候,i会产生一个临时变量,(类型转变才会产生临时变量)并且这个临时变量具有常性,需要用const的变量进行接收。

指针和引用的区别

引用:

  1. 语法上,没有开辟空间,在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。
  2. 引用比指针使用起来相对更安全
  3. 没有NULL引用,但有NULL指针
  4. 有多级指针,但是没有多级引用
  5. . 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
#include<iostream>
#include<time.h>
#include<assert.h>
using std::cout;
using std::endl;
using std::cin;

int main()
{
  int c = 20;
  const int& d = c;
  cout << sizeof(d);

  return 0;
}

6. 指针语法上,开辟了空间,在底层实现上实际也是有空间的

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


两者共同点:

1.引用的底层是汇编实现的

引用表面好像是传值,其本质也是传地址,只是这个工作有编
译器来做

内联函数

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调

用建立栈帧的开销,内联函数提升程序运行的效率。

#include<iostream>
using std::cout;
using std::endl;
using std::cin;
int Add(int a, int b)
{
  return a + b;
}
int main()
{
  Add(1, 2);
  return 0;
}


这里是没有inline修饰,需要创建函数栈帧

使用inline修饰

#include<iostream>
using std::cout;
using std::endl;
using std::cin;
inline int Add(int a, int b)
{
  int c = a + b;
  return c;
}
int main()
{
  Add(1, 2);
  return 0;
}


未显示展开

要想看到展开我们需要以下操作

内联函数 优点:

  1. 可以调试
  2. 效率高,会展开
  3. 不用创建栈帧,提高效率


缺点:

不适合于大型的函数,每次调用inline修饰过的函数,就会展开一次,如果函数有100行,调用10000次,合计就要运行100 * 10000行,没有inline修饰的函数,每调用一次,就会找到相同的函数栈帧进行调用,总次数就是 100(函数的行数) + 10000(反汇编的call),所以inline修饰大型函数就会影响可执行程序的大小


inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建

议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不

是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。(简单的理解,看编译器的心情来决定展不展开)


需要注意的是,如果在其他cpp文件使用inline修饰函数,再到头文件声明,在其他cpp文件使用这个函数就会报错,因为使用inline修饰的函数在链接时不会生成符号表。这是因为inline函数在编译时会被直接插入到调用它的地方,而不会产生独立的函数代码。

day1_1.cpp

#include"day1_1.h"
int main()
{
  fun(10);
  return 0;
}

day1_2.cpp

#include<iostream>
using std::cout;
using std::endl;
using std::cin;
inline void fun(int a)
{
  cout << a << endl;
}

day_1.h

#include<iostream>
using std::cout;
using std::endl;
using std::cin;
inline void fun(int a);


所以我们使用inline修饰函数,在对当前cpp文件或者在头文件定义和声明就行了

auto

auto关键字可以用于自动推导变量的类型,让编译器根据变量的初始化表达式推导出其类型,从而简化代码书写

#include<iostream>
using std::cout;
using std::endl;
using std::cin;
int main()
{
  int a = 10;
  int* b = NULL;
  auto c = a;
  auto& d = a;
  cout << typeid(a).name() << endl;
  cout << typeid(b).name() << endl;
  cout << typeid(c).name() << endl;
  cout << typeid(d).name() << endl;
  return 0;
}


这里typeid(a).name()是返回a的类型

我们可以得出结论

  1. auto 必须初始化
  2. auto 不能当函数参数,返回值也不行
  3. auto不能声明数组


范围的for循环

与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。

前面我们学习过C语言的for循环语句,

int i = 0;
for (i = 0; i < 100; i++)
{
  printf("%d ", i);
}

但是在c++中的for语句有点差别

#include<iostream>
using std::cout;
using std::endl;
using std::cin;

int main()
{
  int a[] = { 1,2,3,4,5,6,7,8,9 };
  for (auto e : a)
  {
    cout << e << " ";
  }
  return 0;
}

意思就是遍历一遍a数组,每个元素都依次赋值给e,自动判断结束, 修改e不会修改里面的元素

如果我们要修改元素的值

#include<iostream>
using std::cout;
using std::endl;
using std::cin;

int main()
{
  int a[] = { 1,2,3,4,5,6,7,8,9 };
  for (auto& e : a)
  {
    e++;
    cout << e << " ";
  }
  return 0;
}

我们可以使用引用来进行修改

指针空值nullptr

#include<iostream>
using std::cout;
using std::endl;
using std::cin;
void func(int)
{
  cout << "f(int)" << endl;
}
void func(int*)
{
  cout << "f(int*)" << endl;
}
int main()
{
  func(0);
  func(NULL);
  return 0;
}


这里的函数只写了类型,没有写变量,这个在c++是可以的,

看到结果的人可能会发现,为啥都打印了f(int),NULL不是指针类型吗,

其实不是,在c++

NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:


如果是c++就是把NULL定义成了一个宏,C语言就是一个指针类型

所以c++就为了弥补这个错误,就写出了一个nullptr来代表NULL空指针

注意:

  1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入
    的。
  2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
  3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。
相关文章
|
2天前
|
C++ 存储 编译器
|
2天前
|
存储 算法 C语言
【C++入门到精通】C++的IO流(输入输出流) [ C++入门 ]
【C++入门到精通】C++的IO流(输入输出流) [ C++入门 ]
21 0
|
2天前
|
设计模式 安全 算法
【C++入门到精通】特殊类的设计 | 单例模式 [ C++入门 ]
【C++入门到精通】特殊类的设计 | 单例模式 [ C++入门 ]
18 0
|
1天前
|
编译器 C++
C++入门(命名空间)
C++入门(命名空间)
|
2天前
|
C++ 编译器 程序员
C++ 从零基础到入门(3)—— 函数基础知识
C++ 从零基础到入门(3)—— 函数基础知识
|
2天前
|
C++ 存储
C++从零基础到入门(2)—— (if、switch、for、while语句)
C++从零基础到入门(2)—— (if、switch、for、while语句)
C++从零基础到入门(2)—— (if、switch、for、while语句)
|
2天前
|
编译器 C语言 C++
C++入门基础-2
C++入门基础
12 3
|
2天前
|
C语言 C++
C++入门基础-1
C++入门基础
18 1
|
2天前
|
自然语言处理 编译器 C语言
【C++】C++ 入门 — 命名空间,输入输出,函数新特性
本文章是我对C++学习的开始,很荣幸与大家一同进步。 首先我先介绍一下C++,C++是上个世纪为了解决软件危机所创立 的一项面向对象的编程语言(OOP思想)。
35 1
【C++】C++ 入门 — 命名空间,输入输出,函数新特性