指针

C++ 智能指针详解

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-18 22:44:49
C++ 智能指针详解 文章目录 C++ 智能指针详解 1. 智能指针能解决什么问题? 2. 智能指针的发展 3. 智能指针 shared_ptr 3.1 创建shared_ptr实例 3.2 访问所指对象 3.3 拷贝和赋值操作 3.4 检查引用计数 3.5 reset 函数 4. 智能指针 weak_ptr 4.1 weak_ptr 的基本用法 4.2 weak_ptr 的相关函数 4.3 weak_ptr 总结 5. 智能指针 unique_ptr 6. 智能指针注意事项 1. 智能指针能解决什么问题? 在C++中,动态内存的管理是通过一对运算符来完成的: new ,在动态内存中为对象分配空间并返回一个指向该对象的指针,可以选择对对象进行初始化; delete ,接受一个动态对象的指针,销毁该对象,并释放与之关联的内存。 动态内存的使用很容易出问题,因为确保在正确的时间释放内存是极其困难的。有时会忘记释放内存,在这种情况下会产生 内存泄露 ;有时在尚有指针引用内存的情况下就释放了它,在这种情况下就会产生引用非法内存的指针。 为了更容易(同时也更安全)地使用动态内存,C++11标准库提供智能指针(smart pointer)类型来管理动态对象。 智能指针的行为类似常规指针,重要的区别是它负责 自动释放所指的对象 。 智能指针是模板类而不是指针 。类似vector

《操作系统真象还原》特权级

拥有回忆 提交于 2020-01-18 22:16:49
下面是看第五章特权级的收获 特权 简介   什么是特权?顾名思义,如果特权级别高的,就能拥有更强大的能力,能访问低特权不能访问的数据。操作系统将特权分为四层,分别为0、1、2、3,0是最高特权级别,3是最低特权级别。特权级别为0一般时由操作系统占有,特权级别1、2是由驱动程序和虚拟机占有,而用户程序一般都在特权级别3的级别下,也就是最低特权级别,能拥有的能力是最低的。 TSS   TSS是一种描述任务状态的数据结构,每一个任务都会有这样的一个结构。为什么要描述这种结构,是因为在特权级别转移的时候会用到这个结构,但TSS不仅仅用于特权级别转移,既然它是描述任务状态的,那它必然也包含任务的其它信息。   那什么是任务呢?在没有操作系统内核的情况下,任务就是进程,一段独立的程序运行起来就是一个任务;但在有操作系统的情况下,任务就不仅仅包括用户的进程了,它还包含内核程序,用户进程处于特权级别3,内核程序处于特权级别0,即一个任务是有可能从特权级别3的用户程序跳到特权级别0的内核程序的,反之亦然。   先来看看TSS的整体结构:   我们关注一下TSS结构偏移4到偏移27的三个栈指针,包括ss和esp。一个任务最多有4个栈,每个特权级别会用到一个独立的栈,但并不是每个任务都会有4个栈,因为不是每个特权级别都会用到。为什么每个特权级别的栈是独立的,而不是共用一个栈呢?这是因为如果共用一个栈

C++ 函数指针

守給你的承諾、 提交于 2020-01-18 20:29:40
一般格式: 例如: //函数声明 bool length(const string &, const string &); //函数指针 bool (*pf)(const string &, const string &); 格式: 类型名 (*pf)(形参表) 函数指针的调用: bool b1 = pf("hello","world"); bool b2 = (*pf)("hello","world"); 函数指针的赋值: pf = length; pf = &length; 来源: CSDN 作者: lun55423 链接: https://blog.csdn.net/lun55423/article/details/104032192

c++ 指针(一)

依然范特西╮ 提交于 2020-01-18 19:02:31
指针 每一个变量都有一个内存位置 ,每一个内存位置都定义了可使用连字号( & )运算符访问的地址,它 表示了在内存中的一个地址 #include <iostream> using namespace std; int main () { int var1; char var2[10]; cout << "var1 变量的地址: "; cout << &var1 << endl; cout << "var2 变量的地址: "; cout << &var2 << endl; return 0; } 结果: var1 变量的地址: 0xbfebd5c0 var2 变量的地址: 0xbfebd5b6 一、定义 指针是一个变量,其值为另一个变量的地址 ,即, 内存位置的直接地址 。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。 type *var-name; 星号是用来指定一个变量是指针 int *ip; /* 一个整型的指针 */ double *dp; /* 一个 double 型的指针 */ float *fp; /* 一个浮点型的指针 */ char *ch; /* 一个字符型的指针 */ 所有 指针的值的实际数据类型 ,不管是整型、浮点型、字符型,还是其他的数据类型, 都是一样的,都是一个代表内存地址的长的十六进制数 。

文件输入/输出

為{幸葍}努か 提交于 2020-01-18 14:48:18
一 文件是什么? 一个文件file通常就是磁盘上的一端命名的存储区。比如stdio.h就是一个包含一些有用的文件的名称。 在C语言中文件看成是连续的字节序列,其中每一个字节都可以单独地读取。 I/O级别 I/O有两个级别:低级I/O:使用操作系统提供的基本I/O服务,标准高级I/O使用一个标准的C库函数包和stdio.h头文件中的定义。 标准文件: C程序自动打开3个文件。这些文件分别称为标准输入、标准输出、标准错误输出 默认的标准输入是系统的一般输入设备,通常为键盘;默认的标准输出和标准错误输出是系统的一般输出设备,通常为显示器 用标准输入程序提供输入是很自然的事情:getchar() ;gets();scanf() 读取文件 用标准输出程序输出对象为putchar();puts();printf()输入文件 标准I/O 除了可移植性之外,标准I/O包相对低级I/O有两点优势: 第一,标准I/O包含很多专用的函数,可以方便的处理不同的I/O问题,列入printf()将各种类型的数据转换成为适合终端的字符串输出。 第二,对输入和输出进行了缓冲,也就是说大块地转移信心(通常每次不少于512个字节),而不是每次一个字节进行转移。例如,当程序读入一个文件时,会把大块数据复制到缓冲区(一块中介存储区)中。这样缓冲大大提高了数据传输率。随后程序就可以分析缓冲区中个别字节。 #include

第六周编程总结

↘锁芯ラ 提交于 2020-01-18 14:02:34
6-1 求两数平方根之和 (10 分) 函数fun的功能是:求两数平方根之和,作为函数值返回。例如:输入12和20,输出结果是:y = 7.936238。 函数接口定义: double fun (double a, double b); 其中 a和 b是用户传入的参数。函数求 a指针和b 指针所指的两个数的平方根之和,并返回和。 裁判测试程序样例: include<stdio.h> include <math.h> double fun (double a, double b); int main ( ) { double a, b, y; scanf ("%lf%lf", &a, &b ); y=fun(&a, &b); printf ("y=%.2f\n", y ); return 0; } (1)实验代码 double fun (double a, double b) { double sum; sum=sqrt( a)+sqrt( b); return sum; } (2)设计思路:首先定义浮点型 a, b,sum然后进入公式再运行,再然后结束sum。 (3)运行截图 7-1 利用指针返回多个函数值 (30 分) 读入n个整数,调用max_min()函数求这n个数中的最大值和最小值。 输入格式: 输入有两行: 第一行是n值; 第二行是n个数。 输出格式: 输出最大值和最小值

考研之数据结构(第二章总结)

笑着哭i 提交于 2020-01-18 09:55:00
1.线性表:具有相同特性数据元素的一个有限序列,该序列中所含元素的个数叫做线性表的长度。 2.逻辑特性:线性表只有一个表头元素,只有一个表尾元素,表头元素没有前驱,表尾元素没有后继。 3.线性结构包括:线性表、栈、队列、串。 4.线性表的存储结构分为:顺序存储结构和链式存储结构。 5.顺序存储:把线性表的结点按逻辑顺序依次存放在一组地址连续的存储单元里。 特性:1.随机访问特性 2.占有连续的存储空间 3.做插入操作时要移动多个元素 6.链表:一种物理储存单元上非连续,非顺序的存储结构。 特性:1.不支持随机访问 2.结点的存储空间利用率较低 3.支持存储空间的动态分布 4.做插入操作时不需要移动元素 7.顺序表与链表各自的特点: 基于空间的比较:①.存储分配方式: 顺序表的存储空间是静态分配的(一次分配) 链表的存储空间是动态分布的(多次分配) ②.存储密度(存储密度=结点值域所占的存储量/结点结构所占的存储总量) 顺序表的存储密度=1 链表的存储密度<1(因为结点中有指针域) 基于时间的比较:①.存取方式:顺序表可以随机存取,链表只能顺序存取 ②.插入/删除时移动元素的个数:顺序表平均需移动近一半的元素,链表不需要移动元素,只需要修改指针。 8.插入一个元素时所需移动元素次数的期望值(平均次数):E=1/(n+1) ∑_(i=1)^(n+1)▒(n-i+1) =n/2

一些常用的算法技巧总结

柔情痞子 提交于 2020-01-18 07:57:09
1. 巧用数组下标 数组的下标是一个隐含的很有用的数组,特别是在统计一些数字,或者判断一些整型数是否出现过的时候。例如,给你一串字母,让你判断这些字母出现的次数时,我们就可以把这些字母作为 下标 ,在遍历的时候,如果字母a遍历到,则arr[a]就可以加1了,即 arr[a]++; 通过这种巧用下标的方法,我们不需要逐个字母去判断。 我再举个例子: 问题: 给你n个无序的int整型数组arr,并且这些整数的取值范围都在0-20之间,要你在 O(n) 的时间复杂度中把这 n 个数按照从小到大的顺序打印出来。 对于这道题,如果你是先把这 n 个数先排序,再打印,是不可能O(n)的时间打印出来的。但是数值范围在 0-20。我们就可以巧用数组下标了。把对应的数值作为数组下标,如果这个数出现过,则对应的数组加1。 代码如下: public void f(int arr[]) { int[] temp = new int[21]; for (int i = 0; i < arr.length; i++) { temp[arr[i]]++; } //顺序打印 for (int i = 0; i < 21; i++) { for (int j = 0; j < temp[i]; j++) { System.out.println(i); } } } 提醒:可以左右滑动 利用数组下标的应用还有很多

函数指针及应用

China☆狼群 提交于 2020-01-18 07:24:13
函数的名字也是函数的地址所在。 在学习函数指针时发现一个问题。 # include <stdio.h> void f ( ) { printf ( "in f\n" ) ; } int main ( ) { int i ; int * p = & i ; * p = 20 ; int a [ 2 ] [ 2 ] = { 1 , 2 , 3 , 4 } ; void ( * pf ) ( void ) = f ; //声明函数指针 f ( ) ; ( * pf ) ( ) ; //老师是这样写的 pf ( ) ; //但是我这样写,函数也能正常的运行。 printf ( "%p\n" , pf ) ; printf ( "%p\n" , f ) ; system ( "pause" ) ; } 问题先记录在这,以后的学习中,解决这个问题后,再来回答。 # include <stdio.h> int plus ( int a , int b ) { return a + b ; } int minus ( int a , int b ) { return a - b ; } void cal ( int f ( int , int ) ) //void cal(int (*f)(int, int)) { printf ( "%d" , f ( 2 , 3 ) ) ; } int

c++使用智能指针需要注意的几个“坑”(C++类相关)

淺唱寂寞╮ 提交于 2020-01-18 06:58:22
1、绝对不要自己手动地管理资源 2、一个裸的指针不要用两个shared_ptr管理,unique_ptr也是,两个指针是没有关联的都会认为是只有自己在用这个资源析构的时候会出错 3、用weak_ptr打破循环引用,parent和child 4、当需要在类的内部接口中,如果需要将this作为智能指针来使用的话,需要用该类派生自enable_shared_from_this 5、使用shared_ptr作为函数的接口,如果有可能尽量用const_shared_ptr&的模式 6、多线程模式下使用shared_ptr需要注意的事项 7、shared_ptr,weak_ptr和裸指针相比会大很多,并且效率上会有影响,尤其是在多线程模式下 一个shared_ptr在空间上至少是三个裸指针的大小(24个字节),本身有引用还要配合weak_ptr使用所以要保存多少该指针的引用。如下生成既有对象的new还有本身的new ObjectPtr obj4 = obj3进行拷贝时时间效率会慢很多 可以用以下方式减少空间 8、enable_shared_from_this和shared_from_this在构造和析构中是不能使用的,在某些情况下也不能使用,因为构造的时候类还未生成好,析构的时候类快完蛋了都没有意义 9、某些情况下,会出现内存不会降的问题,尤其是使用weak_ptr来处理循环引用的问题 10