c语言指针

NULL和nullptr和nil和Nil还有NSNull

吃可爱长大的小学妹 提交于 2019-11-28 22:28:32
NULL和nullptr 在Clang 6.0 的stddef.h文件中可以找到NULL和nullptr的声明: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #undef NULL #ifdef __cplusplus # if !defined(__MINGW32__) && !defined(_MSC_VER) # define NULL __null # else # define NULL 0 # endif #else # define NULL ((void*)0) #endif #ifdef __cplusplus #if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED) namespace std { typedef decltype(nullptr) nullptr_t; } using ::std::nullptr_t; #endif #endif 早在1972年,C语言诞生的初期,常数0带有常数及空指针的双重身分。 C使用preprocessor macro NULL表示空指针,让NULL及0分别代表空指针及常数0。 NULL可被定义为((void*)0)或是0。 C++并不采用C的规则,不允许将void*隐式转换为其他类型的指针。为了使代码char*

C++基础

假装没事ソ 提交于 2019-11-28 21:36:32
静态多态和动态多态优缺点 avl树与红黑树的效率 实际上红黑树的查找大约需要logN次比较, 并且查找不可能超过 2*logN 次比较. 插入和删除的时间要增加一个常数因子, 因为不得不在下行的路径上和插入点执行颜色变化和旋转. 平均起来, 一次插入大约需要一次旋转. 因此插入的时间复杂度还是O(logN), 但是比在普通的二叉搜索树中要慢 avl树查找的时间复杂度为O(logN), 因为树一定是平衡的. 但是, 由于插入或删除一个节点时需要扫描两趟树, 一次向下查找插入点, 一次向上平衡树 AVL树保持每个结点的左子树与右子树的高度差至多为1, 从而可以证明树的高度为O(log(n)). Insert操作与delete操作的复杂度均为log(n), 旋转操作可能会达到log(n)次 avl树不如红黑树效率高, 也不如红黑树常用 有了avl树为什么还需要红黑树 1、红黑树放弃了追求完全平衡, 追求大致平衡, 在与平衡二叉树的时间复杂度相差不大的情况下, 保证每次插入最多只需要三次旋转就能达到平衡, 实现起来也更为简单. 2、平衡二叉树追求绝对平衡, 条件比较苛刻, 实现起来比较麻烦, 每次插入新节点之后需要旋转的次数不能预知. avl树是为了解决二叉查找树退化为链表的情况, 而红黑树是为了解决平衡树在插入、删除等操作需要频繁调整的情况 总结 红黑树的查询性能略微逊色于AVL树

[C语言教程]九、指针

喜欢而已 提交于 2019-11-28 18:08:01
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:为敢(WeiGanTechnologies) ➤博客园地址:山青咏芝( https://www.cnblogs.com/strengthen/ ) ➤GitHub地址: https://github.com/strengthen/LeetCode ➤原文地址: https://www.cnblogs.com/strengthen/p/11418333.html ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。 ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创! ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 一、地址与指针 Hi,欢迎来到指针的世界,也许您早已听过它的大名,指针被称为是C语言的精华所在。真正理解和掌握指针是征服C语言的关键所在! 在众多的计算机语言中,试问:还有哪门语言可以有C语言这样在作用、速度和安全上平衡的如此优异的呢?而指针则在其中扮演了重要的角色!或许有人会说:正是因为指针才使C程序变得非常不安全!而我则想说的是:这就要求C程序员要有更高的驾驭C语言的能力,而这点也恰好反映出C的设计哲学!那就是:“C充分相信程序员!” 所以:请不要辜负她! OK,在学习指针之前,我们先弄清楚一个概念: 地址 何谓地址

redis的数据结构与对象

倾然丶 夕夏残阳落幕 提交于 2019-11-28 17:57:24
  地方简单动态字符串   redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组),而是自己构建了一种名为简单动态字符串(simple dynamic string sds)的抽象类型,并将sds作为redis的默认字符串表示。    在redis中,c字符串只会作为字符串字面量用在一些无须对字符串值进行修改的地方 。比如打印日志:   redisLog(REDIS_WRNING,"redis is now ready to exit,bye bye");    如果redis需要的是一个可以被修改的字符串,那么就会使用sds来表示字符串的值 ,比如,如果在客户端执行命令,msg 和 hello word都将会用sds来表示。   redis> set msg "hello word"   OK   除了用来保存数据库中的字符串值之外,sds还被用作缓冲区:AOF模块中的AOF缓冲区。    1.sds定义   每个sds.h/sdshdr结构表示一个sds值:      sds遵循了c字符串以空字符结尾的惯例,保存空字符的1字节空间不计算到len属性中。为空字符串分配额外的1字节空间,以及将空字符串添加到字符数组的末尾都是由sds函数自动完成的,所以空字符串对于sds的使用者来说是完全透明的。 遵循了c字符串以空字符结尾的惯例的好处是

半边数据结构及其使用

我与影子孤独终老i 提交于 2019-11-28 16:09:00
实体的B-rep表示模型是一非常复杂的模型,要求能够表达出多面体各几何元素之间完整的几何和拓扑关系,并且允许对这种几何和拓扑关系进行修改.在B-rep表示中,体、面、边和顶点是最基本的几何元素,在实体的拼合、显示、分析计算或人机交互过程中,对基本几何元素的下列操作是必不可少的: .增加或删除体、面、边或顶点;   .已知一个体,查找它的所有面、所有边或所有顶点;   .已知一个面或一个边,查找它所属于的体;   .已知一个面,顺序查找围成它所有边;   .已知一个边,查找交于该边的所有面,或着查找该边的邻边,或者查找该边的两个端点;   .已知一个顶点,查找交于该顶点的所有边或所有面. 以上这些基本操作的效率直接影响着整个实体造型系统的效率。一个B-rep数据结构应当方便、迅速地实现几何元素的这些查询或增删操作.为了查询或操作方便,必须建立各几何元素间的拓扑关系,且引入其它辅助元素,例如在许多B-rep数据结构中具有环结点,用来表示面的内、外封闭边界.在B-rep的数据结构设计时,除了需要考虑时间的因素外,还要考虑空间的因素,即模型所占计算机内存的大小,但往往这两方面是互相矛盾的.要想各个几何元素之间查询迅速,必然要在它们之间建立广泛的联系,这样必然增加存储空间的占用量.反过来也是如此,而半边数据结构就很好的权衡了空间和时间的问题。 在构成多面体的三要素(点、边、面)中

C++中const与指针、引用的分析(转自china_unix GP-King)

允我心安 提交于 2019-11-28 14:42:13
C++中函数的参数相比C语言中的函数参数要复杂的多,其中主要的原因是C++中引入了引用以及const限定符。这两个对象的引入,使得C++中的函数参数变得异常的复杂多变,每一种类型都具有比较适合的使用范围。 本文详细的分析const与指针、引用在一起存在情况下的情况分析。 首先介绍引用 引用是对象的别名,必须在初始化的过程中与一个具体的对象绑定起来,绑定完成以后就再也不能够修改了,引用貌似和指针有很大的相似性,但是引用是引用,是一个别名,而指针是一个变量,只是变量中保存的是对象的地址,引用并不分配新的内存空间。因此一个引用与一块内存区域绑定,是这块内存区域的别名,就如同数组名一样,数组是内存中的一块区域,数组名是这块区域的名字,但是在内存中并不存在额外的区域保存数组名。引用就是一块内存区域的别名。C++中变量实质上就是一块内存区域,我们在用&i就可以得到变量i的地址,也就是说变量是这块区域的名字。对变量的操作实质上就是对这块内存中内容的操作。别名是这块区域的另一个名字。采用任何一个名字对这块区域修改都会影响区域的内容。 int vari = 10; int & refr = vari; vari = 20; cout < < refr < < " " < < vari < < endl ; refr = 30 ; cout < < refr < < " " < < vari < <

指针大小为什么与类型无关

倖福魔咒の 提交于 2019-11-28 13:53:22
  指针的大小与硬件有关。   内存中有各种各样的数据,整型、浮点型、字符型等等。这些数据在内存中占据不同大小的储存空间,用sizeof运算符(注:sizeof是种运算符而不是函数,它在编译时发挥作用)进行运算时结果是不同的。然而不同类型的指针在相同系统环境下进行这种运算时结果却是相同的。   众所周知,C语言中的指针描述的是内存中的地址。而内存地址这种东西则是由CPU进行编址的。对于一个4位的CPU来讲,它能同时输出的数据为4位,即0000-1111共2^4 种情况,故这些二进制数字只能对应到16个位置的内存地址,即CPU仅能识别出16个内存地址。即便你的内存再大,它也显示只有16个位置的内存可用。这种原理同样应用于32位和64位的CPU。   32位的CPU能同时呈现32个位的数据,故有2^32 种情况,对应到2^32 个内存位置也就是最大3.85GB大小,因此32位的系统只能支持最大4GB的内存。相比之下,64位的CPU能同时吞吐2^64 位的数据,这显然能够对应到2^64 个内存的地址,而理论上这个大小换算成10进制则是相当大的数,如果对应到内存,此时一个很大的内存。所以我们说64位系统理论支持无穷大内存(这里的无穷大只是一种概念,因为我们不可能用到如此巨大容量的内存)。   综上,因为指针存放的是地址,所以32位内存,共4个字节;64位系统的64位地址共8个字节—

C++内存详解[精]

你离开我真会死。 提交于 2019-11-28 12:53:15
伟大的Bill Gates 曾经失言:   640K ought to be enough for everybody — Bill Gates 1981   程序员们经常编写内存管理程序,往往提心吊胆。如果不想触雷,唯一的解决办法就是发现所有潜伏的地雷并且排除它们,躲是躲不了的。本文的内容比一般教科书的要深入得多,读者需细心阅读,做到真正地通晓内存管理。   1、内存分配方式   内存分配方式有三种:    (1) 从静态存储区域分配 。内存在程序编译的时候就已经分配好, 这块内存在程序的整个运行期间都存在 。例如全局变量,static变量。   (2) 在栈上创建 。在执行函数时,函 数内局部变量的存储单元都可以在栈上创建,函数 执行结束时这些存储单元自动被释放 。栈内存分配运算 内置于 处理器的指令集中,效率很高 ,但是分配的内存 容量有限 。   (3) 从堆上分配 ,亦称 动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存 ,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。   2、常见的内存错误及其对策   发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。有时用户怒气冲冲地把你找来

C语言笔记--传递结构指针以及值传递,址传递

Deadly 提交于 2019-11-28 10:40:04
#include <stdio.h> #include <windows.h> #include <mmsystem.h> #include <string.h> typedef struct _accoutn { char *name;//定义用户名 char *bankName;//定义银行名称 double limit;//定义银行卡额度 double Nowmoney;//定义现在银行卡金额 }Account; double Getload(const Account *a){ return(a->limit - a->Nowmoney);//定义欠款金额的算法 } int main() { Account p1; /*printf("请输入您的账户名:", *p1.name);*/ p1.name = "胡66"; p1.bankName = "招商银行"; p1.limit = 30000; p1.Nowmoney = 20000;//初始化信息,方法1。 /*Account p2; 这种定义变量,再赋值会报错,具体原因我还不清楚,看来自己定义的数据类型还是和系统自定义的数据类型有些不同! p2={ "小王","农业银行",50000,10000 }*/ Account p2 = { "小王","农业银行",50000,10000 };//初始化信息方法2 printf

C++软件开发面试题总结

落爺英雄遲暮 提交于 2019-11-28 07:34:53
  面试题有难有易,不能因为容易,我们就轻视,更不能因为难,我们就放弃。我们面对高薪就业的态度永远不变,那就是坚持、坚持、再坚持。出现问题,找原因;遇到困难,想办法。我们一直坚信只有在坚持中才能看到希望,而不是看到希望才去坚持。   人生没有如果,只有结果和后果。既然选择了,就不后悔。年轻就是资本,年轻就要吃苦,就要历练。就要学会在坚持中成长。如此感慨,至深的心得体会,绝对的经验之谈。 1、 Static有什么用途? (1)函数体内static变量的作用范围是该函数体,该变量的内存只被分配一次,因此它的值在下次调用时不变; (2)模块内的static全局变量同样只能在该模块内的函数访问和调用,不能被模块外的其他函数访问; (3)在类中的static成员变量属于整个类所有,对类的所有对象只有一份拷贝,这个函数不接受this指针,因为只能范围类的static成员函数。 2、 const (1)不管在函数声明修饰形参、还是修饰类的成员变量,表示该成员变量不能被改变,而且通常需要进行初始化,因为之后不能再改变; (2)对于指针来说,可以修饰指针所指向的变量(在*左边,即指针指向内容为常量),也可以指定指针本身为const(在*右边,指针本身是常量),或者两者同时指定为const(都是常量)。 3、 this指针 (1)this指针本质是一个函数参数,只是编译期隐藏起形式的,语法层面上的参数