指针与函数及指针与数组之间的关系

来源:互联网 发布:pid控制算法 编辑:程序博客网 时间:2024/05/16 07:20

首先大家应该清楚指针与数组没有关系!

数组与指针

1、sizeof中数组名单独使用的时候为整个数组,数组名如果不单独使用则为首元素地址。

例如:sizeof(a)->数组名在sizeof中单独使用,则求的是整个数组的长度

    sizeof(a+1)->数组名没有单独使用则为首元素的地址,所以(a+1)为第二个元素的地址

2、“a”为首元素的地址,而“&a”为整个数组的地址

例如:sizeof(a+1)->数组名没有单独使用则为首元素的地址,所以(a+1)为第二个元素的地址

    sizeof(&a+1)->下一个数组的地址

总结;(1)取地址数组名->整个数组

                   sizeof数组名->整个数组

                   其他均为首元素地址

         (2)a+1->第二个元素的地址

                   &a+1->数组指针,指向下一个数组

3、指针数组、数组指针:

(1)很多人会问指针数组到底是指针还是数组呢?

a.指针数组是数组,是一个存放指针的数组。

(如果不能理解,就可以想:像整型数组一样,是一个数组里面存放的都是整型。指针就像整型一样是一个类型)

b.数组指针是指针,这个指针有能力指向一个数组。

例如:int *arr[10]->指针数组

   int(*p)[10]->整型数组指针(对p加一实际为加40,因为p指向数组,所以给p加一其实加的是数组的大小)

如何判断是指针数组还是数组指针?

看p先和谁结合,看“*”和“[ ]”谁的优先级更高。因为“[ ]”的优先级更高,所以第一个为数组,而第二个给*p加了“()”所以p先和“*”结合,则为指针。

int(*p[5])[10]->数组指针数组

int(*(*p)[5])[10]->数组指针数组的指针

int arr[10]={0};

所以&arr 为整个数组地址->数组指针

则从严格意义上讲: int*p1 = &arr   这样就是不对的,因为左值为整形指针,而右值为数组指针。

4、数组传参时,第一个维度可以被忽略

例如:void print(int arr[3][5])

    void print(int arr[ ][5])

任何维度数组都认为成一维数组

指针传参时也要形成临时变量

5、定义:需要开辟空间,声明:不需要开辟空间

数组的定义:char arr[]="abcdef"

数组的声明:extern char arr[ ]->声明一个变量时不需要写初始值:a.第一个维度是被忽略的b.声明不需要开辟空间


函数与指针

1、函数指针:第一条指令的地址,可以为该函数的函数名或对该函数取地址
函数名代表地址等同于&函数名
例如:main = &main

   fun = &fun

函数名具有只读属性,不会做左值

2、

void (*pfun1)();->指向一个返回值为空参数列表为空的函数的指针

void *pfun2();->返回值为void*的函数

如何判断是函数指针?

看p先和谁结合,看“*”和“()”谁的优先级更高。因为“()”的优先级更高,所以第二个为函数,而第一个给*p加了“()”所以p先和“*”结合,则为指针。

例如:(*(void(*)())0)();->调用该函数

首先先看:(void(*)())->函数指针类型

(void(*)())0->把“0”强转成函数指针

(*(void(*)())0)->函数

(*(void(*)())0)();->调用该函数

例如;void  ( * signal ( int ,  void ( * ) ( int ) ) )( int );

首先先看:void ( * ) ( int ) ->函数指针

    signal ( int ,  void ( * ) ( int ) )->函数signal(int,函数指针)


3、函数指针数组

例如:int(*parr1[10])( );

函数指针数组的用途:转移表

例如:int(*p[5])(int x,int y) = {0,add ,sub,mul,div};



4、指向函数指针数组的指针:

是一个指针,指针指向一个数组,数组的元素都是函数指针

例如:void  (*pfunArr[5])(const  char *str)->函数指针数组

   void (*(*ppfunArr)[10])(const  char *)->函数指针数组的指针



总结:判断是指针还是数组还是函数,就看和谁先结合