指针

简单讲述我对指针和结构体的一些理解

时光总嘲笑我的痴心妄想 提交于 2020-02-27 03:05:49
大家可以写几行代码好好想想这些东西。编译出来看就很好理解了。 指针概述 指针在C语言可以理解为一个对象,利用地址,她的值直接向存在电脑内存储存器中的另一个地方的值。可以说,地址指向该单元变量,所以将地址形象化的称为“指针”。我们可以理解为指针是个变量,存放内存单元的地址。指针是一个存放地址的变量。 指针的大小在32位平台是四个字节,在64位平台是八个字节。 指针类型 指针一般存放什么类型的变量,指针就定义为什么类型。 eg: int* char* flaot* /等等都可以定义指针变量 指针类型的意义就在于当指针±整数时,决定指针向前或者向后走一步的距离有多大(地址的变化) 指针类型也同样决定了,对指针解引用的时候有多大的权限(可以操作几个字符).char* /的指针解引用只可以访问一个字节,而int* /的指针的解引用就可以访问四个字节。 野指针 野指针可以理解为错误的使用指针。使指针指向的位置是不可知的。 规避野指针出现的方法:指针初始化;小心指针越界;指针指向空间释放即使置NULL;指针使用之前检查其有效性。 指针与数组 int arr[10] = {1,2,3,4,5,6,7,8,9,10}; int* p = arr; 数组名表示的是数组首元素的地址。 可以直接通过指针来访问数组。 二级指针 int a = 10; int *pa = &a; int **ppa =

C++ | 智能指针再探

≡放荡痞女 提交于 2020-02-27 02:55:40
上篇博客我们模拟实现了 auto_ptr 智能指针,可我们说 auto_ptr 是一种有缺陷的智能指针,并且在C++11中就已经被摈弃掉了。那么本章我们就来探索 boost库和C++11中的智能指针以及其实现方法。 文章目录: 一、独占型智能指针 scope_ptr 二、强 智能指针shared_ptr 三、弱 智能指针 weak_ptr 准:在本文中模拟的智能指针并不与库中的智能指针的实现完全相同,只是为了通过探究其实现原理而进行的一种模拟。 一、独占型智能指针 scope_ptr 在 boost中有一种 scope_ptr 指针,可以说这是boost库中最为简单的一种智能指针了。相对于前两种智能指针而言, scope_ptr 规定,一个智能指针只能引用一块堆内存,当这个指针的作用域消失之后自动释放。 scope_ptr 实现起来很简单,只需要将拷贝构造函数和赋值函数的接口屏蔽起来即可。 template < typename T > class Scope_ptr { public : Scope_ptr ( T * ptr ) { m_ptr = ptr ; } ~ Scope_ptr ( ) { delete m_ptr ; m_ptr = NULL ; } T & operator * ( ) { return * m_ptr ; } T * operator - > (

C语言实现反转链表 II(指定2个节点反转)

人走茶凉 提交于 2020-02-27 00:50:34
要求: 反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。 说明: 1 ≤ m ≤ n ≤ 链表长度。 示例: 输入: 1->2->3->4->5->NULL, m = 2, n = 4 输出: 1->4->3->2->5->NULL 方法迭代链接反转 算法 在看具体算法之前,有必要先弄清楚链接反转的原理以及需要哪些指针。举例而言,有一个三个不同结点组成的链表 A → B → C,需要反转结点中的链接成为 A ← B ← C。 假设我们有两个指针,一个指向结点 A,一个指向结点 B。 分别记为 prev 和 cur。则可以用这两个指针简单地实现 A 和 B 之间的链接反转: cur.next = prev 这样做唯一的问题是,没有办法继续下去,换而言之,这样做之后就无法再访问到结点 C。因此,我们需要引入第三个指针,用于帮助反转过程的进行。因此,我们不采用上面的反转方法,而是: third = cur.next cur.next = prev prev = cur cur = third 迭代 地进行上述过程,即可完成问题的要求。下面来看看算法的步骤。 1.如上所述,我们需要两个指针 prev 和 cur。 2.prev 指针初始化为 None,cur 指针初始化为链表的 head。 3.一步步地向前推进 cur 指针,prev 指针跟随其后。 4.如此推进两个指针,直到

C#实现平衡多路查找树(B树)

自古美人都是妖i 提交于 2020-02-26 23:22:03
原文: C#实现平衡多路查找树(B树) 写在前面:搞了SQL Server时间也不短了,对B树的概念也算是比较了解。去网上搜也搜不到用C#或java实现的B树,干脆自己写一个。实现B树的过程中也对很多细节有了更深的了解。 简介 B树是一种为辅助存储设计的一种数据结构,在1970年由R.Bayer和E.mccreight提出。在文件系统和数据库中为了减少IO操作大量被应用。遗憾的是,他们并没有说明为什么取名为B树,但按照B树的性质来说B通常被解释为Balance。在国内通常有说是B-树,其实并不存在B-树,只是由英文B-Tree直译成了B-树。 一个典型的 B树如图1所示。 图1.一个典型的B树 符合如下特征的树才可以称为B树: 根节点如果不是叶节点,则至少需要两颗子树 每个节点中有N个元素,和N+1个指针。每个节点中的元素不得小于最大节点容量的1/2 所有的叶子位于同一层级(这也是为什么叫平衡树) 父节点元素向左的指针必须小于节点元素,向右的指针必须大于节点元素,比如图1中Q的左指针必须小于Q,右指针必须大于Q 为什么要使用B树 在计算机系统中,存储设备一般分为两种,一种为主存(比如说CPU二级缓存,内存等),主存一般由硅制成,速度非常快,但每一个字节的成本往往高于辅助存储设备很多。还有一类是辅助存储(比如硬盘,磁盘等),这种设备通常容量会很大,成本也会低很多,但是存取速度非常的慢

C++笔记(3):一些C++的基础知识点

99封情书 提交于 2020-02-26 23:05:08
前言: 找工作需要,最近看了下一些C++的基本概念,为范磊的 《零起点学通C++》,以下是一些笔记。 内容:   delete p;只是删除指针p指向内存区,并不是删除指针p,所以p还是可以用的。删除空指针所指向内存是可以的。   堆中的变量和对象时匿名的,没有名称,只能通过指针来访问。   在堆中创建对象时,在分配内存的同时会调用类的构造函数,在删除堆中对象时,会调用类的析构函数。   为了避免内存泄露,在删除一个指针后应该将其其值赋为0。   常量指针是指针指向的内存区域地址不能改变,但是该内存地址里保存的值是可以改变的,比如int a; int * const p = &a;   指向常量的指针表示指针指向的对象是不能被修改的,但是该指针可以被修改,即该指针可以指向另一块目标内存地址。比如const int a = 0; const int *p = &a; 如果A是一个类,也可以为const A* p = new A;   而指向常量的常指针表示指针本身不能被修改,其指向的内存地址内容也不能被修改。比如const int a = 0; const int * const p = &a;   引用就是别名常量。   堆中的地址是用指针来操作的,用不到别名。   如果在main函数前面的其它函数的声明和定义是一起的,则表明这个函数是内联函数!因此当该函数较长时

Typedef函数指针?

守給你的承諾、 提交于 2020-02-26 22:57:02
我正在学习如何动态加载DLL,但我不明白的是这一行 typedef void (*FunctionFunc)(); 我有几个问题。 如果有人能够回答他们,我将不胜感激。 为什么要使用 typedef ? 语法看起来很奇怪; 在 void 之后,应该没有函数名称或其他名称吗? 它看起来像一个匿名函数。 是否创建了函数指针来存储函数的内存地址? 所以我现在很困惑; 你能为我澄清一下吗? #1楼 #include <stdio.h> #include <math.h> /* To define a new type name with typedef, follow these steps: 1. Write the statement as if a variable of the desired type were being declared. 2. Where the name of the declared variable would normally appear, substitute the new type name. 3. In front of everything, place the keyword typedef. */ // typedef a primitive data type typedef double distance; // typedef

链表中的双指针

戏子无情 提交于 2020-02-26 18:39:30
1、两个链表的第一个公共结点 输入两个链表,找出它们的第一个公共结点。 当不存在公共节点时,返回空节点。 思路 :让两个指针分别走一遍两个链表,交点就是公共节点: /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *findFirstCommonNode(ListNode *headA, ListNode *headB) { ListNode* p1 = headA, *p2 = headB; while(p1 != p2){ p1 = p1? p1->next:headB; p2 = p2? p2->next: headA; } return p1; } }; 来源: https://www.cnblogs.com/Aliencxl/p/12368147.html

C语言指针变量的定义和使用

时间秒杀一切 提交于 2020-02-26 16:33:46
指针变量的含义 数据在内存中的地址也称为指针,如果一个变量存储了一份数据的指针,我们就称它为指针变量 。 在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。指针变量的值就是某份数据的地址,这样的一份数据可以是数组、字符串、函数,也可以是另外的一个普通变量或指针变量。 定义指针变量 定义指针变量与定义普通变量非常类似,不过要在变量名前面加星号*,格式为: datatype * name ; 或者 datatype * name = value ; *表示这是一个指针变量,datatype表示该指针变量所指向的数据的类型 。例如: int * p1 ; p1 是一个指向 int 类型数据的指针变量,至于 p1 究竟指向哪一份数据,应该由赋予它的值决定。再如: int a = 100 ; int * p_a = & a ; 在定义指针变量 p_a 的同时对它进行初始化,并将变量 a 的地址赋予它,此时 p_a 就指向了 a。值得注意的是,p_a 需要的一个地址,a 前面必须要加取地址符&,否则是不对的。 指针变量也可以被多次写入,只要你想,随时都能够改变指针变量的值,请看下面的代码: //定义普通变量 float a = 99.5 , b = 10.6 ; char c = '@' , d = '#' ; //定义指针变量 float * p1 = & a ; char *

22.链表中倒数第k个节点

烂漫一生 提交于 2020-02-26 15:51:06
我的第一次做法是两次遍历,第一次找到总个数,然后总数减去k就是正着数的位置,但是这道题还有一次遍历就能实现的方法,也就是快慢指针,让快指针先走n步,满指针再走,这样的话当快指针为空时刚好慢指针到的目标位置 代码如下: 剑指offer中提到了鲁棒性这个东西,我觉得是该关注下,所以加上了, 因为可能没有k那么大 来源: CSDN 作者: qq_40058686 链接: https://blog.csdn.net/qq_40058686/article/details/104516728

C++变量和基本类型知识概要总结

烂漫一生 提交于 2020-02-26 15:38:40
整合基本的关于c++的变量和基本类型的知识。参考于C++primer第二章 仅包含部分,而非全部 inti=b; //i的值为1 i= 3.14; //i的值为3 double pi = i; // pi的值为3.0 unsigned char C = - 1; //假设char占8比特,c的值为255 signed char c2 = 256; //假设char占8比特,c2的值是未定义的 注意:当我们赋给无符号类型一个超过它表示范围的值时,结果就是初始值对无符号类型所表示的数值总值取模后的余数。 举个清新易懂的例子 例如:八比特大小的unsigned char 可以表示0至255区间内的值,如果赋了一个区间以外的值,则实际值就是该值对256取模后所得的余数。-1赋值给unsigned char的结果时255. 但是 !!赋值给有符号类型超过它表示范围的值时,结果就是未定义的。程序可能继续工作,可能崩溃,也可能产生垃圾数据。 int类型的加了一个无符号值时,int会先变成无符号类型然后再操作。 若两个无符号相减后变成负数了,结果会是取模后的值 ‘A’ 和 "A"是有区别的,'A’就是一个单独的字符A,而"A"则代表了一个字符的数组,包含两个字符,一个是字母A ,另一个是空字符。 对于C++程序员来说,变量和对象一般可以互换使用 初始化不是赋值