C++知识点

1、关键字的使用以及升级优化

1.1C与C++的区别

1.1.1都可以实现代码重用和模块化编程,但是面对对象的模块化更深,数据更封闭,也更安全!因为面向对象的封装性更强!

1.1.2面对对象的思维方式更加贴近于现实生活,更容易解决大型的复杂的业务逻辑

1.1.3从前期开发角度上来看,面对对象远比面向过程要复杂,但是从维护和扩展功能的角度上来看,面对对象远比面向过程要简单!

1.2、关键字

1.2.1 register(C)

register:提高程序运行效率:省去CPU从内存抓取数据的开销
语法作用:尽可能将变量保存在CPU内部寄存器中

使用注意事项:
只能修饰局部变量,不能修饰函数、全局变量
使用register修饰的变量,不能通过&获取该变量的地址;(有可能该变量保存在cpu内部寄存器中)
register修饰变量类型一定是CPU所能处理的数据类型;(有的cpu不支持浮点型运算)

什么时候用register修饰一个变量?(频繁访问的变量)

C++中优化:

 优化内容:当对register变量取地址时,会将该变量重新保存到内存中;

搭配使用:

1.2.2volatile :防止编译器优化(将变量优化到寄存器中(寄存器存在边际效应))

  使用场景:访问硬件时。所使用的全局变量;
           一般定义寄存器变量:volatile register int index;

1.2.3 auto(C)

 自动变量,离开作用域自动释放。

C++优化:

优化内容:auto 自动类型推导

1.2.2typedef (C):

语法作用:给数据类型重命名
工程应用:1、提高代码可读性;2、提高移植性;
 用法:typedef 数据类型 重命名
 存在一个问题:重命名函数指针时。可读性差;
 typedef 重命名函数指针:
定义:typedef 数据类型 (*重命名)(int,int); \ typedef 数据类型  ( *) (int,int) 重命名;

(额外知识点:函数命名规则:解决的是函数功能的可读性,无法解决形参的可读性;)

C++优化:

typedef == using

1.2.3 const (C):

 将一个变量变为只读变量;
 工程应用作用:修饰函数形参,保存实参在函数执行过程中不能被修改;(编译阶段处理)

类比:constexpr(预编译阶段处理)
作用:值不会改变并且在编译过程中就得到计算结果的表达式;
constexpr函数是指能用于常量表达式的函数:
constexpr int new_sz() ireturn 42}; cosntexpr int foo = new_sz();(返回值一定是一个常量)。
好处:1、是一种很强的约束,更好地保证程序的正确语义不被破坏
     2、编译器可以在编译期对constexpr的代码进行非常大的优化,比如将用到的constexpr表达式都直接替换成最终结果等。
     3、相比宏(可替代宏)来说,没有额外的开销,但更安全可靠。

C++中const的作用?
1、const声明的变量是一个真正的变量(没有自己的存储空间),无法间接被改变;
2、
3、
4、
const和define的区别:
1、const可以指定数据类型;
2、所处时期不同:denfine处于预处理阶段(文本替换)、const处于编译器处理阶段;
3、const可以用于一些复杂的数据类型:(数组或者结构体)

const 离谁近谁就不能变:eg:

C++优化:

优化内容:const 修饰的变量是常量;
修饰指针函数与C相同;

1.2.5 bool

在C语言中需要添加头文件;在C++中可直接用。
两种结果:true / false

1.2.6 三目运算符

在C++中可用
结果可以做左值;

1.2.7 while

升级了可以写逗号表达式: while(a > b, a < b)

2、类型的引用以及升级优化

2.1 引用 (C)

什么时候传地址,什么时候传值?
当修故实参变量值时,传实参变量的地址;(传实参变量的地址,即可以使用也可以修改实参变量的值)
当只使用不修改实参变量值时,传实参变量名;(传实参变量名,只能使用实参变量的值,不能修改)

注意事项:定义引用必须绑定变量;一旦绑定一个变量就不能绑定其他变量;

返回值:不要返回局部变量的地址或指针;加static可以延长使用周期(消除警告)

C++:

引用:解决就是函数指针传参和返回值问题;
引用就是给变量起别名,操作引用相当于在操作引用所绑定的变量

引用作为函数形参:解决传值和传地址问题;

常引用:只能使用不能修改其绑定的值

引用也可用于返回值:函数调用做返回值:修改返回的值;

C++11以后引用的作用被加强:(左值引用 右值引用)

左值:可以被修改的值可以叫做左值;(可以取地址的值可以作为左值)
右值:不可以被修改的值可以叫做右值;(不可以取地址的值可以作为右值)
左值引用:只能绑定左值;  int &
右值引用:只能绑定右值; int && (对象移动)

面试题的扩充(C)(everyday 2.c)

3、new/delete

3.1 C语言中(malloc/free)

malloc原型: void * malloc(size_t size);
释放原型:void free (void *addr);

C++优化(new/delete)

new、delete:暂时理解为运算符;//malloc和free 是函数
new、delete:按照类型的个数为单位; //malloc、free:按照字节为单位分配
new、delete:可以初始化;//malloc、free:只能手动初始化
(关于初始化:最好手动初始化!!默认初始化都为0);
new、delete:如果分配失败会产生异常; //malloc、free:返回NULL;
new 对应底层调用的是 malloc;
delete 底层调用的是 free;
new malloc :频繁分配(小内存空间)内存会导致内存产生碎片,同时会增加(程序)开销;
(如何解决::池化技术:内存池!!)

关于多维数据分配:
1、规则的多维数组:int (*p)[5] = new int[2][5];
2、不规则的多维数据:int (**array);

NULL的定义:(C) #define NULL (void *) 0
                          (C++) nullptr;将指针设为空

‘

可能会存在面试或笔试题:

4、函数

4.1 内联函数、内嵌函数

4.1.1 在 C

inline:修饰的函数为内联函数、内嵌函数;
空间(内存空间)、时间(编译时间、运行时间)
以时间换空间:消耗了更多编译/运行时间,换取占用更小的内存    (宏函数)
以空间换时间:占用更多的内存空间,换取运行时间    
(inline 内联函数/内嵌函数   改变了函数调用的处理过(将函数体的内容内嵌到函数调用的地方)
内联的限制:1、内联函数中不可含有循环;
           2、内联函数中不可能含有静态变量;
           3、;内联函数不可为:递归函数;
           4、内联函数中不可含有错误处理。
  **注意事项**:内联函数的定义必须在第一次内联函数调用之前;

eg1:宏函数

处理阶段:预处理阶段
处理过程:傻瓜式替换 (没有空间分配) 不做语法检查!! 不安全

eg2:自定义函数
处理阶段:编译时检查语法、运行时函数进栈出栈;
处理过程:通过函数名找到函数的入口地址; 给形参分配空间; 传值; 执行函数体语句; 函数返回; 释放空间;

C++中:

inline:编译决定是否为内联处理
函数的默认参数:如果一个函数的参数为默认参数,那么它右边(后面)所有参数都必须为默认参数;
函数的占位符:预留函数接口
函数的重载:函数名命名的可读性问题;
函数重载的条件:1、函数形参的个数不同;
              2、函数形参个数相同类型不同;
              3、函数形参类型不同顺序不同;
              函数的个数、类型、顺序不同!!!
注意事项:函数的返回值不能作为重载条件;函数默认参数会影响重载条件;

演示:(错误写法)

正确写法:

5、结构体

C++在C中的升级

1、可以省略在主函数中struct的声明;
2、可以在struct中定义函数;
3、可以对成员加入访问权限;
public(公有的):可以直接在外部访问;
private(私有的):只能在结构体内部使用或者内部函数直接访问,不能在外部访;
protected(保护的):只能在结构体内部使用或者函数内部直接访问,不能在外部访问;
访问权限好处:隐藏了数据(封装)

如何对private/protected成员设置值?   提供set/get方法;

**struct**的升级目的是为了引入**class**(类);

程序代码结构1: 在类里定义和实现方法:这些方法有可能会已inline处理

程序结构2: .h类的定义声明,不在类内去实现方法,编译器不会将方法用inline

struct 和 class 的区别

叫法1: struct 结构体class类struct定义的变量是结构体变量;class定义的变量称之为对象;
叫法2: struct/class :变量称之为属性或者是成员变量;   函数称之为方法;
默认访问权限: struct默认的是public ;     class 默认的是 private

6、string类 (替代C中字符串的操作)

6.1 定义

6.2 获取属性

6.2.1

6.2.2 (长度)
1、获取字符串的大小;
2、有多少字符;
3、当前string的容量;它的值总是会比size()大一个或者多个;
4、当前环境最多可容纳多少字符; 注意:string可变长!!!!

6.3 遍历

6.3.1

第一个输出:[ ] 运算符: 越界不报错 不安全
第二个输出:at(int index) :如果访问越界, 会产生异常, 安全!!
eg:

6.3.2 迭代器遍历

6.4 连接

1、通过append 进行字符串的连接;
2、直接通过变量名进行连接;
3、通过迭代器进行连接;

6.5 赋值

在这里插入图片描述

6.6 比较

在这里插入图片描述

6.7 提取子串

s.substr(a,b); (a为你从子串哪里开始计数,b为需要提取多少)

6.8 交换

6.9 查找


6.9.1查找一个字符串里某个字符的位置

查找到返回该值下标,查不到返回其他

6.9.2

6.10 替换

6.11 插入

6.12 删除

注意事项:::最好不要在迭代器遍历中进行插入或者删除,因为这样会导致迭代器失效;

6.13 string类的迭代器处理

7、vector

一定要注意加载头文件#include <vector>
以后尽量都用vector 容器来定义数组
也可以定义很多类型


7.1 在vector 的末尾添加/删除数据

 v.push_back(int n);  //在末尾添加数据
 v.pop_back(int n);   // 在末尾删除数据
 注意一定是在**末尾**

在这里插入图片描述

7.2 在中间插入或者删除

v.insert(位置,int n);   //在中间某个位置插入一个数据
v.erase(位置,int n);  //在中间删除某个数据
注意是在**中间**进行操作;

在这里插入图片描述

8、类型转换

8.1 在C语言中

1、隐式转换: char -- int -- double -- float -- long
eg: int num = 'a';    double b = num;
2、显式转换(强制类型转换):(type) 变量名
eg: char *ptr = (char *)malloc(sizeof(char *) * 100);

8.2 C++优化

C++为什么提出新的类型转换运算符?
C语言类型转换是个不安全转换(任意类型转化,不检查)

8.3 static_cast

1、可以转换::相关类型(int、float这些基本转换);父类与子类;void *与其他类型指针的转换
2、任意两个类型的指针之间转换不能用static_cast;

8.4 reinterpret_cast

C++中强制类型转换;可以达到任意类型转换,但是不检查错误;建议少用,不安全。


8. 5 const_cast(去掉const的属性)

1、允许非const赋值给const; 不允许const赋值给非const;(会改变const的值)
2、const_cast  只能去除指针或者引用的const属性;

8.6 d’ynamic_cast(多态)

与static_cast 用法大致相同;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Geminikzx

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

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

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

打赏作者

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

抵扣说明:

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

余额充值