指针粗解
- 格式:doc
- 大小:138.50 KB
- 文档页数:17
【C】Re05指针⼀、变量 & 指针变量 = 内存地址 + 存储值指针变量 = 内存地址 + 存储值【变量的内存地址】作⽤:间接访问内存地址内存地址 = 地址编号地址编号:内存中的每个字节唯⼀的编号,从0开始记录,使⽤⼗六进制显⽰可以使⽤指针变量存储变量的地址不同数据类型就有对应的指针的数据类型⼆、使⽤#define _CRT_SECURE_NO_WARNINGS#include <stdlib.h>#include <stdio.h>void pointer () {// 指针变量int * pointer;// 变量int varA = 100;printf("pointer -> x16 %x, x10 %d, x8 %o\n", pointer, pointer, pointer);printf("varA -> %d\n", varA);printf("- - - - - - - - - - - - - - -\n");// 把varA的地址赋值给指针变量pointerpointer = &varA;// 通过指针变量pointer取地址访问varA变量*pointer = 20;printf("pointer -> x16 %x, x10 %d, x8 %o\n", pointer, pointer, pointer);printf("varA -> %d\n", varA);}int main() {pointer();return EXIT_SUCCESS;}输出格式注意:// %p显⽰完整⼗六进制位数, %x只显⽰进制数语法递进:int tf = (*pointer == *&varA); // 0 false, 1 trueint tf2 = (pointer == &varA);int tf3 = (*pointer == varA);printf(" %d\n",tf);printf(" %d\n",tf2);printf(" %d\n",tf3);三、空指针& 野指针空指针定义void nullPointerAndWildPointer () {// 定义⼀个空指针int * nullPointer = NULL;}指向的NULL常量来⾃于STDLIB标准库头⽂件的这⼀段#else#define NULL ((void *)0)#endif#endif最后指向的还是⼀个0⽽已void nullPointerAndWildPointer () {// 定义⼀个空指针int * nullPointer = 0;}实际上不建议直接写0,容易混淆指针变量与变量空指针不能被访问到:void nullPointerAndWildPointer () {// 定义⼀个空指针int * nullPointer = NULL;printf("nullPointer -> %p", *nullPointer);}int main() {nullPointerAndWildPointer();return EXIT_SUCCESS;}因为内存地址编号0 - 255已经被操作系统占⽤了空指针的作⽤:不知道应该对指针定义多少合适时使⽤野指针定义:void nullPointerAndWildPointer () {int * wildPointer = 0xffff;printf("wildPointer -> %p\n", *wildPointer);}指针变量存储了⾮法的、未知的⼀个内存地址,该地址存储的内容将⽆法访问但是允许查看地址void nullPointerAndWildPointer () {// 定义⼀个空指针// int * nullPointer = NULL;// printf("nullPointer -> %p\n", *nullPointer);// 定义⼀个野指针// int * wildPointer = 0xffff;// printf("wildPointer -> %p\n", *wildPointer);int * nullPointer = NULL;printf("nullPointer -> %p\n", nullPointer);int * wildPointer = 0xffff;printf("wildPointer -> %p\n", wildPointer);}int main() {nullPointerAndWildPointer();return EXIT_SUCCESS;}野指针的第⼆种情况:也是⼀样,地址可以访问,但是内部存储的值⽆法访问// 野指针的第⼆种情况int * wildPointer2;printf("wildPointer2 -> %p\n", wildPointer2);// printf("wildPointer2 value -> %d\n", *wildPointer2);四、⽆类型指针和万能指针1、Void类型概述void voidUsage() {// void 是⼀个数据类型,所以也具备对于的指针类型 void *// void 的⽤途是修饰函数返回类型和形参类型}// 形参修饰了void 表⽰该函数不需要参数void noNeedParam( void ) {}2、函数返回类型省略当函数的返回值类型声明的是void时,我们可以省略,不需要return不过不建议这样书写,C++并不⽀持这样的语法aaa () {printf("void返回类型省略的函数调⽤");}int main() {aaa();return EXIT_SUCCESS;}如果函数不需要注⼊任何类型的参数,编写时是可以明确标注void 数据类型即可3、⽆类型指针与万能指针:⽆类型指针可以强转任意类型接收对于的类型的变量地址void noTypePointer() {void * p = NULL;printf("sizeof p = %d\n", sizeof(p)); // 64位 sizeof p = 8 32位 sizeof p = 4int num = 10;p = #// printf("p = %d\n", *p); int指针类型赋值给void指针类型,类型不匹配错误// 使⽤强转来转换指针类型printf("p = %d\n", *(int *)p);}另外可以作为万能指针使⽤:void anyTypePointer() {void * pointer = NULL;int * varA = NULL;char * varB = NULL;// ⼀个是int指针类型⼀个是char指针类型,直接这样赋值不会有语法错误提⽰// 但是在编译执⾏时会有警告提⽰,另外,如果指针调⽤了就会报错。
c语言指针详细讲解
C 语言中指针是非常强大的概念,它允许程序直接访问内存中的数据。
指针在 C 语言中最初是被用于解决内存分配问题而提出的,随着 C 语言的发展,指针也变得愈发重要。
指针的本质是一个存储变量地址的变量。
在 C 语言中,指针通常用符号&来表示,例如&x 表示的是 x 变量的地址。
指针变量存储的是一个内存地址,当程序读取指针变量时,它会读取该地址中存储的数据。
C 语言中可以使用指针进行高效的内存操作。
例如,当程序需要对一个数组元素进行修改时,可以直接用指针修改该元素的值,而不必修改数组名本身。
另外,指针还可以用于动态分配内存,这是 C 语言中一个重要的特性。
指针的使用方法比较灵活,但也需要小心使用。
如果不小心处理指针,可能会导致未知的错误。
例如,当指针指向的内存空间被释放后,程序试图访问该内存空间时可能会导致未定义的行为。
因此,在C 语言中,指针的使用需要更加谨慎。
C 语言中指针是一个非常重要和强大的概念,掌握指针的使用方法可以让程序员写出更加高效和安全的代码。
鼠标指针抖动的原因及其解决方法鼠标指针抖动的原因及其解决方法随着科技技术的飞速发展,电脑已经越来越多的进入了寻常的百姓家,然而由于电子技术的发展飞快与我们电子知识的学习脱节问题,我们出现了很多电脑方面的问题有待于我们研究,下面就有店铺为大家总结一下鼠标指针在屏抖动的原因及其解决措施。
一、鼠标指针抖动的原因1、老机的适应状况较差:老用户在计算机的升级过程中还在保留原来的串口鼠标,而这类鼠标可以在任何一类具有COM接口的主板上使用,但是随着显卡的技术提高,显卡就占有了更多的中断资源,显卡就会抢断COM接口,造成鼠标抖动。
2、电脑外部放射性信号的扰乱:计算机硬件是以一定频率进行工作的,如果发现频率波声发生变化,就会带动鼠标指针抖动。
3、受到外界的杂散光影响:鼠标为了追求外观的美丽,而使得透光性较好,如果出现光路屏蔽不好现象,如果出现强光扰乱的话,就就会影响鼠标的光信号传输,则鼠标就会进行晃动。
4、鼠标质量较差:如果鼠标质量不好的话,受到室内温度的影响,使鼠标的工作频率不稳,则会出现鼠标晃动现象。
5、电缆的.中芯线出现断路:鼠标端口处的四根中芯线受到鼠标的来回折动,时间长久之后就会有折断而造成鼠标运动不规律甚至出现定格不动。
6、鼠标垫的问题:鼠标垫是否干净,粗糙度是否很好,还有就是鼠标垫放置是否平稳,都会影响鼠标指针。
二、鼠标指针抖动解决方法1、检查放置鼠标的鼠标垫是否太过光滑,可以调换个鼠标垫试试。
2、看看驱动是够出现问题,可以先卸载了这个驱动,然后在进行重新安装。
3、如果是鼠标的接口坏了,那么就只能更换鼠标了。
4、用棉布擦一擦鼠标的感光灯,清理感光灯的杂物,使得鼠标的感光灯不再受杂物的影响。
5、调整鼠标的精确度,使得鼠标能够适应电脑的运行需要。
以上的情况是鼠标状况完好无损的前提下进行的的一些简单操作步骤,如果是电脑自身跟不上时代更新的步伐,那么鼠标抖动的问题就是电脑的问题,可以考虑更换电脑,如果是室内强光的扰乱情况,或者是鼠标自己的问题,那么就可以更换鼠标了,最好是跟换比较抗强光能力好一点的鼠标。
在C语言中,函数指针是一种特殊类型的指针,可以用来存储和传递函数的地址。
函数指针可以在编译时或者运行时被调用,并通过参数和返回值来传递数据。
强制类型转换是将一个类型的值转换为另一个类型。
在C语言中,强制类型转换可以使用强制类型转换运算符(`(type)`)来完成。
参数个数不对是指在调用函数时,传递给函数的参数数量与函数定义中的参数数量不匹配。
这可能会导致编译错误或者运行时错误。
如果将函数指针强制转换并传递参数个数不对,会导致以下几种情况:
1. 编译错误:如果参数个数与函数定义中的参数数量不匹配,编译器会报错,导致编译失败。
2. 运行时错误:如果参数个数与函数定义中的参数数量不匹配,但编译器没有报错,那么在运行时可能会出现错误。
这可能会导致程序崩溃或者出现未定义的行为。
3. 未定义行为:如果函数指针强制转换后,调用的函数和原始函数具有不同的参数个数和类型,那么可能会出现未定义的行为。
这可能会导致程序出现不可预测的结果或错误。
因此,在使用函数指针时,应该确保传递给函数的参数个数和类型与函数定义中的参数个数和类型一致,以避免出现编译错误、运行时错误或未定义行为。
指针式时钟设计知识点时钟是人们生活中必不可缺的物品,而指针式时钟作为一种经典的设计,被广泛运用于各类时钟设备中。
本文将从时钟基本原理、指针设计、时钟运作机制等方面介绍指针式时钟的设计相关知识点。
一、时钟基本原理指针式时钟是根据物体运动的规律来显示时间的。
其基本原理是借助时钟机芯中的发条、电池或电源等能量源,通过传动装置将能量传递给时钟机芯中的齿轮组,使之转动。
然后,通过指针与齿轮组的配合,指向刻度盘上的不同刻度从而显示出时间信息。
二、指针设计1. 指针形状指针的形状设计要考虑美观、实用和易读性。
一般情况下,时钟有三个指针,即时针、分针和秒针。
时针比分针短而粗,秒针更细长。
指针的尖端应做成与指针轴心对称,这样可以避免视觉上的误差。
2. 指针材质指针的材质应选用轻便且不易变形的金属材料,如铝合金、不锈钢等。
这样可以确保指针的稳定性和耐用性。
3. 指针颜色为了方便读取时间,指针的颜色应与背景形成鲜明对比,一般情况下选择黑色或深色的指针。
另外,指针上也可以采用荧光涂料,以提供在暗光环境中的可读性。
三、时钟运作机制1. 机械式指针时钟机械式指针时钟通常使用机械齿轮传动,通过发条或者电磁弹簧的力量来驱动时钟机芯。
发条会慢慢放松,通过传动装置带动时钟齿轮的转动,进而驱动指针运动,实现时间的显示。
2. 电子式指针时钟电子式指针时钟使用电子元件作为驱动力。
一般情况下,采用电池或者外接电源来提供能量。
通过电路控制和芯片的计算,实现指针的运动和时间的显示。
3. 网络同步指针时钟网络同步指针时钟通过与网络连接,接收准确的时间信号来调整指针的运动。
这种时钟一般用于需要高度精确时间的场合,如实验室、控制系统等。
四、指针式时钟的应用领域指针式时钟由于其简洁、直观的设计和易于读取的特点,在生活中得到广泛应用。
它可用于家庭、学校、办公室等室内时钟,也可安装在公共场所如车站、机场等作为大型时钟的显示设备。
此外,在钟表和手表等个人佩戴装置中,指针式时钟同样被广泛运用。
幼儿园认识钟表教案(必备8篇)幼儿园认识钟表教案第1篇活动目标:1、能辨认出钟表上的整点、半点。
2、知道时针、分针及它们的运转规律。
3、教育幼儿要珍惜时间、爱惜时间。
4、发展幼儿的观察比较能力。
5、探索、发现生活中的多样性及特征。
活动准备:1、幼儿一日生活录像、课件。
2、实物钟表一人一份、小钟表模型若干。
活动过程:1、听音乐《铃儿响叮铛》做活动前的热身运动。
2、谈话激趣,观看录像,引入主题----钟表老师:小朋友在家喜欢做什么事情?(让幼儿自由说)老师最喜欢看电视了,咱们一起看。
观看录像《大风车》老师:《大风车》是几点播出的?怎样才能准时收看呢?做哪些事情还需要看钟表?3、参观钟表店,认识不同形状、不同种类的表。
4、让幼儿自选钟表,仔细观察。
(1)上面有什么?(数字、指针)(2)后面有什么?(齿轮)用手拨一拨,有什么发现?时针和分针有什么变化?(分针跑的快,时针跑的慢)(3)课件《龟兔赛跑》理解时针和分针的运转规律。
(分针跑一圈,时针走一格)5、课件演示:认识整点、半点,寻找他们之间的规律。
(1)、(对比时间为4点、9点钟表)老师:有没有相同的地方?(分针都指向12)老师总结:当分针指向12时,时针指向几,就是几点整。
幼儿拨整点(6点和12点时针和分针的关系)(2)、(对比时间为2点半、8点半钟表)老师:有没有相同的地方?(分针都指向6)师总结:分针指在6上,时针指在两个数字中间,就是半点,是两个数字中小的数的半点。
6、观看幼儿一日生活录像,取小钟表模型认识时间。
(1)幼儿看录像,取出有时间的钟表模型。
(2)游戏:《找朋友》。
幼儿任选一个钟表模型,老师说出一种活动,时间相同的好朋友站在一起。
7、课件演示:让幼儿正确辨认时间。
8、帮助幼儿理解钟表的功能,教育幼儿珍惜时间、爱惜时间。
老师:钟表是告诉人们现在是什么时间,应该干什么事情了。
小朋友认识了钟表,就可以按时做事情。
比如:按时起床,按时上幼儿园。
c语言中的指针详解在C语言中,指针是一种特殊的变量类型,它存储了一个变量的内存地址。
通过指针,我们可以间接访问和修改内存中的数据,这对于一些需要动态分配内存的操作非常有用。
以下是关于C语言指针的一些详细解释:1. 定义指针:使用"*"符号来定义指针变量。
例如,int* ptr; 定义了一个指向整型变量的指针 ptr。
2. 取址操作符(&):取地址操作符(&)用于获取变量的内存地址。
例如,&a 返回变量 a 的地址。
3. 解引用操作符(*):解引用操作符(*)用于访问指针所指向的变量的值。
例如,*ptr 返回指针 ptr 所指向的整型变量的值。
4. 动态内存分配:可以使用相关的库函数(如malloc和calloc)在运行时动态分配内存。
分配的内存可以通过指针来访问和使用,并且在使用完后应该使用free函数将其释放。
5. 空指针:空指针是一个特殊的指针值,表示指针不指向任何有效的内存地址。
可以将指针初始化为NULL来表示空指针。
6. 指针和数组:指针和数组在C语言中有密切的关系。
可以通过指针来访问数组元素,并且可以使用指针进行指针算术运算来遍历数组。
7. 传递指针给函数:可以将指针作为函数参数传递,以便在函数内部修改实际参数的值。
这种传递方式可以避免拷贝大量的数据,提高程序的效率。
8. 指针和字符串:字符串在C语言中实际上是以字符数组的形式表示的。
可以使用指针来访问和操作字符串。
需要注意的是,指针在使用时需要小心,因为不正确的操作可能导致程序崩溃或产生不可预料的结果。
对于初学者来说,理解指针的概念和使用方法可能需要一些时间和练习。
认识钟表教学设计【大全5篇】认识钟表教学设计1活动目标:1、初步了解,认识钟表的基本结构,知道钟表是表示时间的工具。
2、知道时针分针及其表示时间的关系,了解时间的意义。
3、帮助幼儿了解钟表的功能,培养幼儿从小养成珍惜时间的好习惯。
活动准备:教具准备:故事挂图《时间哥哥》;钟表卡片,记录时间的.工具。
学具准备:钟表卡片。
一、导入活动:教师出示故事挂图《时间哥哥》,讲故事并引导幼儿回答问题。
教师:“时间哥哥的房子里面有什么呢?”“时间哥哥教小动物们认识了什么?”二、集体活动:1、教师引导幼儿认识钟表的种类。
(1)教师引导幼儿说一说自己见过什么样的钟表。
(2)教师出示各种各样的钟表卡片,请幼儿说出它们的名称,如,座钟,挂钟,闹钟,手表,怀表等。
2、教师引导幼儿了解钟表的结构。
教师请幼儿观察钟表上有什么,引导幼儿认识并正确说出它们的名称,如,表盘,表针,数字等。
3、教师引导幼儿通过观察,比较钟表上时针和分针的不同,认识钟表上的12个数字以及数字的排列位置。
教师:“请小朋友们看一看钟面上都有什么?” “钟面上有多少个数字,这12个数字是怎么排列的?”“请小朋友们看一看两根针有什么不一样?”“又短又粗的这根针叫时针,又长又细的这根针叫做分针。
”4、教师引导幼儿了解钟表的功能。
教师:“小朋友们你们家里有钟表吗?”“你们还在什么地方看见过钟表。
”“为什么那么多地方都要用到钟表呢!”5、教师小结:钟表是计时的工具,它可以告诉人们现在是什么时间,应该干什么事情,可以帮助人们形成良好的生活习惯,我们认识了钟表,就可以按时起床,按时上幼儿园了。
时间离开我们就不会回来了,我们一定要珍惜时间,爱惜时间。
6、教师引导幼儿观察其他记录时间的工具。
三、操作活动:教师引导幼儿自制钟表。
四、延伸活动:1、园内延伸:(1)教师在教区里投放废旧钟表引导幼儿拆装。
(2)教师让幼儿画出不同的钟表并涂上漂亮颜色。
(3)园内完成《操作册》第19、20页。
一年级数学教案:认识钟表上的指针,看看它们指向了什么!钟表是我们日常生活中最常见的工具之一,时刻提醒我们时间的流逝。
而钟表上的指针,表盘,刻度等概念对于孩子们来说,却是比新鲜的。
本篇教案,主要是想带领一年级的小朋友们认识钟表上的指针,看看它们指向了什么。
一、教学目标1、认识钟表上的时针和分针。
2、掌握钟表上的刻度及用时针和分针来读时间。
3、培养学生观察,分析问题的能力。
二、教学内容1、钟表上的概念2、时针和分针的认识3、如何读钟表时间三、教学过程1、上课打卡。
周一早上,开学第一课,不妨先进行一下上课打卡。
这样可以让小朋友们更有参与感,同时也可以为后续的活动铺垫。
2、闹钟启程在上课之前,我们先来一道小游戏吧。
你们有没有在家经常听到一个声音,它嘟嘟嘟地不停响?对了!那就是闹钟!每次当它响起时,我们都会知道时间到了。
但是,你知道它响的是几点吗?如果想了解它响的是什么时间,我们就需要认识一下钟表上的一些概念。
在课堂上,可以准备一个模拟的闹钟,用手摇,放大镜等小物件让小朋友们观察,找出其中有哪些表盘,时针,分针等。
3、时针和分针的认识概念讲得出来,但如果不实际动手演示,让小朋友亲手触摸时针和分针。
他们根本不知道时针和分针是长什么样子的。
因此,我们需要在此环节中,上手示范,让小朋友们能够认真观察和体验。
示范时,可以用一支笔和一张纸把钟盘画出来。
学生们可以在钟盘上面画出两个粗细不同的线。
分别称为时针和分针。
让他们一起用手指移动线模拟指针的转动。
当小朋友们看到指针都不是完好的圆形时,就会认为,钟表上的指针是条线而不是圆形或者是扭曲的线。
仅仅是这样的一个小环节,它的教学收益却是不可估量的。
4、如何读钟表时间学生们学会了时针和分针后,我们就开始了时钟读数环节。
教师示范,时针一圈是12个小时,一小时就是逆时针转30度。
那么,如果时针指向1的位置,那就是1个小时。
如果指向6的位置,就是6个小时。
接着,我们来看看分针。
小时针走1小时,分针就走一圈,也就是60分钟,因此,分针走了一圈就代表了1小时。
指针壹、内存分配表计算机中的内存都是编址的,就像你家的地址一样。
在程序编译或者运行的时候,系统(可以不关心具体是什么,可能是编译器,也可能是操作系统,实际上是二者合作的结果。
)开辟了一张表。
每遇到一次声明语句(包括变量的声明、函数的声明和传入参数的声明等等)都会开辟一个内存空间,并在表中增加一行纪录,记载一些对应关系。
贰、指针就是一个整数指针,是一个无符号整数(unsigned int,因不致歧义下简称“整数”),它是一个以当前系统寻址范围为取值范围的整数。
32位系统的寻址能力(地址空间)是4GB(0~232-1 bytes),二进制表示长度为32bit,也就是4B。
不难验证,在32位系统里,int类型也正好是4B(32-bit)长度,可以取遍上述范围。
同理,64位系统取值范围为0~264-1,int类型长度为8B。
例证就是程序1得到的答案和程序2的答案一致。
(不同机器可能需要调整一下pT的取值。
)程序2第6行加上“(char *)”是因为毕竟unsigned int和char *不是一回事,需要强制转换,否则会有个警告。
既然指针的实质是一个整数,为何不用unsigned int直接声明,或者统一用int *声明,而要用不同的类型后面加上一个“*”表示呢?char *声明过的类型,一次访问1个sizeof(char)长度,double *声明过的类型,一次访问1个sizeof(double)长度。
在汇编里,没有数据类型这一概念,整数类型和指针就是一回事了。
不论是整数还是指针,执行自增的时候,都是将原值加一。
如果上文声明char *pT;,汇编语言中pT自增(INC)之后值为1245049,可是C语言中pT++之后pT值为1245049。
如果32位系统中,上文声明int *pT;,汇编语言中pT自增之后值为1245049,可是C语言中pT++之后pT值为1245052。
为什么DOS下面的Turbo C,和Windows下的VC的int类型自增时的步进不一样长?因为DOS是16位的,Windows x86是32位的,int类型长度取决于操作系统的位长。
可以预见,在Windows x64中编译,上文声明int *pT;,在执行pT++之后pT值为1245056。
那么,复杂的结构怎么分配空间呢?C语言的结构体(汇编语言对应为Record类型)按顺序分配空间。
在32位系统下,内存里面做如下分配:(单位:H,16进制)这就说明了为什么sizeof(pst)=16而不是8。
编译器把结构体的大小规定为结构体成员中大小最大的那个类型的整数倍。
至于pT的存储,可以依例推得。
总长为160,此不赘述。
有个问题,如果执行pT++,答案是什么?是自增16,还是160?别忘了,pT是常量,不能加减。
所以,我们就可以声明:用一个整数,代表一棵树的结点。
把它赋给某个结点的LeftChild/RightChild值,就形成了上下级关系。
只要无法找到一个路径,使得A->LC/RC->LC/RC...->LC/RC==A(A泛指某一结点),这就构成了一棵二叉树。
反之就成了图。
叁、C的按值传递C中函数调用是按值传递的,传入参数在子函数中只是一个初值相等的副本,无法对传入参数作任何改动。
但实际编程中,经常要改动传入参数的值。
这一点我们可以用一个小技巧,即传入参数的地址而不是原参数本身,当对传入参数(地址)取“*”运算时,就可以直接在内存中修改,从而改动原想作为传入参数的参数值。
在执行inc(&a);时,系统在内存分配表里增加了一行“inc中的val”,其地址为新地址,值为&a。
操作“*val”,即是在操作a了。
肆、*和&运算“*p”操作是这样一种运算,返回p的值作为地址之内存空间的取值。
“&p”则是这样一种运算,返回当时声明p时开辟的地址。
显然可以用赋值语句对内存地址赋值。
我们假设有这么一段内存地址空间,他们取值如下:(单位:H,16进制)然后,执行这么一段代码“int *p;”,假设开辟空间时p被分配3001H、3002H两个位置。
则p为2003H,*p为3001H。
(字节序为小尾序,Little-Endian,低位在低地址,Intel的x86系列CPU适用。
Motorola的PowerPC 系列则采用大尾序,Big-Endian,高位在低地址,则上述p为0320H,*p需进一步查内存0320H处的存储值。
)**p的值为多少?**p=*(*(p))=*(*(2003H))=*(3000H)=0300H。
那么&&p、*(&p)和&(*p)又等于多少?&&p=&(&(p))=&(3001H),此时出错了,3001H是个常数怎么可能有地址呢?*&p=*(&(p))=*(3001H)=2003H,也就是*&p=p。
很多人误解了&和*,以为他们互为逆运算,即&*p=p。
实际上&*p=&(*p) =&(3001H),出错了,3001H是个常数怎么可能有地址呢?我们再看看另类的*和&。
这里有两个地方要注意:(1)在程序声明变量的时候的*,只是表明“它是一个整数,这个整数指向某个内存地址,一次访问sizeof(type)长度”。
这点不要和(*)操作符混淆;(2)在C++程序声明变量的时候的&,只是表明“它是一个引用,这个引用声明时不开辟新空间,它在内存分配表加入新的一行,该行内存地址等于和调用时传入的对应参数内存地址”。
这一点不要与“*”声明符和“&”操作符混淆。
伍、双重指针(指向指针的指针)双重指针又是怎么一回事儿呢?综合贰的BTree定义,和叁的说法。
对于一棵树,我们通常用它的根结点地址来表示这棵树。
正所谓“擒贼先擒王”,找到了树的根,其每个结点都可以找到。
但是有时候我们需要对树进行删除结点,增加结点操作,往往考虑到删除根结点,增加的结点取代原来的根结点作为新根结点的情况。
为了修改根结点这个“整数”,我们需要退一步,使用这个“整数”的内存地址,也就是指向这个“整数”的指针。
在声明时,我们用2个*号,声明指向指针的指针。
它的意思是“它是一个整数,这个整数指向某个内存地址,一次访问sizeof(unsigned int)长度,其指向的内存地址所存储的值是一个整数,那个整数值指向某个内存地址,一次访问sizeof(BTree)长度。
”详见“数据结构.rar”有关“树”(06文件夹)的程序代码。
陆、指针数组、数组指针和指向函数的指针指针数组:就是一个整数数组,那个数组的各个元素都是整数,指向某个内存地址。
数组指针:数组名本身就是一个指针,指向数组的首地址。
注意这是声明定长数组时,其数组名指向的数组首地址是常量。
而声明数组并使某个指针指向其值指向某个数组的地址(不一定是首地址),指针取值可以改变。
指向函数的指针:从二进制角度考虑,数组名是该数组数据段首地址,函数名就是该代码段的首地址,可以用“int *fun()”。
在二进制层面,代码段和数据段什么区别?没什么区别。
柒、几个问题下面是关于指针的几个思考题,在文中或许没有提及,然而读者可以自行上机实现之。
1、声明一个指针之后,为什么要立即赋值为NULL?如果不这么做,其初始值是多少?2、声明为void *的指针,一次可以访问多大步长?为什么很多程序在需要传入缓存(Buffer)首地址的时候都习惯在传入参数处声明为(void *Buffer)?3、很多人都说C语言是一种面向过程的语言,因为它最多只有struct的定义,而没有class的概念。
看完本篇后,你认为C语言能成为面向对象的语言吗?如果可以,请给出一个简单的表示。
4、指针和引用只有表示上的差异,而无实质的区别。
那么,Java、C#等语言里没有指针的概念,你认为这样的理解正确吗?如果不赞同,请举出什么情况下传入的参数实际上是其指针而不是副本。
5、指针是一个指向内存地址的整数,如何用这个概念去理解Windows程序设计中的HANDLE(句柄)、RESOURCE (资源)和MESSAGE(消息)?C语言中的指针专题一、数组的指针、指针数组以及指向指针的指针考虑数组的指针的时候我们要同时考虑类型和维数这两个属性。
换一句话,就是说一个数组排除在其中存储的数值,那么可以用类型和维数来位置表示他的种类。
A)一维数组在c和c++中数组的指针就是数组的起始地址(也就第一个元素的地址),而且标准文档规定数组名代表数组的地址(这是地址数值层面的数组表示)。
例如:int a[10]; int *p;</pre>p=&a[0]//和p=a是等价的:因为a是数组名,所以他是该数组的地址,同时因为第一个元素为a[0],那么&a[0]也代表了该数组的地址。
但是我们是不是就说一个数组名和该数组的第一个元素的&运算是一回事呢?在一维的时候当时是的,但是在高维的时候,我们要考虑到维数给数组带来的影响。
a[10]是一个数组,a是数组名,它是一个包含10个int 类型的数组类型,不是一般的指针变量噢!(虽然标准文档规定在c++中从int[]到int*直接转换是可以的,在使用的时候似乎在函数的参数为指针的时候,我们将该数组名赋值没有任何异样),a代表数组的首地址,在数字层面和a[10]的地址一样。
这样我们就可以使用指针变量以及a来操作这个数组了。
所以我们要注意以下问题:(1) p[i]和a[i]都是代表该数组的第i+1个元素;(2) p+i和a+i代表了第i+1个元素的地址,所以我们也可以使用*(p+I)和*(a+I)来引用对象元素;(3)p+1不是对于指针数量上加一,而是表示从当前的位置跳过当前指针指向类型长度的空间,对于win32的int为4byte;B)多维数组对于二维数组a[4][6];由于数组名代表数组的起始地址,所以a(第一层)和第一个元素a[0][0]地址的数字是相同的,但是意义却是不同的。
对于该数组我们可以理解为:a的一维数组(第一层),它有四个元素a[0]、a[1]、a[2]、a[3](第二层),而每个元素又含有6个元素a[0][0],a[0][1],a[0][2],a[0][3],a[0][4],a[0][5](第三层),…到此我们终于访问到了每个元素了,这个过程我们经历了:a->a[0]->a[0][0];整体来讲:a是一个4行5列的二维数组,a表示它指向的数组的首地址(第一个元素地址&a[0]),同时a[0]指向一行,它是这个行的名字(和该行的第一个元素的首地址相同(第一个元素为地址&a[0][0]))。