指针的指针

函数指针

我们知道,一个指针变量可以指向整型变量,字符串,数组,也可以指向一个函数。一个函数在编译的时候被分配给一个入口地址,这个入口地址就称为函数的指针可以用一个指针变量指向函数,然后通过指针变量调用这个函数。因为每个函数都占有一段内存单元,它们有一个起始地址。所以,我们可以用一个指针变量指向一个函数,通过指针变量来访问它指向的函数。

如:

#include "stdio.h"

main()

{

    int max( int,int );

    int (* p)();

    int a,b,c;

    p = max;

    scanf( "%d,%d",&a,&b );

    c = (* p)(a,b);

    printf( "a = %d,b = %d,max

= %d",a,b,c );

    getch();

}

 

max( int x,int y )

{

    int z;

    if( x>y )z = x;

    else z = y;

    return(z);

}

我们看到,其中int (* p)();首先,p*结合,表明了p是一个指针变量,后面的括号表明指针是指向函数的。 int表明了此函数带回了整型的返回值

赋值语句“p = max;”的作用是将函数max 的入口地址赋给指针变量p。和数组名代表数组起始地址一样,函数名代表该函数的入口地址。也就是说,pmax都指向函数的开头。值得注意的是,p是指向函数的指针变量,它只能指向函数的入口处,而不能指向函数中间的某一条指令处,因此不能用*p+1)来表示下一个指令。

(1)       指向函数的指针变量的一般形式为:

数据类型   * 指针变量名 )();

数据类型指的是函数返回值的类型。

(2)       函数的调用可以通过函数名调用,也可以通过函数指针调用。

(3)          *p)()表示定义一个指向函数的指针变量,它不固定指向哪一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存入函数的入口地址的。要调用的时候,程序把哪一个函数的地址赋给它,它就指向哪一个函数。也就是说,一个指针变量可以先后指向返回类型相同的不同函数。

(4)          在给函数指针变量赋值时,只需要给出函数名而不必给出参数。如:

P = max;

因为是将函数入口地址赋给p,而不牵涉到实参与形参的结合问题。不能写成“p = max(a,b)”形式

(5)          在函数指针变量调用时,只需要将(*p)代替函数名即可。在(*p)后的括号中根据需要写上实参。如下面程序表示:“调用由p指向的函数,实参为a,b。得到的函数值赋给c。”

c = (* p)(a,b);

 (6)对于指向函数的指针变量像p++,p--等运算是无意义的。

 数组指针:

一个数组,其元素均为指针类型数据,称为指针数组。也就是说,指针数组中的每一个元素都相当于一个指针变量。一维指针数组的定义形式为:

类型名    * 数组名[数组长度]

例如:  int * p[22]

P先与[ ]结合,形成p[22]的形式,就显然是数组形式,它有22个元素,然后再与p前面的“*”结合,“*”表示此数组是指针类型的,每个数组元素(相当于一个指针变量)都可以指向一个整型变量。

 

为什么要用到指针数组呢?它比较适合于用来指向若干个字符串,使字符串处理起来更加方便。也会节省更多的内存单元。

比如:分别定义一些字符串,然后用指针数组中的元素分别指向各字符串,如果想对字符串排序,只需要改变指针数组中各元素的指向(即改变各元素的值,这些值是各字符串的首地址),这样,各字符串的长度可以不同,而且移动指针变量的值(地址)会比移动字符串所花的时间少得多。

比如:

#include

#include

 

void main()

{

    void sort( char *name[],int n );

    void print( char * name[],int n );

    char * name[] = { "Follow me","BASIC","Great Wall","FORTRAN","Computer"};

    int n = 5;

    sort( name,n );

    print( name,n );

    getch();

}

 

void sort( char * name[],int n )       //对书排序

{

    char * temp;

    int i,j,k;

    for( i = 0;i< span>

    {

        k = i;

        for( j = i+1;j<>

            if(strcmp( name[k],name[j])>0)k = j;

        if( k!=i )

            {temp = name[i];name[i] = name[k];name[k] = temp;}

    }

}

 

void print( char * name[],int n )       //打印出来

{

    int i = 0;

    char * p;

    p = name[0];

    while(i< span>

    {

        p = *(name+i++);

        printf("%s/n",p);

    }

}

指针的指针:

怎么样定义一个指向指针数据的指针变量呢?例如:

char **p

因为*运算符的结合性是从右向左,所以它相当于:**p),显然,(*p)是指针变量的定义形式,如果没有前面的*,那就是定义了一个指向字符数据的指针变量,现在它前面又多了一个*,表示指针变量p指向一个字符指针变量的。(*p)是p指向的另一个指针变量。

例:

void main()

{

    char * name[] = { "Follow me","BASIC","Great Wall","FORTRAN","Computer"};

    char **p;

    int i;

    for( i = 0;i<5;i++)

  &nbsp; {

        p = name + i;

        printf("%s/n",*p);

    }

    getch();

}

我们知道,在赋值的时候,p = name + i;是指p指向指针数组的第i行,加一个*后,*p是指向数组的第i行第0列的首地址,再加一个*后, **p指向第i行第0列地址中的内容

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值