指针数组与数组指针的区别,指针函数与函数指针的区别

来源:互联网 发布:java excel 换行 编辑:程序博客网 时间:2024/06/08 11:09

指针数组:

array of pointers,即用于存储指针的数组,也就是数组元素都是指针。

如char *p[3]={"aaaa","bbbb","cccc"};

此时就定义了一个指针数组,该数组里面有三个char型指针分别指向a,b,c三个字符串的首地址。

例如

//指针数组char *p5[]={"aaaaa","bbbbbb"};printf("p5:%d\n",sizeof(p5));//输出的大小是两个指针的大小

数组指针:

a pointer to an array,即指向数组的指针

如 int (*b)[4];

即定义了一个指针,该指针指向了一个大小为4*sizeof(int)的数组。

#include <stdio.h>int main(){int c[4]={1,2,3,4};int (*b)[4]; //数组指针b=&c;printf("%d\n",(*b)[1]);//此时输出的结果应该为2return 0;}

函数指针:

int (*pf)();//pf:是一个指向函数的指针,改函数返回一个int型的对象,即pf是指针

借鉴别人的例子就不写了:

  int * GetDate(int wk,int dy);        main()        {            int wk,dy;            do            {                printf(Enter week(1-5)day(1-7)\n);                scanf(%d%d,&wk,&dy);            }            while(wk<1||wk>5||dy<1||dy>7);            printf(%d\n,*GetDate(wk,dy));        }        int * GetDate(int wk,int dy)        {            static int calendar[5][7]=            {               {1,2,3,4,5,6,7},               {8,9,10,11,12,13,14},               {15,16,17,18,19,20,21},               {22,23,24,25,26,27,28},               {29,30,31,-1}            };            return &calendar[wk-1][dy-1];        }        程序应该是很好理解的,子函数返回的是数组某元素的地址。输出的是这个地址里的值。


指针函数:

int *f();//f:是一个函数,它返回一个指向int类型的指针。即本质是一个函数。函数返回类型是某一类型的指针。其中函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。指向函数的指针包含了函数的地址,可以通过它来调用函数
例如:
        void (*fptr)();
    
把函数的地址赋值给函数指针,可以采用下面两种形式:
        fptr=&Function;
        fptr=Function;
    
取地址运算符&不是必需的,因为单单一个函数标识符就标号表示了它的地址,如果是函数调用,还必须包含一个圆括号括起来的参数表。
    
可以采用如下两种方式来通过指针调用函数:
        x=(*fptr)();
        x=fptr();
    
第二种格式看上去和函数调用无异。但是有些程序员倾向于使用第一种格式,因为它明确指出是通过指针而非函数名来调用函数的。下面举一个例子:
 void (*funcp)();        void FileFunc(),EditFunc();        main()        {            funcp=FileFunc;            (*funcp)();            funcp=EditFunc;            (*funcp)();        }        void FileFunc()        {            printf(FileFunc\n);        }        void EditFunc()        {            printf(EditFunc\n);        }        程序输出为:            FileFunc            EditFunc 

指向指针的指针

以下转载:

指针的指针
    
指针的指针看上去有些令人费解。它们的声明有两个星号。例如:
        char ** cp;
    
如果有三个星号,那就是指针的指针的指针,四个星号就是指针的指针的指针的指针,依次类推。当你熟悉了简单的例子以后,就可以应付复杂的情况了。当然,实际程序中,一般也只用到  二级指针,三个星号不常见,更别说四个星号了。
    
指针的指针需要用到指针的地址。
        char c='A';
        char *p=&c;
        char **cp=&p;
    
通过指针的指针,不仅可以访问它指向的指针,还可以访问它指向的指针所指向的数据。下面就是几个这样的例子:
        char *p1=*cp;
        char c1=**cp;
    
你可能想知道这样的结构有什么用。利用指针的指针可以允许被调用函数修改局部指针变量和处理指针数组。
        void FindCredit(int **);        main()        {            int vals[]={7,6,5,-4,3,2,1,0};            int *fp=vals;            FindCredit(&fp);            printf(%d\n,*fp);        }        void FindCredit(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",             0        };        main()        {            char **nm=Names;printf("%c\n",**nm++);            while(*nm!=0)printf("%s\n",*nm++);        }

输出结果


总结

函数指针:void (*f)()
函数返回指针:void *f()
const指针:const int* p
指向const的指针:int *const p
指向const的const指针:const int *const p


0 0