几种常见语言的基本语法对比:最终阐述 指针,值和引用

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

基础知识

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++的引用不是存在更改指针的情况。

 

 

转载于:https://www.cnblogs.com/lsfv/p/9709104.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值