zoukankan      html  css  js  c++  java
  • 几种常见语言的基本语法对比:最终阐述 指针,值和引用

    做一个小结,终结值和引用的疑惑。

    基础知识

    1.bit & byte

    所有的数据最终在内存或硬盘都是电信号,表示为0或者1.我们叫0,或者1为1  bit。

    8个bit叫做一个 byte,也叫Byte。为了避免bit缩写混淆 。b转制bit .B专指Byte.

    一个字节是0xaa, 最大表示255 。 0xf是半个字节,4个bit,最大为15.

    2.指针寻址,容量,带宽 。

    我们通常说的指针地址,如32位 0xaabbccdd,他可以寻找到内存中的某一个位置,而地址+1的意思。0xaabbccde,是加了一个字节,地址+1,内存是加了8bit=1byte.

    硬盘也是如此。我们通常说的硬盘大小也是以字节为单位。40gB.意思就是可以存储40g个字节。如果是ACSII码。也就是40G 个英文字母。

    但我们的宽带却一般用的是bit为单位。所以要除8.     10m的意思。就是一秒可以传递 10/8 m个英文字母。

    3. c++ 的一种内存 模型。

    4.数字在内存的表示。

    如int a=10,在内存的表示为: 0x0a 0x00 0x00 0x00,

    int 32位。所以4个字节。高位到低位是从右边向左边。记住一个关键点,必须以字节为单位,而不是 每个bit都反过来。是4个字节 ,按字节反过来就是 00 00 00 0a,

    1,值

    值很好理解,如下图数字 5.

    2.指针,引用

    指针,在32位系统中,就是32bit。4字节。存储了一个地址,指向了实际存储数据的地方。

    主要是看传参的情况。

    1.在c++中。

    指针有很多情况

    Book *mybook;  可修改对象和指针本身。

    const Book *mybook. 不可以修改对象数据。

    Book const *mybook. 不可以修改指针本身。

    指针已经可以满足一切了,但是太灵活,所以c++引入了 引用。

    2。 引用

    引用就是某一变量(目标)的一个别名,目的就是保证一个非空且指向地址是不可变的。好处,想想看。看到引用符号,就可以保证,他一定不会是null,一定不会因为空指针导致程序奔溃,你如何都不能吧他指向null,最多是把的所指的数据改为null。这就是好处。

    但是本质上就是指针,最最重要的特性就是无法取得指针的地址。&会指向指针所指内容。

    因为引用存在的意义就是一个目标的别名,来方便一些情况。 所以编译器必须保证不能让你去修改指针本身,但目前的技术和现实下引用的实现是通过指针来实现的。

    book &myb=*mybook1;

    book &myb2=mybook2;

    这里2个引用。当然是必须有一个4字节的空间来存储指针。但是无论你如何操作,都没有办法查看到myb本身的地址。

    引用特性:

    0.编译器不会让你获得存放指针的地址。导致网上很多文章说引用不占内存。

    1.不需要->符号来指向变量。而是直接用.

    2.必须初始化

    3.不能修改引用本身(也就是不能修改指针本身)

    这里例子,一个是指针,一个是引用,但是内存中是一模一样。压入参数的时候,实际都是压入 堆的地址。 

    void ChangeID1(Book *mybook,int id)
    {
        int temp=3;
        mybook->id=id;
        cout<<mybook<<endl;
        cout<<&mybook<<endl;
    }
    
    void ChangeID2(Book &mybook,int id)
    {
        int temp=3;
        mybook.id=id;
        //cout<<mybook<<endl;
        cout<<&mybook<<endl;
    }
    
    Book cplus=Book();
    ChangeID1(&cplus,19);
    ChangeID2(cplus,10);
    
    
    changeid1 函数内 内存布局
    0x00007fffffffe054: 0x13 0x00 0x00 0x00  : ????
    0x00007fffffffe058: 0xa0 0xe0 0xff 0xff  :  àÿÿ
    0x00007fffffffe05c: 0xff 0x7f 0x00 0x00  : ÿ???
    
    changeid2 函数内,内存布局。
    0x00007fffffffe054: 0x0a 0x00 0x00 0x00  : ????
    0x00007fffffffe058: 0xa0 0xe0 0xff 0xff  :  àÿÿ
    0x00007fffffffe05c: 0xff 0x7f 0x00 0x00  : ÿ???

     

    3.更高级语言.c# 和 java 的传参

     分析下更高级语言.c# 和 java。

    更高级语言,基本都是把对象放入到堆中。不像 c++那样,对象还 可以放入到栈中。值得一提的是,早期的含有指针的语言object-c ,就非常明智的 限定了对象必须到堆中。为了更统一的编程风格,牺牲了栈性能,鼓掌。

    c#下,典型的例子。2个对象赋值,会发生什么?

    static void ChangeID(Book book)
    {
    book.id=4;
    Book otherbook = new Book();
    book = otherbook;
    }

    测试发现是,book的对象地址和otherbook的地址变成一样了。

    java ,没有直接内存查看工具。所以只是打印了结果。现象表示和c#应该是一样。传递指针,函数内部拥有指针副本。 对象赋值,本质上是指针副本,复制指针而已。

    这样看来,和c++的这个例子基本相似

    void overfristbook(Book *mybook1,Book *mybook2)
    {
    int temp=1;
    mybook1=mybook2;
    }

    和c++的引用反而根本不想。

    所以。。。很郁闷。引用这个概念,java 和c#是一致的。但是他们和c++完全不一样。

    java 和c#所说的引用,完全就是c++的指针,而不是引用。因为java 和c#可以更换引用类型所指的对象。而c++引用是不能变更对象的。

    总结一下

    c++:

    指针:就是指针,指向一块内存。 指针赋值给另一个指针:指针复制给了后者也就是所谓的浅copy.

    引用:某个对象的别名,发明它的意义是获得一个不 为空的对象。但在编译器层面还是由指针来实现,但无法获得引用的存储地址(虽然有)。只能获得指向地址。 、引用赋值给另外一个引用:后者指向的数据被复盖,也就是所谓的深拷贝。(是不是完全深拷贝,应该不是)

    c#,  java

    指针:没有这个概念

    引用:一个概念,但行为就像c++的指针,反而不像c++的引用。 为什么,看引用间的赋值。

    引用赋值给另外一个引用:指针复制给了后者,也就是所谓的浅copy. 而c++的引用不是存在更改指针的情况。

     

  • 相关阅读:
    让我们来学学css3 media queries的使用吧
    Emmet(zen coding)文档(一)[译文]
    给自己不同网站的密码加密
    Photoshop图层混合模式原理(公式)
    3dsmax设置贴图路径为相对目录
    ImageMagick
    FireBreak框架: 用C++打造多浏览器支持的插件
    粒子滤波算法
    页端3d技术
    RANSAC算法
  • 原文地址:https://www.cnblogs.com/lsfv/p/9709104.html
Copyright © 2011-2022 走看看