首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C语言指针初识——原来指针这么有趣

1.1 指针的定义 我认为实战是最好的理解方式,所以会有代码以及注释详细理解,不过在你看代码之前,你应该知道这些东西: ❝ 如何定义一个指针 如何给指针赋值指针赋值后,怎么使用原变量的值 ❞ 就和定义一个普通变量一样...:类型 *变量名 指针变量接收的是变量的内存地址在C语言中,通过符号&来取出变量的内存地址 赋值也是同样的 ---- 1.2 指针实例理解 那么你知道了这些知识后,就看代码: #include ​ int main() { int num = 10; // 创建一个int类型的变量,并赋值为10 int* pnum; // 创建一个int类型的指针,你还能这样写...来看看昨晚我与大佬的对话吧~~ 在这里插入图片描述 但是当时还是很疑惑为什么会出现了两个内存地址~~ 第二天找到了原因!...❝昨天是使用手机敲得C代码,因为那时候还在火车上,没法拿电脑 今天使用了电脑,编译器是gcc,编辑器是vs code 重新编译了一下 ❞ 运行结果如下: p=0061FECC &p=0061FECC *

32700

第5章 | 共享与可变,应对复杂关系

在 C++ 中,std::vector 规范会告诫你“重新分配向量缓冲区会令指向序列中各个元素的所有引用、指针和迭代器失效”。...("{}, {}, {}", m1, m2, z); // 在这里使用这些引用 可以从共享引用中重新借入共享引用: let mut w = (107, 109); let r = &w; let r0...("{}", r0); // 在这里使用r0 可以从可变引用中重新借入可变引用: let mut v = (136, 139); let m = &mut v; let m0 = &mut m.0...Rust 的所有权模型会不断给你制造麻烦。解决之道是进行一些前期设计并构建出更好的程序。 笔记 对程序良好的设计,但不要过度设计 Rust 就是要把你理解程序的痛苦从将来移到现在。...它确实做到了:Rust 不仅会迫使你理解为什么自己的程序是线程安全的,甚至可能还需要你做一些高级架构设计。

8410
您找到你想要的搜索结果了吗?
是的
没有找到

彻底搞定C语言指针(精华版)

1.语言中变量的实质 要理解C指针,我认为一定要理解C中“变量”的存储实质, 所以我就从“变量”这个东西开始讲起吧! 先来理解理解内存空间吧!...看来指针和数组名还是不同的。其实上面的指针指针变量,而数组名只是一个指针 常量。这个代码与上面的代码不同的是,指针pa在整个循环中,其值是不断递增的,即指针修改了 。...之后我的程序在其它任何处都 不会再去重新对它赋值。那我又应该怎么办呢?...所以*pi是常量,是不能赋值的(虽然pi所指的i2是变量,不是常量)。 其次,pi前并没有用const 修饰,所以pi是指针变量,能赋值重新指向另一内存地址的。...,那就请在这里申明了。

93830

C++: 06---构造函数析构函数

深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。 如图: ? 思考: 当对象中存在指针成员时,为什么需要自己实现拷贝构造函数?...分析:两个对象的指针成员所指内存相同,这会导致什么问题呢? mname指针分配一次内存,但是程序结束时该内存却被释放了两次,会造成内存泄漏问题,这是一个不容忽视的问题。...思考: 为什么要避免自赋值呢? 1)自己给自己赋值完全是毫无意义,为了效率。 2)如果类的数据成员中含有指针,自赋值有时会导致灾难性的后果。...对于指针间的赋值,先要将p所指向的空间delete掉,然后再为p重新分配空间,将被拷贝指针所指的内容拷贝到p所指的空间。...如果是自赋值,那么p和拷贝指针是同一指针,在赋值操作前对p的delete操作,将导致p所指的数据同时销毁。 拷贝构造函数与赋值函数的区别?

64220

手把手教你深入理解cc++中的指针

二,指针的本质就是地址 当我们在程序中声明一个变量并给这个变量赋值的时候,编译器做了什么呢?...的地址,也就是2000,当我们想通过p来操纵a的话,首先要根据p保存的地址找到它指向的内容,也就是解引用*p,当*p的内容放生改变的时候,首地址为2000的内存单元存储的值也会做出改变,因此变量当*p重新赋值为...第四行直接报错,因为&arr指的是整个数组的指针,不能把数组指针赋值给整形指针。虽然arr与&arr在数值上是相同的,但是两者意义不同。...至于p2 就更好理解了,在这里括号的优先级比[]高,*号和p2 构成一个指针的定义,指针变量名为p2,int 修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。...注意是从名字开始,不是从开头也不是从末尾,这是理解复杂指针的关键。

45031

《JavaScript 模式》读书笔记(4)— 函数3

所有这些调用不断的重写全局scareMe()指针,以至于当它最终调用时,他才第一次具有更新函数主体并通知“Double boo”消息的权利。...再多说两句,个人理解: // 我们先来看,为什么上面的代码访问不到property属性。...最后,再说一下,为什么赋值给一个其它名字的变量以及用对象的方法来使用的时候,重定义永远没有发生。...个人理解,因为你每次在执行的时候,赋值的动作是有的,但是并没有把我覆盖,所以,每次都是重定义,每次都无法执行新的内部逻辑。...因为前面prank()或者spooky.boo()的每一次执行,都重新定义了scareMe()。希望我说的,你理解了。

37520

JavaScript经典作用域问题(转载)

第5行输出this.a,我们都知道,函数内部的this指针指向的是函数的调用者,在这里函数test全局对象调用,所以this指针指向全局对象(这里即window),所以this.a = window.a...第7行输出结果为100,因为局部变量a在第3行已经赋值了100,所以直接输出局部变量a的值。...a = 10; console.log(a); } test(); 答案:undefined ,10 解析:看了第1个例子,可能有同学会认为输出结果是10 10,但是结果却不是10 10,为什么呢...我们知道在函数内部,一般用var声明的为局部变量,没用var声明的一般为全局变量,在test函数内,a=10声明了一个全局变量,所以第3行的a应该输出全局变量的值,而在函数执行之前已经声明过一个全局变量并赋值...第4行给全局变量a 重新赋值10,所以全局变量a的值变成10,所以第5行输出10。而在函数test外部,第8行输出全局变量a的值,因为全局变量重新赋值为10,所以输出结果即为10。

34220

《JavaScript 模式》读书笔记(4)— 函数3

所有这些调用不断的重写全局scareMe()指针,以至于当它最终调用时,他才第一次具有更新函数主体并通知“Double boo”消息的权利。...再多说两句,个人理解: // 我们先来看,为什么上面的代码访问不到property属性。...最后,再说一下,为什么赋值给一个其它名字的变量以及用对象的方法来使用的时候,重定义永远没有发生。...个人理解,因为你每次在执行的时候,赋值的动作是有的,但是并没有把我覆盖,所以,每次都是重定义,每次都无法执行新的内部逻辑。...因为前面prank()或者spooky.boo()的每一次执行,都重新定义了scareMe()。希望我说的,你理解了。

40540

跟着老猫来搞GO,“面向对象”

上述比较简单地,咱们可以直接用“.”的方式进行对结构体变量进行赋值以及取值,当然咱们也可以获取成员变量的地址,然后通过指针来访问它。...Employee = &jack employeeA.Position = "Super" + employeeA.Position fmt.Println(employeeA.Position) } 还没理解透彻指针的小伙伴可以会有点懵...上面的那个步骤,我们只是获取了jack的职位并通过指针将其重新赋值升级,那么下面,其实咱们就定义了一个Employee的指针,并且这个指针指向的是jack这个结构体,那么针对我们的employeeA这个员工指针就能获取其结构体中所有的属性...,并且将其重新赋值。...这句话可能有点不好理解,我们还是来直接看一下例子。

25420

Python函数之一切皆对象

接下来,我们看一下Python微观世界中完成a=1总共分几步 当我们声明(也叫定义)一个变量a的时候,其实在我们计算机的内存中就开辟了这么一块区域,用来描述a的属性及状态 当我们把1赋值给a的时候(a...=1),计算机相当于把1指向了a(如果这里之前学过指针的同学可能会很快理解) 这时候我们使用print(a)的时候,相当于告诉计算机我要输出a的值,这时候当然就会输出1 如果此时我们再把另外一个值10赋给...a,那么计算机就会 断开1-->a这个指针,并把1丢弃 重新建立a这个对象并且建立10-->a这个指针 这时候我们再次print(a)的时候就是10了 这里注意第一次声明的a和第二次声明的a,并不是同一个...很抱歉,这是不可以的,当你重新定义了一个相同名称的变量时,之前的同名变量及值就已经丢弃了(这也是Python垃圾回收机制的一种表现) 我们回顾一下这如此简单的表面现象 为什么会这样呢?...,就不是把list这个变量及列表全部丢弃,再重新声明的list列表,而是直接在原有list的基础之上增加了一个元素(这和不可变类型变量不同) 理解了以上内容,各位小伙伴们就会理解在函数传递值的时候,我们实际上是传递了变量本身

63170

js中全局变量_var变量提升原理

第5行输出this.a,我们都知道,函数内部的this指针指向的是函数的调用者,在这里函数test全局对象调用,所以this指针指向全局对象(这里即window),所以this.a = window.a...第7行输出结果为100,因为局部变量a在第3行已经赋值了100,所以直接输出局部变量a的值。...console.log(a); var a = 10; console.log(a); } test(); 解析:看了第1个例子,可能有同学会认为输出结果是10 10,但是结果却不是10 10,为什么呢...我们知道在函数内部,一般用var声明的为局部变量,没用var声明的一般为全局变量,在test函数内,a=10声明了一个全局变量,所以第3行的a应该输出全局变量的值,而在函数执行之前已经声明过一个全局变量并赋值...第4行给全局变量a 重新赋值10,所以全局变量a的值变成10,所以第5行输出10。而在函数test外部,第8行输出全局变量a的值,因为全局变量重新赋值为10,所以输出结果即为10。

5.6K30

C++ 合成默认构造函数的真相

(“这些函数“指的是编译器版本的复制构造函数、赋值操作符和析构函数,还包括了默认构造函数。)也就是说,默认构造函数“需要”的时候编译器才会帮我们合成,那什么情况才是默认构造函数”需要“呢?...当你试图查看合成默认构造函数把数据成员num初始化为什么值的时候,你会发现编译器甚至都让你运行不了程序: 当类只含有内置类型或复合类型的成员时,编译器是不会为类合成默认构造函数的,这种类并不符合”需要...function(c); //关注重点在这里 return 0; } 函数function参数pa的真正类型是可以改变的,既可以把A对象指针赋值给pa,也可以把对象指针赋值给...这个指针的安插,编译器将会在合成默认构造函数中完成,同样的,如果设计者已经写了多个构造函数,那么编译器不会重新写默认构造函数,而是把虚基类指针的安插代码插入已有的构造函数中。...总结 重新强调文章开篇所提,以下两个观点都是误解: a)   任何类如果没有定义构造函数,则编译器会帮我们合成一个默认构造函数。

75930

滑动窗口就是这么神奇!

; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break } } } // 如果result没有赋值的话...其实从动画中可以发现滑动窗口也可以理解为双指针法的一种!只不过这种解法更像是一个窗口的移动,所以叫做滑动窗口更适合一些。 在本题中实现滑动窗口,主要确定如下三点: 窗口内是什么?...} // 如果result没有赋值的话,就返回0,说明没有符合条件的子序列 return result == INT32_MAX ?...0 : result; } }; 时间复杂度: 空间复杂度: 一些录友会疑惑为什么时间复杂度是O(n)。...不要以为for里放一个while就以为是 啊, 主要是看每一个元素操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是操作两次,所以时间复杂度是2 * n 也就是 。

75940

从java发微javascript语法里的一些难点问题-js变量,栈区,作用域

其实这个变量任然定义即内存存储里有了标示符,只不过没有赋值,代码一则说明,内部变量a已经和外部环境无关,怎么回事?如果我们按照代码运行是按照顺序执行的逻辑来理解,这个代码也就没法理解。...所以,引子里的代码在函数的局部作用域下变量a重新定义了,在预加载时候a的作用域范围也就被框定了,a变量不再属于全局变量,而是属于函数作用域,只不过赋值操作是在运行期执行(这就是为什么javascript...window,这是为什么了?...,同时javascript里的函数还有可以作为构造函数,这个构造函数可以创建实例化对象,结果导致方法执行时候this指针的指向会不断发生变化,很难控制。...this指针的感觉,常常会忽视它,这就是干扰我们在代码里理解this指针指向window的情形。

29610

iOS - 详解内存管理

那时想总结的,忘记了,趁着最近有时间,再把这本书回炉重新理解再看一遍,对比自己的理解,以及一些Swift内存管理的知识总结的内容,可能文章内容会比较长,就是希望自己能把内存管理这方面的知识真正的仔细总结一下...通过调用 execBlock 这个方法,也就是执行了一下我们的Block表达式之后为什么就不会有“循环引用”呢?...nil赋值的状态,也就是所谓的“空弱引用”!...所以,通过检查__weak修饰的变量是否为nil,来判断赋值的对象是否已经废弃!  ...这个转换可以使 要转换赋值的变量也持有所赋值变量持有的对象 ,通常用作OC对象转换成CF对象       3、"__bridge_transfer 转换类型", 这个转换可以使 转换的变量所持有的对象在该变量赋值给转换目标变量之后随之释放

58510

C语言——小学一年级题目解析(四)

概念理解题,stu是结构体的类型名,而括号后面的stutype是变量名。 选项C错误。 第15题 ? 概念理解题,stu1是变量名。引用成员有三种形式:也就是选项中的B、C、D 选项A错误。...一个变量x的地址就是该变量的指针,记作&x,课本上的定义。 选A 第17题 ? *p是指针,取m的地址&m,赋值给p,那指针就指向了m的地址。 选D 第18题 ?...(Exit code 0) ================ READY ================ 指针p先指向a,然后p赋值为china,地址发生了变化,即:指向了字符串“china”的首地址...另外字符串赋值char *p; p="china"等价于char *p="china" 然后*p是char类型,而p在这里是字符串类型同时也指向字符串首地址,也就是p的地址值可以用%p输出,如果用%s输出就是字符串了...感觉这是学C以来最绕的一个,剪不断理还乱 ? 第19题 ? 这题紧接着上一题,其实上一题还有个点没说,刚好就又来了。 这题跟上题的B选项差不多,但是while里面有个*p,之前没提及。

51010

内存管理说明白点

那时想总结的,忘记了,趁着最近有时间,再把这本书回炉重新理解再看一遍,对比自己的理解,以及一些Swift内存管理的知识总结的内容,可能文章内容会比较长,就是希望自己能把内存管理这方面的知识真正的仔细总结一下...通过调用 execBlock 这个方法,也就是执行了一下我们的Block表达式之后为什么就不会有“循环引用”呢?...nil赋值的状态,也就是所谓的“空弱引用”!...所以,通过检查__weak修饰的变量是否为nil,来判断赋值的对象是否已经废弃!  ...这个转换可以使 要转换赋值的变量也持有所赋值变量持有的对象 ,通常用作OC对象转换成CF对象       3、"__bridge_transfer 转换类型", 这个转换可以使 转换的变量所持有的对象在该变量赋值给转换目标变量之后随之释放

42120

c专题之指针---野指针和空指针解析

在上一篇c专题指针文章中,我们介绍了什么是指针,文章里面从普通变量进而引出指针的概念,这样对指针理解有一定的帮助(其实最好的理解,就是要明白硬件里面的内存原理,这是理解指针最好的地方,就好比说会汇编语言的人来去理解指针这里跟不会指针的人去理解...所以NULL的实质其实就是0,然后我们给指针赋初值为NULL,其实就是让指针指向0地址处。为什么指向0地址处?2个原因。...这个错误(对新手)很难检查出来;如果习惯了把NULL写在前面,当错误的把==写成了=时,编译器会报错,程序员会发现这个错误(这里自己昨天就在这里犯了低级错误)。...3、怎样来避免野指针的出现? 野指针的错误来源就是指针定义了以后没有初始化,也没有赋值(总之就是指针没有明确的指向一个可用的内存空间),然后去解引用。...因此个人推荐大家一般常用的方法: 第一点:定义指针时,同时初始化为NULL 第二点:在指针解引用之前,先去判断这个指针是不是NULL 第三点:指针使用完之后,将其赋值为NULL 第四点:

1.4K20

详细完整的说说对象实例化过程

但是在这个阶段, final 修饰的变量也就是常量会在这个阶段准确的赋值。 具体到这里,在这个阶段 DemoClass 中的 a 会被赋值为 1,b 与 c 均被赋值为 0。...具体到 DemoClass类,在这个阶段会将 b 赋值为 2,c 赋值为 3。 分配内存 当类加载过程完成后,或者类本身之前已经加载过,下一步就是虚拟机要为新生对象分配内存。...第一种方式很好理解,多个线程使用 CAS 的方式更新指针,多线程下只有一个线程可以更新完成,其他线程通过不断重试完成内存指针重新移动。...具体到这里就是 DemoClass 的 d 赋值为 4,e 赋值为 5。...在这里就是讲对象的引入入栈,并返回赋值给 dc,至此,一个对象创建完成。 对象实例化的完整流程 根据上面的讨论,我们再来回顾一下对象实例化的整个流程:

66620

【CPP】简单的字符串匹配(1)——BF算法与KMP算法

在这里我们先将字符串声明为空串,再调用自带的assign函数为其赋值,然后获取它的长度。 ? 然后先是我们最容易想到的算法,BF算法——暴风(Brute Force)算法。...你会发现模式指针和主串指针回溯匹配了很多很多次,但是这些匹配其实是无用的。...我们其实并没有必要不断回溯主串的指针来匹配,我们可以按照一定的规则跳跃模式串来进行匹配,这就是KMP算法的思想,利用已经匹配成功的子串作为之后匹配的经验,利用模式串自身的特典来加速匹配。...但是刚才我们为什么要先从1跳回0再跳回开头呢?这便是我们要找到的模式串的自身特典,一个包含下标的数组,我们把它称为next数组。利用这个数组我们可以跳跃移动模式串来匹配。...首先在理解KMP的思想下,我们先假设已经有了一个next数组来写一个KMP算法。 ? 主体的思路并不复杂,主要就是要理解k=next[k]这句,如果不理解可以试试看画画图理解

95920
领券