您的位置:首页 > 编程语言 > C语言/C++

C语言之函数、指针、数组二重奏

2011-12-17 21:48 162 查看
什么是数组指针,什么是指针数组?

什么是函数指针?什么是指针函数?

说说经常让人晕头转向的**指针、指针**

先声明:()、[] 的优先级大于*

指针**:(指针函数和指针数组)

指针函数:本质上是个函数,其返回值为指针,如: int* fun()

指针数组:依然是个数组,不过数组中的元素全是指针,即“XX的地址”如int* arr[10];

**指针:(函数指针和数组指针)Pay Attention

函数指针:本质上是个指针,该指针指向函数的入口地址;编译时编译器会为每个函数分配一个入口地址,这个入口地址其实就是该函数中第一条指令的地址,即为函数的指针。

声明形式为:函数类型(*指针变量名)();使用之前必须提前声明

如:int (*pFun)(int,int);

//pFun就是一个指针变量,指向一个返回值为int的函数,该函数有两个int形参

//pFun的类型为int(*)(int,int)

函数原型为:int Fun(int,int)

函数指针的赋值:pFun=Fun或者pFun=&Fun,即可将pFun指向函数Fun的地址;编译器会自动将Fun转化为&Fun;

使用函数指针调用函数原型:使用(*pFun)(实参1,实参2)或者pFun(实参1,实参2)来调用函数Fun;编译器会自动将pFun转化为(*pFun)。

函数指针最常用的地方就是作为参数传递给其他函数,来实现回调,即在运行时决定调用哪个函数原型,来实现动态绑定;感觉就像C++中用虚函数来实现运行时绑定的机制。

例如

void fun1(int a){...}

void fun2(int b){...}//回调函数

void callFun(int,void(*pfun)(int)){...}//函数内使用pfun调用

call: callFun(实参,fun1);

callFun(实参,fun2);//运行时动态决定调用fun1或者fun2

数组指针:本质依然是指针,其指向一个数组,与函数指针类似。

如:int (*pArr)
;

//pArr为一个指针变量,指向一个大小为N的int型一维数组,pArr即为数组元素的首地址。同时需要注意的是,pArr的步长也为N,即执行pArr+1时,实际上将pArr当前指向的地址+N*sizeof(int),pArr跨度为N个int型元素。

例如:

int calendar[12][31];//定义一个日历数组

int (*pMonth)[31];//pMonth为数组指针

//遍历整个日历

//pMonth为calendar的首地址,即为calendar[0]或者&calendar[0][0]

for(pMonth=calendar;pMonth<&calendar[12];pMonth++)

{

int* pDay;//指向天数组(int [31])的指针,即指向*pMonth

for(pDay=*pMonth;pDay<&(*pMonth)[31];pDay++)

*pDay=0;//happy每一天

}


无论是函数指针还是数组指针,其本质都是个指针变量,只不过所指向的内容不同;无论是指针函数还是指针数组,其本质都未改变,只不过存储的内容为指针。有没有发现,其本质依然是其名称的后两个字。

最后想说说函数参数传递的方式,指针无非就是0x12345678之类的地址值。而C语言中函数参数传递的方式只有一种,那就是传值,有人可能会辩解还有传指针啊,殊不知指针(地址)本质上其实也是值,依然是传值,只不过我们可以通过传递指针来改变某些内容。引用是C++才引入语言特性。

当采用传值方式时,在函数内会拷贝传递的实参,操作的是实参的副本,而不会直接跟实参打交道,即不会改变实参的值;当传递一个指针时,函数内同样会拷贝该指针的值,我们不能改变该指针本身的值(0x12345678),但是可以通过操作该指针来改变指针所指向的内存单元中的值。所以,传递指针本质上还是传值的方式。

而C++中的引用只是变量的别名,引用不是值,不占用内存空间,即引用只能有声明,不能有定义,而且声明时就必须初始化,一旦初始化便不能更改,不存在空引用。函数形参中传递引用时不会拷贝实参建立副本,而是直接操作实参原值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: