指针与储物箱的关系

news/2024/10/17 22:13:46/
指针类型是C++、Pascal等语言中比较重要的数据类型。在使用上很灵活。在C++中可以使用如下的语句一个int指针类型:
int   * p;
如果要为指针变量赋值,可以使用如下的语句:
     int  x  =   4 ;
    
int   * p;
    p 
=   & x;
对于初学者来说,可能理解指针比较困难。实际上,在定义指针变量时,就相当于为该指针变量分配一个32位的内存空间(4个字节长)来保存内存地址(仅限于32位操作系统)。为而指针变量赋的值实际上就是一个变量(可能是简单类型变量,也可能是复杂类型变量)的首地址。对于32位操作系统来说,不管是什么类型的变量,地址都是4位的(占一个int类型的空间)。  对于两个指向同一个地址的指针变量,改变一个指针变量所指向的数据,都么另一个指针变量所指向的数据也将改变,如下面的代码所示:
     int  x  =   4 ;
    
int   * p1,  * p2;
    p1 
=   & x;  p2  =   & x;
    
* p1  =   12 ;
    printf(
" %d " * p2);
上面的代码将输出12。
对于指针的概念及用途,我们也可以做一个形象的比喻。假设有两个储物箱A和B。有两个人P1和P2。 在A中放置了很多东西,而B是空的。P1拥有A和B的钥匙,而P2只拥有B的钥匙。并且P1不能直接给P2钥匙。 那么P2该如何取得A中的物品呢?(注意,不能直接把A撬开哦,要用钥匙打开)。
方法吗有如下两个:
1.  P1将A和B打开,将A中的物品放在B中。
2.  P1只将B打开,将A的钥匙放在B中。
第一种方法是直接将A中的物品放在了B中,这么做的好处是无论A发生的什么事,都不会影响B中的物品。但缺点是太麻烦,而且如果A中物品很多的话,是很浪费时间的。而且B的存储空间要和A的一样多才能存放A中所有的物品。
第二种方法是P1通过B将A的钥匙将给了P2,这种方法的好处是方便,而且B也不需要和A一样大,实际上,只要能放下一把钥匙即可。但缺点是A可能不只一把钥匙,如果其他人使用了A的钥匙打开A,并动了A中的物品,那么会直接影响到P2所取得的物品。
我们可以将A和B看作是内存中的两个存储区域。对于第一种方法来说,实际上相当于如下的代码:
    typedef  struct
    {
         
int  x
         
int  y;
         
float   abc;

    } MyStruct;

    
//   相当于A中的物品
    MyStruct A;
    
//   B参数相当于B储物箱
     void   MyMethod(MyStruct B)    
    {
          
    }
    
//   将A中的物品放入B中
   MyMethod(A);

     从上面的代码可以看出,将A传入MyMethod方法中需要将A中所有的内容复制到MyMethod的方法栈中,这是很耗费内存资源的。但在MyMethod方法中修改B中的内容,并不会影响到A。但如果使用下面的代码,就会是另外一个样子。
     //   B参数只用于保存钥匙,也就是4个字节的指针
     void   MyMethod(MyStruct  * B)    
    {
          
    }
    
//   将A的钥匙(指针)放到B中
   MyMethod( & A);
上面的方法很节省内存空间,但在MyMethod方法中修改B指向的结构体中变量的值,也同样会影响到A中相应变量的值。
读者在使用指针时,可以将指针相象成储物箱的钥匙。当定义一个指针变量时,就相当于建立一个只用于储放钥匙的储物箱。而我们为这个变量赋值时,只能放钥匙(指针)或相当于钥匙大小的其他物品。一个指针变量可以当成一个int变量来使用,如下面的代码也是正确的:
     int  x  =   1234 ;
    
int   * p;
    p 
=  ( int * )x; 

    上面的代码将x中的值强行转换成了整型指针,实际上,这个指针的值就是1234。也就是说,x变量的值变是一个内存地址了。
    那么指针的指针呢,也就是 int **p;,那么我们再加一个储物箱C吧。B保存了A的钥匙,而C保存了B的钥匙。只要取得了C的钥匙,就可以按图索骥地打开A。
也就是说 ,对于int **p,p中保存了是一个地址,但这个地址指向的内存空间保存了也是一个地址,而这个地址所指向的内存空间保存的才是真正的数据(int类型)。如果是int ***p,那就再加一个储物箱吧。哈哈。
也许有的读者可能会注意到本文前面所说的第一种方法是将A中的物品放到B中,那么A中不就没了,这不就相当于把A变量清空了,哈哈,没错。不过这个比喻只是为了使读者更容易理解指针的含义和优缺点。如果不想把A清空,就把A中的物品想象成可复制的就可以了,如光盘,把A中的光盘复制一份放到B中,那就更麻烦了。哈哈!




 本文转自 androidguy 51CTO博客,原文链接:http://blog.51cto.com/androidguy/216686 ,如需转载请自行联系原作者

http://www.ppmy.cn/news/533339.html

相关文章

NGUI官网示例13 –Character角色装配与储物箱(三)

该部分主要是为实现装备在拖动的时候出现拖动图标的效果和当鼠标放置在装备上时提示装备的一些信息而做准备。 使用UI Tool创建一个Simple 2D UI层级结构,其Layer为2DGUI,我们通过不同的图层的设置让摄像机只显示我们设定的图层中的对象,有点…

Linux5.8 MySQL主从复制与读写分离

文章目录 计算机系统5G云计算第四章 LINUX MySQL主从复制与读写分离一、概述及原理1)什么是读写分离2)为什么要读写分离呢3)什么时候要读写分离4)主从复制与读写分离5)mysql支持的复制类型6)主从复制的工作…

西安阿里云代理商:阿里云服务器的可扩展性和弹性如何?是否支持按需付费?

西安阿里云代理商:阿里云服务器的可扩展性和弹性如何?是否支持按需付费?   一、阿里云服务器的可扩展性   阿里云作为业界知名的云服务提供商,其服务器具有极强的可扩展性。可扩展性主要体现在以下几方面:   1. …

行为型模式--状态模式

目录 举例 状态模式 定义 结构 代码实现 优缺点 优点: 缺点: 使用场景 举例 【例】通过按钮来控制一个电梯的状态,一个电梯有开门状态,关门状态,停止状态,运行状态。每一 种状态改变,都…

剑指 Offer 55 - II. 平衡二叉树 / LeetCode 110. 平衡二叉树(二叉树后序遍历)

题目: 链接:剑指 Offer 55 - II. 平衡二叉树;LeetCode 110. 平衡二叉树 难度:简单 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 …

MySQL权限控制及日志管理

MySQL权限控制及日志管理 用户权限管理 创建用户 CREATE USER 用户名IP地址 [ IDENTIFIED BY 密码 ];GRANT SELECT ON *.* TO 用户名’IP地址’ IDENTIFIED BY "密码";--创建一个用户名为Usr1 密码为 Usr1.mysql的用户 并授权 CREATE USER…

【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念

系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 文章目录 系列文章目录前言一、所有权(Ownership)1.1.、所有权(Ow…

【JUC(一)】进程、线程与管程

1 进程 1.1 概述 进程:程序是静止的,进程实体的运行过程就是进程,是系统进行资源分配的基本单位 进程的特征:并发性、异步性、动态性、独立性、结构性 线程:线程是属于进程的,是一个基本的 CPU 执行单元…