从内存角度理解指针和数组(一)(二)

2014-11-24 00:43:46 · 作者: · 浏览: 9
[cpp]
p++ // 等效p = 0x0000B000+1*sizeof(long int *)
*p 永远表示:将p的值作为内存地址后,读取存在该内存中的值。但是p只是一块内存的首地址,并不知道要读取的值占了多少空间啊,这就要归功于(long int **)了,编译器看到这句话后去掉一个*后就可以得知:以该地址起,存的是一种long int *的数据。那么就从以p值作为首地址一次性读取sizeof(long int *)个字节。
为什么二级指针还是能顺利读取数组的值呢,因为(long int **)p, *p还是表示的是(long int *)类型的指针并不是一个long int的值啊?
要理解这个问题的根本在于:不管p是几级指针,*p永远表示以p所指内存地址为首地址的值。至于该值占多少字节,就需要看去掉一个*后的类型。所以不管什么类型,多少级指针,那些只是编译器编译所需的指导信息,到了程序运行期间,所有的事情在内存中就表现为读写,而这种读写行为的两个必须条件:从哪里开始读,读多少个字节。这里需注意到我的机器:sizeof(p)= sizeof( long int ) = 8。
总结:
1,不管什么类型的变量,类型是用来给编译器确定变量需要的内存空间,变量是一块内存的别名,数组的变量是存储数组元素的一块内存的首地址;
2,不管用几级指针去操作几维数组都是可以的,只要指针的基本移步操作的步长等于数组元素的大小;
3,数组名可以赋值给指针(不管几级指针,需要强制转换),要说它们的区别(对编译器而言)主要有两点:
a,指针只是保存了首地址,丢失了所指内存当中,存储的元素个数的信息(单个元素的大小信息是知道的,由去掉一个*号后余下部分来指定)。所以将指针作为函数的形参,通常也会定义一个整形形参来指定元素的个数。
b,数组有维度信息,即首地址、单个元素的大小以及元素的个数。