指针
一、
(1)指针变量的内容
变量的值就是分配给该变量的内存位置所存储的数值,即使是指针变量也不例外。(类型决定我们看待变量内部数据的方式)
解引用指针(间接访问):通过一个指针访问它所指向的地址的过程。使用单目操作符 * 。
(2)指针的指针:
* 操作符具有从右向左的的结合性,所以**c相当于*(*c)。*c访问c所指向的位置,即变量b,*(*c)访问这个位置所指向的地址,即变量a。
二、
(1)指针和数组,没有关系,但在访问元素时有很大的相似性。
(2)数组名代表整个数组时的两种情况:
<1>sizeof(数组名);
<2>&数组名。
三、
(1)指针数组:指针数组是一个 存放指针 的 数组。
如:
int *arr[10];
int *a[20];
int *p[5];
指针数组可以作为函数的参量使用,使用方式与普通数组类似。
指针数组常适用于指向若干字符串,这样使字符串处理更加灵活方便。
(2)数组指针:
如:
<1>int (*)p[10];//数组指针,指向数组的指针。
注:p先和*结合,说明p是一个指针变量,然后指针指向的是一个大小为10个整形的数组。所以p是一个指针,指向一个数组,叫数组指针。([ ]的优先级要高于*的,所以必须加上()来保证p先和*结合)
<2>数组的地址的存储:
int arr[10]={0};
int (*p)[10]=&arr;//p是数组指针,存放数组的地址。
<3>数组在进行传参时,会降成其内部元素所指类型的指针。
void test()
{
int arr[3][5] = { 0 };
ptint(arr);//二维数组降维成一级数组指针
}
void print(int arr[3][5])
{
}
void print(int arr[][5])//第一个中括号里面的数字可省略
{
}
void print(int (*arr)[5])//降维
{
}
四、
<1>函数指针
最常见的两个用途:转换表和作为参数传递给另一个函数。
注意:简单声明一个函数指针并不意味着他马上就可以使用。和其他指针一样,对函数指针执行间接访问之前必须把它初始化为指向某个函数。
<1、int f(int);
int (*pf)(int )=&f;
第二个声明创建了函数指针pf,并把它初始化为指向函数f。函数指针的初始化也可以通过一条赋值语句来完成。
在函数指针被声明并且初始化之后,可使用三种方式调用函数:
int ans;
ans=f(25);//使用名字调用函数f,函数名f先被转换为一个函数指针,指定函数在内存中的位置;然后函数调用操作符调用该函数,执行开始于这个地址的代码
ans=(*pf)(25);//对pf执行间接访问操作,把函数指针转换为一个函数名
ans=pf(25);//效果同前两条
<2、
1>(*(void(*)( )) 0 )( ) //函数调用
分析:(void(*)( ))【函数指针类型】对0进行强转,把0当做函数地址,再解引用
2>void (*signal(int ,void(*)(int) ) )(int); //函数
<2>函数指针数组:把函数的地址存到一个数组中,那么这个数组就叫做函数指针数组。
定义:int (*parr[10])( );
<3>指向函数指针数组的指针
指向函数指针数组的指针是一个 指针;
指针指向一个 数组,数组的元素都是 函数指针。
void test(const char* str)
{
ptintf("%s\n",str);
}
int main()
{
//函数指针pfun
void(*pfun)(const char*) = test;
//函数指针的数组pfunArr
void(*pfunArr[5])(const char* str);
pfunArr[0] = test;
//指向函数指针数组pfunArr的指针ppfunArr
void(*(*pfunArr)[5])(const char* str) = &pfunArr;
return 0;
}