关于指针和数组

指针数组

指针数组,从名字就可以看出,指针数组本质上数组,组内元素由指针构成。下面列出几种常见的指针数组类型用来加深大家对指针数组的理解;

int *a[10];
char *b[10];
char **c[10];

数组指针

数组指针是指针,表示一个指向数组的指针,在32位系统下占4个字节。下面列出的就是数组指针。

int (*p)[10];
int (*)[10] p2;

区分指针数组还是数组指针的方法就是首先明白“[ ]”的优先级要高于“的有优先级,”()”的优先级高于“[ ]”,在“int* (p)[10]”中,和p构成一个指针的定义,指针变量名为p,int修饰的是指针指向的数组的元素。数组在这里没有名字,是个匿名数组。p2中int (*)[10]是指针类型,p2是指针变量。

指针和数组

指针和数组是具有本质上的区别的。

  • 指针变量在32位系统下永远占32个byte,其值为某一个内存的地址。指针可以指向任何地方,但不是任何地方都可以通过这个指针变量访问到。对指针的访问可以以指针的形式或者下标的形式访问。分别为(p+2)和p[2],这两种访问在本质上没有什么区别。 (p+2)表示先取出p中储存的地址,然后加上2个字符的偏移量得到新的地址。p[2]表示先取出p里存储的地址,再加上2个元素的偏移量,计算出新的地址,然后从新的地址中取出值。
  • 数组的大小与元素的类型和个数有关。定义数组时必须指定其元素的类型和个数。数组可以存放任何类型的数据,但无法存放函数。数组也同样可以通过下标和指针的形式来访问,原理与上述指针内容同理。
  • 在向函数传参时,无法传递一个数组,当一维数组作为函数参数的时候,编译器总是把它解析成一个指向其首元素地址的指针。并且在传参中,指针本身也无法被传递,只能对指针做一份临时拷贝进行传递。

函数指针

  • 函数指针的定义
A), char* (*fun1)(char *p1,char*p2);
B), char**fun2(char*p1,char*p2);
C), char* fun3(char*p1,char*p2);

上述三个表达式的含义分别为:
A):这里的fun1不是函数名,而是一个指针变量,指向一个函数。这个函数有两个指针类型的参数,函数的返回值也是一个指针。
B):fun2是函数名,p1和p2是指针类型参数,函数的返回值是一个char**类型的二级指针。
C):fun3是函数名,p1和p2是参数,类型为char*,函数的返回类型也为char *。

  • 函数指针的使用
    我们使用函数指针的时候,需要通过“*”来取出存在这个地址上的函数,然后来调用,给函数指针渎职是可以用&函数名或者直接用函数名,这是因为函数名被编译后就是一个地址,所以&函数名和函数名没有什么区别。接下来举例说明函数指针的创建和使用。
void Function()
{
printf("Call Founction\n");
}
int main()
{
  void (*p)();
  *(int*)&p = (int)Founction;
  (*p)();
  return 0;
}

首先void(*p)()是定义了一个指针变量p,p指向一个函数,这个函数的参数和返回值都是void。&p是求指针变量p本身的地址,这是一个32位进制的2进制常数(32位系统)。
(int*)&p表示将地址强制类型转换成指向int类型的指针。(int)Founction表示将函数的入口地址强制转换成int类型的数据。
(int )&p = (int)Founction表示将函数入口的地址赋给指针变量p。
(*p)()表示对函数进行调用。
清楚了函数指针的调用方法后,我们可以再来试一试了解一个例子:(* (void( *)())0)();
我们可以尝试分步对这个表达式进行解析:
第一步:void(*)(),这是一个函数指针类型,这个函数没有参数和返回值。
第二步:(void(*)())0,这是把0强制转换为函数指针类型,0是一个地址,也就是说一个函数存在首地址为0的一段区域内。
第三步:((void()())0),这是取0地址开始的一段内存里面的内容,其内容就是保存在首地址为0的一段区域的函数。
第四步:((void()())0)()表示对该函数进行调用。

函数指针的数组

现在我们可以定义一个函数指针类似“char* (* p)(char * src);”,期中p为函数指针,既然p是指针,那么p就可以保存到一个数组里面。例如“char *( *p[3]) (char *src);”就是定义了一个函数指针数组,这是一个数组,数组名为p,数组内储存了3个指向函数的指针,这些指针指向一些返回值为字符的指针,参数为指向字符的指针的函数。

函数指针数组的指针

函数指针数组的指针归根结底也是一个指针,里面用来存放一个数组,这个数组里面存放的是指向函数的指针。下面就顶一个简单的函数指针数组的指针:

char*(*(*p)[3])(char* src);

在这里p是一个指针,指向一个包含了3个元素的数组,这个数组里面存放了指向函数的指针,这些指针指向一些返回值类型为指向字符的指针,参数为一个指向字符指针的函数。

猜你喜欢

转载自blog.csdn.net/higher_and/article/details/80270031
今日推荐