码迷,mamicode.com
首页 > 其他好文 > 详细

指针不再是你的拦路虎....................千万不可错过!!

时间:2016-01-22 03:14:24      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:指针   指针数组   数组指针   函数指针等   

    不得不说,指针对于学习c/c++的人而言的确是一个头疼但是又特别重要一个问题,在这里,我就将自己的学习经验分享给大家,希望能够帮助更多的人学习。说起指针,或许你还在为到底什么是指针?指针和数组到底是否相等?指针数组是什么?数组指针是什么?函数指针又是什么?函数指针数组,函数指针数组指针它们又是什么?看完这个你就会对指针有更深一步的了解了,下面我为大家一一解答。

1、什么是指针?

      要想明白什么是指针首先看这样一个例子:int *a;

                                              ...

                                             *a=12;

先想一下,这段代码是否正确?其实这段代码是错误的,它首先声明创建了一个指针变量a,最后的语句是想将12存储在a所指向的内存里,这里的*就代表a是一个指针,它是一个指向4个字节的整型变量,*就好像是防盗门的锁芯,没有这个*,我们就不能读或者写这块内存。代码错误的地方就是声明a这个指针变量的时候,我们没有对它进行初始化,所以我们没有办法预测12这个值将会存储在什么地方,因为我们不知道a到底指向哪里。

     所以,一个变量的地址称为该变量的”指针“,指针变量就是专门用来存放另一变量的地址(即指针)的变量,指针变量的值就是地址,占4个字节。所以以后在对指针进行间接访问或者解引用之前,一定要确保他们被初始化,所以以后再声明指针变量的时候最好同时对其初始化。

2、指针和数组是否相等?

     实际上,指针和数组并不相等,虽然它们在很多时候是可以互用的。如果你还是对这个结论存有疑虑,那么请看下面的例子:

                     int   a[5];

                int    *b;

这两行代码都是声明,并且a与b都具有指针值,因为数组名a代表数组首元素的地址即a[0]的地址,b是一个指针变量,而且它们都可以进行解引用和下标引用操作,但是这也不能代表他们是相等的。因为声明一个数组的时候,编译器会根据声明所指定的元素数量为数组保留相应的内存,然后再创建数组名;而声明一个指针变量时,编译器只给指针本身保留内存空间,它并不为任何整型值分配内存空间,而且,指针变量并未被初始化为指向任何现有的内存空间,如果它是一个自动变量,它甚至不会被初始化。

     所以上式*a是完全合法的。*b却是非法的,它将访问内存中某个不确定的位置,或者导致程序终止。此外,b++可以通过编译,a++却不行,因为a是个常量值,它代表数组首元素的地址。因此指针和数组不相等。

     指针变量在32位系统下永远只占4个字节,它的值为某一内存的地址。数组的大小与元素的类型和个数有关,定义数组时必须指明元素的类型和个数,数组可以存任何类型的数据,但是不能存函数。

3、指针数组是什么?数组指针是什么?

    指针数组它首先是一个数组,数组的元素都是指针,数组占多少字节由数组本身决定。数组指针首先它是一个指针,它指向一个数组,在32位系统下永远只占4个字节。这里,我们需要知道[ ]的优先级高于*,而()得优先级又高于[ ],所以我们就很容易就可以判断出int  *p1[10];是一个指针数组,int  (*p2)[10];是一个数组指针。

4、函数指针是什么?

    函数指针就是函数的指针,它是一个指针,指向一个函数。下面我们看一个函数指针应用的例子:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>


char *fun(char *p1, char * p2)

{

           int i = 0;

          i = strcmp( p1, p2 );

           if (0 == i)

          {

                    return p1 ;

          }

           else

          {

                    return p2 ;

          }

}

int main()

{

           char *(*pf)(char *p1, char *p2);   //通过(*pf)取出存在这个地址上的函数即fun函数,然后调用它。

          pf = &fun;

          (*pf)( "aa", "bb" );

          system( "pause");

           return 0;

}

    在这里,我们有必要看一个有趣的例子:(*(void(*)( ))0) ( );看一下。你是否能看懂它代表的是什么?看不懂别着急,我会慢慢剖析给你看,然后你就会觉得它也没有表面上看着那么难懂了。  (    *(void   (*)  ( )   )0     )   ( );这样将上面代码分隔开来,看起来是不是好看多了?

     1、 void(*)( )这是一个函数指针类型,这个函数没有参数,也没有返回值。

     2、(void(*)( ))0这是将0强制类型转换函数指针类型,这里的0不同于寻常的0,它在这里是一个地址,即一个函数保存在一段首地址为0的区域中。

     3、(*(void(*)( ))0)这是对上面所说的进行了解引用。

     4、(*(void(*)( ))0) ( )这是函数调用。

5、函数指针数组是什么?函数指针数组指针又是什么?

       char *(*pf[3])(char *p);这段代码就是定义函数指针数组,它是一个数组,数组名为pf,数组内存储了三个指向函数的指


针,这些指针指向一些返回值类型为指向字符的指针,参数为一个指向字符的指针的函数,这样分析起来是不是容易理解多了。其实还有一个简单的方法就是倒着看,它先是数组,然后它存储了指针,这些指针又指向函数。

       函数指针数组指针实际上就是一个指针,这个指针指向了一个数组,这个数组里面存储的是指向函数的指针,它同样也可以利用我上面所说的倒着看的方法进行分析。


本文出自 “10911544” 博客,转载请与作者联系!

指针不再是你的拦路虎....................千万不可错过!!

标签:指针   指针数组   数组指针   函数指针等   

原文地址:http://10921544.blog.51cto.com/10911544/1737475

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!