C & C++ 复习笔记

1 篇文章 0 订阅
1 篇文章 0 订阅

这篇文章主要是我复习一些C和C++时记录的一些知识点,以备不时之需,常常浏览,温故而知新~

union和struct

union为联合体、共用体,而struct为结构体;他们的相同点是:都可以包含多种数据类型。具体的使用规则见:联合体;其实从名字上已经可以看出来,联合体就是在内存开辟一个空间,它的大小跟联合体里面最大的数据类型一样,举个例子,我定义了一个书包,书包可以放电脑和书和其他东西,书包的大小由电脑决定,电脑多大,书包就多大,因为一般来说,电脑是书包能够容纳的最大物品。而对于结构体,它的大小则是按照一定的对齐方式,所有数据类型大小的“总和”;这里的对齐是指每个数据类型都要对齐,比如你定义了如下数据类型:

struct stu{
    char sex;
    char name[10];
}

如果是按四字节对齐方式,请问上面的结构体的大小是多少?答案是16,char类型占一个字节,但是要对齐所以后面三个字节为空。同理name数组后面需要空两个字节,因此大小为4+12=16。

命名空间

命名空间是解决命名冲突的。详见:using namespace std 到底是什么意思

类型转换

当我们赋值给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数,比如:

unsigned char c = -1;//假设char占一个字节,则c的值为255

当我们赋值给带符号类型,如果这个数大于它能够表示的范围,结果是未定义的。此时程序可能继续工作,可能崩溃,可能生成垃圾数据。
实际上,char类型究竟是有符号还是无符号有编译器决定,因此,考虑到可移植性,不要在算术表达式使用char或者bool(会转化成整形,非0即1)。

变量


初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来代替。

  • 变量的初始化

    列表初始化:用一个花括号来初始化变量,如果出现丢失信息的风险,编译器将会报错:double pi = 3.1415926; int a{pi};//错误,转换不会执行
    默认初始化:如果定义变量时没有指定初值,则变量被默认初始化。定义在函数体外的内置类型对象如果没有初始化,其值未定义。定义在函数体外部的内置类型变量转化为0.类的对象如果没有显示初始化,则其值由类本身确定(由类的构造函数定义)。

  • 变量的声明和定义

    变量声明规定了变量的类型和名字,在这一点上定义与之相同。但是除此之外,定义还申请存储空间,也可能会为变量赋一个初始值。任何包含显式初始化的声明即成为定义:extern int i = 2;//定义

引用和指针


  • 引用

引用是一个已经存在的对象(不可以是字面值)的别名;引用本身不是对象,不能对引用进行引用;定义引用必须初始化,程序将会把引用和它的初始值一直绑定在一起;而且一般来说,引用类型必须跟与之绑定的对象严格匹配。但是,也有例外:其一是在初始化常量引用时允许用任意表达式作为初始值( const int &r = 42*2;);其二是可以将基类的引用绑定到派生类对象上。
int val = 1;
int &refVal = val; //refVal 是val的小名
int &ref; //报错,引用必须初始化
double &ref1 = val; //错误,类型必须严格匹配

虽然引用和指针都提供间接访问对象的功能,但是指针不同于引用,指针是一个变量,可以更改指针所指的对象,使用指针最好是有效指针(指向实际的对象);还有一个怪胎就是void指针,它可以存放任意的数据类型的地址,但是不能操作void*指针所指的对象,因为无法知道这个对象的类型。
在C语言中没有引用的概念,引用是C++提出来的;既然指针和引用都能够对一个对象进行间接访问,那为什么还要使用引用呢?直接使用指针不就好了吗?引用是怎么实现的?
下面本人做出解答:
引用实质上就是被引用对象的地址。在编译的时候,指针变量的地址是和指针所指向对象的地址不同,指针变量的值才跟指向对象的地址相同。而引用的地址就是被引用对象的地址,引用的值就是被引用对象的值。因此一般说来,引用是不占用内存空间的,也不存在引用的引用,引用声明的时候必须初始化。而指针是一个对象实体,占用内存空间,存在指针的指针,指针在声明的时候可以不初始化,也可以为NULL。因此,可以把引用看成是只允许内容存取的指针。

引用存在的理由:

  1. 当你看别人的代码的时候,有时觉得变量名的含义不清晰,可以声明一个含义更清晰地引用,然后再对引用进行操作。(这个好像用一个全局替换就可以了==)
  2. 虽然引用和指针都能够用来传递实参和返回结果,并且能够避免拷贝,但是引用使用起来跟优雅一些。因为指针需要解引用操作来更改实参的值,但是引用是自动间接寻址来更改实参的值。实质上,按指针传参也是通过按值传参的方式实现的,它传的是一个地址值,在栈上实际保存的是指针变量的副本,实际上可以改变的是指针指向对象的值,但是指针变量本身的值是不会变的。按引用传参则不同,虽然在栈上同样开辟空间,但是存放的是实参变量的地址,被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

参考链接1
参考链接2
参考链接3.

数组和链表的优缺点

数组的优缺点:元素值的存取操作方便,节省空间。增删操作费时,大小固定。
链表的优缺点:元素的增删操作方便,可以组织成更为复杂的数据结构:树,图。扩展性比较好,大小可以随意增加。但是元素值的存取和查找操作费时,耗费空间。
结合数组和链表的优点的数据结构:解决哈希表冲突使用链地址法使用的结构:总体是一个数组,数组的元素是一个指针,指向一个链表。

delete 和 delete [] 的区别

具体要看delete的对象类型:
(1)delete的是内置数据类型的数组,没有区别。
(2)delete的是自定义的数据类型的数组,则delete将会只调用一次析构函数,对数组首元素进行析构,而其他的元素则没有,因此会造成内存泄露。而delete []则会把所有对象析构,然后释放空间,比较安全。
参考链接:具体的工作原理。

c++程序运行时的三种内存分配策略

(1)静态存储分配:在编译的时候就可以确定对象在运行时刻的空间大小,因此在编译时就可以给他们分配固定的内存空间。
(2)栈式存储分配:在编译的时候未知,只有在程序运行的时候才能够知道大小。栈的分配和释放有编译器自动管理,栈空间比较小,栈不存在碎片问题,一般来说能够用栈最好用栈。(函数的局部变量存放在栈区)
(3)堆式存储分配:在编译时或运行时都无法确定存储要求的数据结构的内存分配。堆由大片的可利用的块组成,堆中的内存都可以按任意书序分配和释放。堆需要程序员自己控制,空间比较大,不停的分配和释放会带来碎片的问题,效率比较低,但是堆非常灵活,需要谨慎使用。(使用new分配的内存块都在堆里。)
C++内存管理详解

weixin063传染病防控宣传微信小程序系统的设计与实现+springboot后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值