c++指针理解

    我相信c++的初学者经常会对指针引用感到困惑。我想从底层的内存分配的角度,帮助大家理解我们的每一行代码都对内存做了什么事情,帮助大家更好的理解c++语言。

    声明:我下面demo的运行环境是在linux 64位系统下的,所以一个指针所占用的空间是8个字节。如果是32位的操作系统,一个指针占用四个字节。

    首先让我们看一段简单的main函数的代码(每行代码后面跟的注释是cout的输出的内容)


int main()
{
int i = 1;
int* iPonit = &i;


cout << "i = " << i << endl;//i = 1
cout << "iPonit = " << iPonit << endl;//iPonit = 0x7fff33ee981c
cout << "&i = " << &i << endl;//&i = 0x7fff33ee981c
cout << "&iPonit = " << &iPonit << endl;//iPonit = 0x7fff33ee981c
cout << "sizeof(i) = " << sizeof(i) << endl;//sizeof(i) = 4
cout << "sizeof(iPonit) = " << sizeof(iPonit) << endl; //sizeof(iPonit) = 8
cout << "sizeof(&i) = " << sizeof(&i) << endl;//sizeof(&i) = 8
}


从c++内存分配的角度来理解以下这段简单的代码,看看我们这段代码在内存中具体做了什么事情。

int i = 1;

这句代码,我们先在机器的栈区申请了四个字节的内存用来存储一个int类型的数据。(在函数内部申请的内存都是栈内存)。ok,我们申请了这么一块内存,内存中的数据都是01010101 01011111 00000000 00000000这种类型的二进制数据,(申请的内存内的数据是随机的,因为我们尚未进行初始化),我们如何访问内存区域的数据呢,c++给了我们一个机制,叫做别名(你也可以理解成索引),代码中的i 其实就是一个别名,用来代表这块内存块,而int 则是用来修饰i这个别名,表示i存储的是一个四个字节的内存数据。ok,这样我们可以更加方便的访问内存中的变更量。我们执行i = 10的赋值操作。c++通过别名帮助我们将10这个数字转化成二进制的数据,存入我们声请的内存区域。所以我们内存中的值实际编程这样了00000000 00000000 00000000 00000010。


int* iPonit = &i;这句代码又在内存中做了什么事情呢?

我们在栈内存中又申请一块8个字节的内存。我们给这个内存取了一个别名叫做iPonit。int*修饰这个别名,标识iPonit存放的是一个8字节的指针。什么是指针呢?指针就是一个内存中地址的值。也就是说这个8字节的内存区域存放的是内存中另外一个内存区域的地址。所以所有类型的指针都是占用8个字节的内存。我们得到了另外一块内存区域的地址,我们知道这块区域存的是int类型的数据,那么我们可以通过指针访问另外一块内存区域的地址了,这是不是很棒?我们申请了iPonit这个指针,但是如何给iPonit指针赋值呢?

c++提供了一个取地址的符号。我们知道一块内存地址的别名,那么我们可以通过&这个取地址符号得到这块内存的真正内存地址,然后赋值给iPonit。int* iPonit = &i中我们取得了i的地址,然后赋值给iPoint。那么我们如何取得iPonit的地址呢?同理,&iPonit可以取得iPonit的地址。


后面的cout是帮助大家理解,就不深入解释了。



int main()
{
int i = 1;
int i2 = 2;
int* iPonit = &i;
iPonit = &i2; //可以编译通过
iPonit = 0; //可以编译通过
&i2 = 0; //不可以编译通过
}


好现在我们再来理解以下,为什么iPonit = 0可以编译通过吧。&i2 = 0却不能编译通过

iPonit是我们申请的一个指针,iPonit = 0这个操作,我们将这块指针内存的数值赋值为0,当然是可以的。

但是看看&i2 = 0吧。他试图做一件可怕的事情,那就是想改变i2在内存中的实际存放的位置,c++是不提供直接修改内存位置的。就类似于,你在上海建了一栋别墅,但是你又试图将整栋别墅从 上海移动到北京,这个当然是不被允许的。c++的内存管理也是一样,他能让你申请和释放内存,但是不能让你改变内存的位置。


我相信,当能理解c++的每一个语句在内存中都做了什么的时候,对于加了*p, **p。 等等的语法也就想通了。



    

    



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值