理解指针之基础篇
2012-04-08 22:30
127 查看
理解指针
指针是程序开发中经常使用的类型,然而却对它的概念一直迷迷糊糊的,经常犯一些莫名其妙的错误,甚至对一些用法不知其意。今天看了一些指针的文章,做一下总结。
准确的说,指针也是一种变量,特殊的是该类型变量存储的是内存地址。举个例子.
上述表达式中,指针a指向了一个整形变量,上述表达式映射到内存中,其存储方式如图1所示:
图1
从图1中可以看出,指针a的值为10004688,内存中地址10004688处存储了值为5的整形,我们说指针a指向的整形值为5.
当然指针指向的值也可以是其他类型,比如如下类型:
那么,既然都是指针类型,那么他们之间能进行复制吗?比如c = f.答案是否定的。虽然他们都是指针,但是他们指向的具体类型是不一样的,编译器在编译时,会检查指针所指向的具体类型,当指向的具体类型不一样,是无法编译通过的.因此有必要更加具体的说明指针的类型,我们称之为指针类型。也就是说,虽然指针的值都是内存单元地址,但是它们的类型还是各不相同的,如果上面的几个例子来说,a的类型是int*,c的类型是char*,以此类推.
既然指针也是有类型,那么如何确定指针是什么类型的呢?很简单,获取普通变量的类型方法一样.见如下代码:
g的类型是int,h的类型是char,只要去掉变量名便可获得变量类型,对于指针也是如此,见如下代码:
去掉变量名后,i和j的类型分别是int*和char*,此时我们说i的类型是int*,j的类型是char*。既然指针有类型,那么我们如何声明一个指针呢?声明的方法也很简单,只需在普通类型后加*便可.比如我们要声明一个双精度类型的指针.只需按如下方法书写即可.
通过上述说明相信你应该明白了指针变量的值、指针变量的类型、指针所指向的值一直指针所指向的值的类型.理解这些概念后,你对指针就有了初步的了解。下面我们将进一步介绍指针与数组的关系.
我们经常用指针来操作数组,因此有必要介绍一下指针与数组的关系.分析如下数组:
上述代码中定义一个数组,该数组中含有10个int类型的成员,该数组在内存中的镜像如图2:
图2
从图2中可以看出arr内存储了一个内存地址,该地址为数组的首个元素地址。因此,arr也是一个指针,该指针指向的即是数组的首个元素.同样的我们可以看出,由于数组的内容连续的存放在内存空间中,因此只要通过简单的运算,以arr的值作为基值,便可得出数组第二个元素、第三个元素的地址,从而获取或修改其值.下面我们就将介绍指针如何运算.
上面介绍到数组的名称,也是指向数组第一个算是的指针,我们可以通过这个指针的运算,获取其他元素的内存地址。那么具体的是如何获取其他元素的内存地址呢?方法很简单,比如获取第二个元素的地址代码如下:
上述代码中,我们定义了一个int*类型的指针p,并将p赋值为arr+1.此时指针p便指向了数组的第二个元素.请注意,此处不能对指针arr进行操作,如arr++或arr
= arr+1是非法的,因为arr使用指向数组的首个元素,如果它的值发生改变,将不一定指向数组的首个元素,因此它是不可被修改的.
对于上述代码中p = arr + 1,是不是表示p的值为10006689呢?答案是否定的,此处的加1,代表加一个单位指针所指向的类型长度.对于上式,指针指向的类型是int,int类型在内存中占4个字节,因此p
= arr + 1后p的值将比arr的值多4,变成10006682;验证程序如下:
运行结果如下:
由上可知,对于字符型的指针来说char* c; c++后,c的值将比原来多2,因为字符在内存中占用两个字节.以此类推可以得出其他类型,进行指针运算后,其值的变化情况.
获得指针后,我们便可以通过指针来获取,指针所有指向的内存单元的值了,那么如何取值呢?
运行结果如下图所示:
指针是程序开发中经常使用的类型,然而却对它的概念一直迷迷糊糊的,经常犯一些莫名其妙的错误,甚至对一些用法不知其意。今天看了一些指针的文章,做一下总结。
什么是指针
int * a; |
上述表达式中,指针a指向了一个整形变量,上述表达式映射到内存中,其存储方式如图1所示:
图1
从图1中可以看出,指针a的值为10004688,内存中地址10004688处存储了值为5的整形,我们说指针a指向的整形值为5.
char * c; float* f; bool* b; |
那么,既然都是指针类型,那么他们之间能进行复制吗?比如c = f.答案是否定的。虽然他们都是指针,但是他们指向的具体类型是不一样的,编译器在编译时,会检查指针所指向的具体类型,当指向的具体类型不一样,是无法编译通过的.因此有必要更加具体的说明指针的类型,我们称之为指针类型。也就是说,虽然指针的值都是内存单元地址,但是它们的类型还是各不相同的,如果上面的几个例子来说,a的类型是int*,c的类型是char*,以此类推.
int g; char h; |
Int* i; Char* j; |
去掉变量名后,i和j的类型分别是int*和char*,此时我们说i的类型是int*,j的类型是char*。既然指针有类型,那么我们如何声明一个指针呢?声明的方法也很简单,只需在普通类型后加*便可.比如我们要声明一个双精度类型的指针.只需按如下方法书写即可.
double* a; |
指针与数组
Int arr[10] = {1,2,3,4,5,6,7,8,9,10}; |
上述代码中定义一个数组,该数组中含有10个int类型的成员,该数组在内存中的镜像如图2:
图2
从图2中可以看出arr内存储了一个内存地址,该地址为数组的首个元素地址。因此,arr也是一个指针,该指针指向的即是数组的首个元素.同样的我们可以看出,由于数组的内容连续的存放在内存空间中,因此只要通过简单的运算,以arr的值作为基值,便可得出数组第二个元素、第三个元素的地址,从而获取或修改其值.下面我们就将介绍指针如何运算.
指针的运算
Int arr[10] = {1,2,3,4,5,6,7,8,9,10}; Int* p; p = arr + 1; |
上述代码中,我们定义了一个int*类型的指针p,并将p赋值为arr+1.此时指针p便指向了数组的第二个元素.请注意,此处不能对指针arr进行操作,如arr++或arr
= arr+1是非法的,因为arr使用指向数组的首个元素,如果它的值发生改变,将不一定指向数组的首个元素,因此它是不可被修改的.
int _tmain(int argc, _TCHAR* argv[]) { int arr[10] = {1,2,3,4,5,6,7,8,9,10}; int* p; p = arr + 1; printf("arr: %d\n",arr); printf("p: %d\n",p); int wait; scanf("%d",&wait); return 0; } |
= arr + 1后p的值将比arr的值多4,变成10006682;验证程序如下:
运行结果如下:
由上可知,对于字符型的指针来说char* c; c++后,c的值将比原来多2,因为字符在内存中占用两个字节.以此类推可以得出其他类型,进行指针运算后,其值的变化情况.
获得指针后,我们便可以通过指针来获取,指针所有指向的内存单元的值了,那么如何取值呢?
取值与取址
通过指针运算得到一个新地址后,地址本身对我们没什么意义,有意义的是该地址处,存放的值,那么如何取值呢?c语言为我们提供了取值符号*,该符号与指针定义时使用的符号一样.只不过放的位置有点区别,指针定义时,*号是放在类型之后,表示该类型指针,取值的时候,指向把*号放于指针变量之前即可.如对于上述数组指针运算,如果想取得第二个元素的值,直接使用*p即可。与取值向对应的是取址,即获取一个指定变量所存放的内存地址,C语言为取址提供的符号是&,想获得某个变量的地址时,指向将&放于其前即可.下面的代码展示了如何取值和如何取址:int _tmain(int argc, _TCHAR* argv[]) { int a = 5; int* b; b = &a; printf("%d\n",&a); printf("%d\n",b); printf("%d\n",*b); int wait; scanf("%d",&wait); return 0; } |
相关文章推荐
- 【c语言基础】字符串数组与字符串指针的理解心得
- C基础知识之理解指向函数的指针
- 【C语言基础】对指针数组,数组指针,函数指针, 函数指针数组,指向函数指针数组的指针的理解
- 【c基础】对函数指针的详细理解
- C/C++基础———C/C++中函数指针和数组指针、数组名的一些个人理解
- 理解C语言-第21课-指针基础
- C++ 指针基础理解
- 指针的基础理解,以及引用的理解
- 对指针的基础理解
- C语言中 指针的基础知识总结, 指针数组的理解
- 对C语言中指针的理解与其基础使用实例
- 对数组和指针的基础理解
- 深入理解指针
- [C++学习历程]基础部分 C++中的指针数组和结构
- 从四个属性的角度来理解C语言的指针也许会更好理解
- 网络基础知识讲座之八:初步理解IP协议
- [3D基础]理解计算机3D图形学中的坐标系变换
- 进程,线程基础理解
- 位运算的基础知识点(关联指针、数组的操作)
- 深入理解C语言指针的奥秘