不得不说,指针对于学习c/c++的人而言的确是一个头疼但是又特别重要一个问题,在这里,我就将自己的学习经验分享给大家,希望能够帮助更多的人学习。说起指针,或许你还在为到底什么是指针?指针和数组到底是否相等?指针数组是什么?数组指针是什么?函数指针又是什么?函数指针数组,函数指针数组指针它们又是什么?看完这个你就会对指针有更深一步的了解了,下面我为大家一一解答。
1、什么是指针?
要想明白什么是指针首先看这样一个例子:int *a;
...
*a=12;
先想一下,这段代码是否正确?其实这段代码是错误的,它首先声明创建了一个指针变量a,最后的语句是想将12存储在a所指向的内存里,这里的*就代表a是一个指针,它是一个指向4个字节的整型变量,*就好像是防盗门的锁芯,没有这个*,我们就不能读或者写这块内存。代码错误的地方就是声明a这个指针变量的时候,我们没有对它进行初始化,所以我们没有办法预测12这个值将会存储在什么地方,因为我们不知道a到底指向哪里。
所以,一个变量的地址称为该变量的”指针“,指针变量就是专门用来存放另一变量的地址(即指针)的变量,指针变量的值就是地址,占4个字节。所以以后在对指针进行间接访问或者解引用之前,一定要确保他们被初始化,所以以后再声明指针变量的时候最好同时对其初始化。
2、指针和数组是否相等?
实际上,指针和数组并不相等,虽然它们在很多时候是可以互用的。如果你还是对这个结论存有疑虑,那么请看下面的例子:
int a[5];
int *b;
这两行代码都是声明,并且a与b都具有指针值,因为数组名a代表数组首元素的地址即a[0]的地址,b是一个指针变量,而且它们都可以进行解引用和下标引用操作,但是这也不能代表他们是相等的。因为声明一个数组的时候,编译器会根据声明所指定的元素数量为数组保留相应的内存,然后再创建数组名;而声明一个指针变量时,编译器只给指针本身保留内存空间,它并不为任何整型值分配内存空间,而且,指针变量并未被初始化为指向任何现有的内存空间,如果它是一个自动变量,它甚至不会被初始化。
所以上式*a是完全合法的。*b却是非法的,它将访问内存中某个不确定的位置,或者导致程序终止。此外,b++可以通过编译,a++却不行,因为a是个常量值,它代表数组首元素的地址。因此指针和数组不相等。
指针变量在32位系统下永远只占4个字节,它的值为某一内存的地址。数组的大小与元素的类型和个数有关,定义数组时必须指明元素的类型和个数,数组可以存任何类型的数据,但是不能存函数。
3、指针数组是什么?数组指针是什么?
指针数组它首先是一个数组,数组的元素都是指针,数组占多少字节由数组本身决定。数组指针首先它是一个指针,它指向一个数组,在32位系统下永远只占4个字节。这里,我们需要知道[ ]的优先级高于*,而()得优先级又高于[ ],所以我们就很容易就可以判断出int *p1[10];是一个指针数组,int (*p2)[10];是一个数组指针。
4、函数指针是什么?
函数指针就是函数的指针,它是一个指针,指向一个函数。下面我们看一个函数指针应用的例子:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *fun(char *p1, char * p2)
{
int i = 0;
i = strcmp( p1, p2 );
if (0 == i)
{
return p1 ;
}
else
{
return p2 ;
}
}
int main()
{
char *(*pf)(char *p1, char *p2); //通过(*pf)取出存在这个地址上的函数即fun函数,然后调用它。
pf = &fun;
(*pf)( "aa", "bb" );
system( "pause");
return 0;
}
在这里,我们有必要看一个有趣的例子:(*(void(*)( ))0) ( );看一下。你是否能看懂它代表的是什么?看不懂别着急,我会慢慢剖析给你看,然后你就会觉得它也没有表面上看着那么难懂了。 ( *(void (*) ( ) )0 ) ( );这样将上面代码分隔开来,看起来是不是好看多了?
1、 void(*)( )这是一个函数指针类型,这个函数没有参数,也没有返回值。
2、(void(*)( ))0这是将0强制类型转换函数指针类型,这里的0不同于寻常的0,它在这里是一个地址,即一个函数保存在一段首地址为0的区域中。
3、(*(void(*)( ))0)这是对上面所说的进行了解引用。
4、(*(void(*)( ))0) ( )这是函数调用。
5、函数指针数组是什么?函数指针数组指针又是什么?
char *(*pf[3])(char *p);这段代码就是定义函数指针数组,它是一个数组,数组名为pf,数组内存储了三个指向函数的指
针,这些指针指向一些返回值类型为指向字符的指针,参数为一个指向字符的指针的函数,这样分析起来是不是容易理解多了。其实还有一个简单的方法就是倒着看,它先是数组,然后它存储了指针,这些指针又指向函数。
函数指针数组指针实际上就是一个指针,这个指针指向了一个数组,这个数组里面存储的是指向函数的指针,它同样也可以利用我上面所说的倒着看的方法进行分析。