指针

27.移除元素

若如初见. 提交于 2019-12-20 23:10:02
27.移除元素 法1 双指针 题目要求我们就地删除给定值的所有元素,我们必须用O(1)的额外空间来处理它,我们可以保留两个指针i和j,其中i是慢指针,j是快指针 class Solution { public int removeElement ( int [ ] nums , int val ) { int i = 0 ; for ( int j = 0 ; j < nums . length ; j ++ ) { if ( val != nums [ j ] ) { nums [ i ] = nums [ j ] ; i ++ ; } } return i ; } } 执行用时 :0 ms, 在所有 java 提交中击败了100.00%的用户 内存消耗 :35.5 MB, 在所有 java 提交中击败了84.23%的用户 来源: CSDN 作者: 啾啾啾九日 链接: https://blog.csdn.net/weixin_40840854/article/details/103638162

期末复习——头插和尾插法的再次复习

*爱你&永不变心* 提交于 2019-12-20 20:26:26
之前一直习惯用尾插法,因为尾插法更符合我自己的逻辑,每次看到别人使用头插法的时候也不是不能理解,就是感觉不舒服,今天再次来复习一下头插法和尾插法, 1.头插法 故名思议,从链表头部不断插入,然后将头指针不断后移,这样插入导致的结果就是输出的时候和输入的顺序相反。 头指针被只是被声明,开辟了一个四个字节的指针变量用来存地址,在头插法中,这个是头指针,而在尾插法中,我更愿意认识是头结点。因为在尾插法中我们用头结点的指针域不断的去存下一个节点的地址。 下面给出头插法的代码 PNODE creat() { PNODE Head=NULL; int n,i,val; cout<<"请输入链表长度:"; cin>>n; for(i=0;i<n;i++) { PNODE pNew=new NODE;//开辟新节点 cout<<"请输入第"<<i+1<<"个节点的值:"; cin>>val; pNew->data=val;//将值存入数据域 //头插 pNew->pNext=Head; Head=pNew; } return Head; } 在尾插法中,会多出来一个节点,这个节点就是头节点,它是一个结构体指针变量,用指针域存下一个节点的起始位置,在逻辑思维上,我更习惯这个尾插法。 //尾插 PNODE creat()//尾插法 { PNODE Head=new NODE;//造一个头节点

C++ 11 相关的智能指针详解

折月煮酒 提交于 2019-12-20 19:40:16
本文介绍c++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三个是c++11支持,并且第一个已经被c++11弃用。 为什么要使用智能指针:我们知道c++的内存管理是让很多人头疼的事,当我们写一个new语句时,一般就会立即把delete语句直接也写了,但是我们不能避免程序还未执行到delete时就跳转了或者在函数中没有执行到最后的delete语句就返回了,如果我们不在每一个可能跳转或者返回的语句前释放资源,就会造成内存泄露。使用智能指针可以很大程度上的避免这个问题,因为智能指针就是一个类,当超出了类的作用域是,类会自动调用析构函数,析构函数会自动释放资源。下面我们逐个介绍。 auto_ptr ( 官方文档 ) #include<iostream> #include<memory>//auto_ptr的头文件 using namespace std; class Test { public: Test(string s) { str = s; cout<<"Test creat\n"; } ~Test() { cout<<"Test delete:"<<str<<endl; } string& getStr() { return str; } void setStr(string s) { str = s; }

用指针方法排序数组

若如初见. 提交于 2019-12-20 13:50:09
#include <stdio.h> #include <stdlib.h> //将一维数组中10个数按大到小的顺序排列输出 int main() { void sort(int x[],int n); //void sort(int *x,int n) int i,x[10]; int *p; p=x; for(i=0;i<10;i++) scanf("%d",p++); p=x; sort(p,10); p=x; for(i=0;i<10;i++) printf("%d ",*(p++)); return 0; } void sort(int x[],int n) //void sort(int *x,int n) { int i,j,t; for(i=0;i<n;i++) { for(j=i;j<n;j++) { //if(*(x+j)>*(x+i)) { t=x[j],x[j]=x[i],x[i]=t; //t=*(x+j),*(x+j)=*(x+i),*(x+i)=t; } } } } *(x+j)就是x[j]; 来源: https://www.cnblogs.com/webmen/p/5739687.html

python文件打开的几种访问模式

故事扮演 提交于 2019-12-20 11:50:10
文件打开的几种访问模式 访问模式 说明 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 r+ 打开一个文件用于读写。文件指针将会放在文件的开头。 w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 ab+

Java内存结构

风格不统一 提交于 2019-12-20 11:48:27
转载: 原文链接: https://blog.csdn.net/qq906627950/article/details/81324825 运行时数据区 JVM所管理的内存包括以下几个运行时数据区域,如图所示 方法区和堆为线程共享区,虚拟机栈、本地方法栈及程序计数器为线程独占区。 程序计数器 程序计数器是一块较小的空间,它可以看作是当前线程所执行的字节码的行号指示器。 如果线程执行的是java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址(可以理解为上图所示的行号),如果正在执行的是native方法,这个计数器的值为undefined。 JVM的多线程是通过线程轮流切换并分配CPU执行时间片的方式来实现的,任何一个时刻,一个CPU都只会执行一条线程中的指令。为了保证线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各线程间的程序计数器独立存储,互不影响。 此区域是唯一一个在java虚拟机规范中没有规定任何OutOfMemoryError情况的区域,因为程序计数器是由虚拟机内部维护的,不需要开发者进行操作。 虚拟机栈 每个线程有一个私有的栈,随着线程的创建而创建,生命周期与线程相同。 虚拟机栈里面存着的是一种叫“栈帧”的东西,每个方法会创建一个栈帧,栈帧中存放了局部变量表、操作数栈、动态链接、方法出口等信息。

冒泡排序与指针结合

不羁岁月 提交于 2019-12-20 10:37:34
冒泡与选择排序为C语言排序经典,以下为经典样例,供读者参考 # include <stdio.h> //选择排序 void select ( int a [ ] , int n ) { int i , j ; for ( int j = 1 ; j < n - 2 ; j ++ ) for ( int k = j + 1 ; k < n - 2 ; k ++ ) { if ( a [ j ] > a [ k ] ) //升序 { int t ; t = a [ k ] ; a [ k ] = a [ j ] ; a [ j ] = t ; } } } //冒泡 void pro ( int a [ ] , int n ) { int i , j , k , t ; for ( int j = 1 ; j <= n ; j ++ ) for ( int k = 1 ; k <= n - j ; k ++ ) { if ( a [ k + 1 ] > a [ k ] ) { int t ; t = a [ k ] ; a [ k ] = a [ k + 1 ] ; a [ k + 1 ] = t ; } } } //冒泡的指针算法 void zhizhen ( int * b , int n ) { int i , j , k , * p ; for ( j = 0 ; j <= n

C++ typedef用法小结

£可爱£侵袭症+ 提交于 2019-12-20 09:33:09
一、typedef的四个用法 用法一: 为复杂的声明定义一个新的简单的别名。方法是:在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。举例: 1. 原声明:int *(*a[5])(int, char*); 变量名为a,直接用一个新别名pFun替换a就可以了: typedef int *(*pFun)(int, char*); 原声明的最简化版: pFun a[5]; 2. 原声明:void (*b[10]) (void (*)()); 变量名为b,先替换右边部分括号里的,pFunParam为别名一: typedef void (*pFunParam)(); 再替换左边的变量b,pFunx为别名二: typedef void (*pFunx)(pFunParam); 原声明的最简化版: pFunx b[10]; 3. 原声明:doube(*)() (*e)[9]; 变量名为e,先替换左边部分,pFuny为别名一: typedef double(*pFuny)(); 再替换右边的变量e,pFunParamy为别名二 typedef pFuny (*pFunParamy)[9]; 原声明的最简化版: pFunParamy e; 理解复杂声明可用的“右左法则”: 从变量名看起,先往右,再往左,碰到一个圆括号就调转阅读的方向

【逆向知识】动态调试技巧-C++代码逆向

为君一笑 提交于 2019-12-20 09:08:08
1、C++类代码的特点 寄存器ECX传参时一般用作this指针(对象地址)或是计数器。 有ecx传参的call,是成员函数,构造函数,析构函数 能访问成员变量的函数都会有ecx传参 静态函数、全局函数无ecx(this指针) 返回值 寄存器eax一般用作返回值 识别构造函数的OD反汇编代码 特点: (1) 代码特点:没有返回值、用于初始化 (2)反汇编特点:有返回值,而且是this指针 根据反汇编可以看出成员变量的顺序,因为在内存数据中的排布顺序是由代码中成员变量定义顺序决定的。 识别构造函数的办法: (1)构造函数调用时,会使用ECX用于this指针 (2)构造函数在反汇编层有返回值,是eax存放this指针 (3)构造函数用于初始化,一般内存如果是未初始化的比如CCCCCCC,经过构造函数会完成初始化。 (4)如果一个函数有对前4字节初始化为一个指针地址,那么可能是在初始化虚函数表指针。 如果一个类有虚函数,那么对象的内存数据里会有虚函数指针的定义。构造函数会初始化虚函数表指针,而类中定义多少个虚函数也只有一个虚函数表指针。 识别成员函数的OD反汇编代码 特点: (1)ECX传递this指针,调用成员函数 (2)成员函数中会访问exc所指向的内存空间 成员函数与虚函数本身没有什么区别,所以反汇编出来的代码都差不多。 识别成员函数: (1)如果找到了构造函数

c++类型转换Type Cast)

删除回忆录丶 提交于 2019-12-20 09:02:15
C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是: TYPE b = (TYPE)a。 C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。 const_cast,字面上理解就是去const或volatile属性。 static_cast,命名上理解是静态类型转换 。如int转换成char。 dynamic_cast,命名上理解是动态类型转换。如子类和父类之间的多态类型转换。 reinterpret_cast,仅仅重新解释类型,但没有进行二进制的转换 。 4种类型转换的格式,如:TYPE B = static_cast<TYPE>(a)。 const_cast 去 掉类型的const或volatile属性。 struct SA { int i; }; const SA ra; //ra.i = 10; //直接修改const类型,编译错误 SA &rb = const_cast<SA&>(ra); rb.i =10; Syntax const_cast < new_type > ( expression ) Returns a value of type new_type . Explanation Only the following conversions can be done with const_cast . In