天天看点

c语言指针函数和函数指针整理

一、 函数指针

格式如下: 类型说明符 (*函数名)(参数)

说明:

(1)其实这里不能称为函数名,应该叫做指针的变量名。

(2)首先它是一个指针,只是这个指针指向的是一个函数。指针变量可以指向变量的地址、数组、字符串、动态分配地址,同时也可指向一个函数,每个函数在编译的时候,系统会分配给该函数一个入口地址,函数名表示这个入口地址,那么指向函数的指针变量称为函数指针变量。

(3)备注: 指针名和指针运算符外面的括号改变了默认的运算符优先级。如果没有圆括号,就变成了一个返回整型指针的函数的原型声明。

例子:

int (*select) (struct inode * ,struct file *, int ,select_table *);

int (*ioctl) (struct inode * ,struct file *, unsinedint ,unsigned long);

int (*mmap) (struct inode * ,struct file *, structvm_area_struct *);

***注意int(*read)是加上括号的。

二、指针函数

 格式:类型说明符 * 函数名(参数)

说明:

(1)由于返回的是一个地址,所以类型说明符一般都是int。

(2)首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。

例子:

float *fun();

float *p;

p = fun(a);

***注意指针函数与函数指针表示方法的不同,千万不要混淆。最简单的辨别方式就是看函数名前面的指针*号有没有被括号()包含,如果被包含就是函数指针,反之则是指针函数。

代码:

int *f(int a, int b); // 声明指针函数  

int *f(int a, int b) {  

   int *p = (int *)malloc(sizeof(int));  /*建立(动态申请)一块内存空间,建立的内存空间为一个整型变量的长度,并把建立的空间地址转化成指向整型的指针赋值给前面的整型指针变量p*/      

   printf("The memeory address of p = 0x%x \n", p);  

   memset(p, 0, sizeof(int));  /*把第0到第sizeof(int)个字节全替换为p类型 */      

   *p = a + b;  

    printf("*p = %d \n", *p);  

    return p;  //返回指针

}  

推荐参考博客网址:

http://blog.csdn.net/ameyume/article/details/8220832

三、指针的指针

指针的指针看上去有些令人费解。它们的声明有两个星号。

例子:char ** cp;

如果有三个星号,那就是指针的指针的指针,四个星号就是指针的指针的指针的指针,依次类推。当你熟悉了简单的例子以后,就可以应付复杂的情况了。当然,实际程序中,一般也只用到二级指针,三个星号不常见,更别说四个星号了。

    指针的指针需要用到指针的地址。

        char c='A';

        char*p=&c;

        char**cp=&p;

    通过指针的指针,不仅可以访问它指向的指针,还可以访问它指向的指针所指向的数据。下面就是几个这样的例子:

        char *p1=*cp;

        char c1=**cp;

        voidFindCredit(int **);

        main()

        {

           int vals[]={7,6,5,-4,3,2,1,0};

           int *fp=vals;

           FindCredit(&fp);

           printf(%d\n,*fp);

        }

        voidFindCredit(int ** fpp)

        {

           while(**fpp!=0)

           if(**fpp<0) break;

           else (*fpp)++;

        }

    首先用一个数组的地址初始化指针fp,然后把该指针的地址作为实参传递给函数FindCredit()。FindCredit()函数通过表达式**fpp间接地得到数组中的数据。为遍历数组以找到一个负值,FindCredit()函数进行自增运算的对象是调用者的指向数组的指针,而不是它自己的指向调用者指针的指针。语句(*fpp)++就是对形参指针指向的指针进行自增运算的。但是因为*运算符高于++运算符,所以圆括号在这里是必须的,如果没有圆括号,那么++运算符将作用于二重指针fpp上。

四、指向指针数组的指针

    指针的指针另一用法旧处理指针数组。有些程序员喜欢用指针数组来代替多维数组,一个常见的用法就是处理字符串。

        char *Names[]=

        {

            Bill,

            Sam,

            Jim,

            Paul,

            Charles,

        };

        main()

        {

           char **nm=Names;

           while(*nm!=0) printf(%s\n,*nm++);

        }

    先用字符型指针数组Names的地址来初始化指针nm。每次printf()的调用都首先传递指针nm指向的字符型指针,然后对nm进行自增运算使其指向数组的下一个元素(还是指针)。注意完成上述认为的语法为*nm++,它首先取得指针指向的内容,然后使指针自增。

    注意数组中的最后一个元素被初始化为0,while循环以次来判断是否到了数组末尾。具有零值的指针常常被用做循环数组的终止符。程序员称零值指针为空指针(NULL)。采用空指针作为终止符,在树种增删元素时,就不必改动遍历数组的代码,因为此时数组仍然以空指针作为结束。

继续阅读