理解指针之基础篇

来源:互联网 发布:美化你的声音 知乎 编辑:程序博客网 时间:2024/06/08 11:18

理解指针

指针是程序开发中经常使用的类型,然而却对它的概念一直迷迷糊糊的,经常犯一些莫名其妙的错误,甚至对一些用法不知其意。今天看了一些指针的文章,做一下总结。

什么是指针

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;

g的类型是int,h的类型是char,只要去掉变量名便可获得变量类型,对于指针也是如此,见如下代码:

去掉变量名后,ij的类型分别是int*char*,此时我们说i的类型是int*,j的类型是char*。既然指针有类型,那么我们如何声明一个指针呢?声明的方法也很简单,只需在普通类型后加*便可.比如我们要声明一个双精度类型的指针.只需按如下方法书写即可.

double* a;

通过上述说明相信你应该明白了指针变量的值、指针变量的类型、指针所指向的值一直指针所指向的值的类型.理解这些概念后,你对指针就有了初步的了解。下面我们将进一步介绍指针与数组的关系.

指针与数组

Int arr[10] = {1,2,3,4,5,6,7,8,9,10};

我们经常用指针来操作数组,因此有必要介绍一下指针与数组的关系.分析如下数组:

         上述代码中定义一个数组,该数组中含有10int类型的成员,该数组在内存中的镜像如图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(intargc, _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;

}

对于上述代码中p = arr + 1,是不是表示p的值为10006689?答案是否定的,此处的加1,代表加一个单位指针所指向的类型长度.对于上式,指针指向的类型是intint类型在内存中占4个字节,因此p = arr + 1p的值将比arr的值多4,变成10006682;验证程序如下:

         运行结果如下:

由上可知,对于字符型的指针来说char* c; c++,c的值将比原来多2,因为字符在内存中占用两个字节.以此类推可以得出其他类型,进行指针运算后,其值的变化情况.

获得指针后,我们便可以通过指针来获取,指针所有指向的内存单元的值了,那么如何取值呢?

取值与取址

         通过指针运算得到一个新地址后,地址本身对我们没什么意义,有意义的是该地址处,存放的值,那么如何取值呢?c语言为我们提供了取值符号*,该符号与指针定义时使用的符号一样.只不过放的位置有点区别,指针定义时,*号是放在类型之后,表示该类型指针,取值的时候,指向把*号放于指针变量之前即可.如对于上述数组指针运算,如果想取得第二个元素的值,直接使用*p即可。与取值向对应的是取址,即获取一个指定变量所存放的内存地址,C语言为取址提供的符号是&,想获得某个变量的地址时,指向将&放于其前即可.下面的代码展示了如何取值和如何取址:

int _tmain(intargc, _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;

}

 

 

运行结果如下图所示:

 

原创粉丝点击