/*--------------------------------概念------------------------------------------*/
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。
要搞清一个指针需要搞清指针的四方面的内容:
[1]指针的类型,
[2]指针所指向的类型,
[3]指针的值或者叫指针所指向的内存区,
[4]还有指针本身所占据的内存区。 --sizeof(指针变量名) 一般32位机都为4;
指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。当你对C越来越熟悉时,你会发现,把与指针搅和在一起的"类型"这个概念分成"指针的类型"和"指针所指向的类型"两个概念,是精通指针的关键点之一。
[1]指针的类型: (指针本身在内存中的样子,类型)
从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。
[用途]在指针的赋值运算时,知道了指针的类型就可以来定右值得类型了;
[2]指针所指向的类型:指针所指向的内存块里应存的是什么样子(类型)的东东)
当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。
[3]指针的值或者叫指针所指向的内存区:
指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。
[小结]
int(*ptr)[3];
//指针的类型是int(*)[3] -- 一个数组指针,它相当于行指针,它所指的都是一个int()[3]--一维数组;
//指针所指向的的类型是int()[3] -- 这个就是这个指针所指的内存中应存的东西的类型,及一维数组;
指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在上面,指针所指向的类型已经有了(声明了),但由于指针还未初始化(未定义,未初始化),所以它所指向的内存区是不存在的,或者说是无意义的。
以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指的类型是什么?该指针指向了哪里?
注意不知道指针指向哪里就开始用是很危险及隐蔽的错误!!!
-------------------------------------实例分析----------------------------------
例1:
1、chara[20];
2、int*ptr=a;
...
...
3、ptr+=5;
在这个例子中,ptr被加上了5,编译器是这样处理的:将指针ptr的值加上5乘sizeof(int),在32位程序中就是加上了5乘4=20。由于地址的单位是字节,故现在的ptr所指向的地址比起加5后的ptr所指向的地址来说,向高地址方向移动了20个字节。在这个例子中,没加5前的ptr指向数组a的第0号单元开始的四个字节,加5后,ptr已经指向了数组a的合法范围之外了。虽然这种情况在应用上会出问题,但在语法上却是可以的。这也体现出了指针的灵活性。
[说明]
[1]因为指针的类型是int *,所以在第2步时不要误认为指针的类型是a的类型(char);
[2]指针现在指向长度为20字节的数组a的首地址了,在第三句时ptr所指的地方正好越出了数组的边界 -- a[19] or (ptr+19)了.