指针数组、数组指针、函数指针、指针函数总结

指针数组、数组指针、函数指针、指针函数总结
2014-11-11指针数组 && 数组指针
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
char *a[ 5 ];     
//定义一个指针数组, 数组的元素都是char *指针类型。初始化也可以在里面存放字符或字符串。a的类型是char *[5]
//若char *a[5]={"red","white","blue","dark","green"};
//a在这里的类型是char *[],实质上是一个二级指针。也就是说a所代表的那块内存里面存放着的是数组中第一个元素的地址。
//a+1所代表的那块内存里面存放着的是数组中第二个元素的地址,依此类推……
//a[0]就是“red”字符串的地址,printf("%s",a[0]);
//a[0]+1,表示在"red"字符串的地址上偏移一个位置,访问字符'c'.printf("%c",*(a[0]+1))
//若a的地址是0x0000000,则a+1的地址是0x00000008(64位平台)或0x00000004;
 
int (*ptr)[ 5 ];   
//定义一个指向数组的数组指针ptr,它的实际类型为char (*)[5],(数字可以忽略)因为在有些严格的编译器中不同时会提出警告
再定义一个二维数组 int a[ 1 ][ 5 ]={ 1 , 2 , 3 , 4 , 5 };
//a的类型为int [1][5](数字可以忽略),列的维度相同,p=a可以赋值。
也就是说此时数组指针ptr可以看做一个二级指针,它的用法跟 char **a相同。
从上面我们可以看到char (*)[]、 char [][]、char **其实可以看成是等价的
?
1
 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
int main( void )
{
     char *a[ 5 ]={ "red" , "white" , "blue" , "dark" , "green" };
     printf( "%s    %c    %s\n" , a[ 0 ], *(a[ 0 ]+ 1 ), a[ 1 ]+ 1 );
     printf( "%x    %x\n" ,a[ 0 ], a[ 1 ]);
     char m[ 2 ][ 5 ]={ "xxx" , "yyyy" };
     char (*ptr)[ 5 ]=m;
     printf( "%x    %s    %s    %x    %s\n" , ptr[ 0 ], ptr, ptr[ 1 ], ptr[ 0 ]+ 2 , ptr[ 0 ]+ 1 );
     printf( "%d    " ,sizeof(a));
     printf( "%d    " ,sizeof(m));
     return 0 ;
 
}
</stdio.h>
@1 定义指针数组,组中元素均为char *类型

@2 定义数组指针,ptr类型为char (*)[],m类型为char [][],这两类型间是可以赋值的。但他们不是完全等价的。

@3 a的类型为char*[5],sizeof(a)=sizeof(char *)*5; m的类型为char [][]的二维数组,sizeof(m)求得它在内存中实际所占字节,有些编译器出于效率考虑会对字节进行对齐。

运行结果如下

\

常见误区

?
1
2
3
4
5
6
7
8
9
10
double n = 2.0 , *pt=&n;
printf( "double %d %d\n" , pt, pt+ 1 ); //差为8
     
char c= 'm' , *q=&c;
printf( "char %d %d\n" , q, q+ 1 ); //差为1
 
char **p=&q;
printf( "%d %d" ,p ,p+ 1 ); //差为4
 
printf( "%d %d %d" ,sizeof( int *), sizeof( double *), sizeof( char *), sizeof( int **));
//从结果中可以发现,不论什么类型的指针在内存中都是占四个字节的大小存放


函数指针 && 指针函数

  函数指针和其它指针一样,对函数指针执行间接访问之前必须把它初始化为指向某个函数。

  下面是一种初始化函数指针的方法:

  int fun( int );

int ( * pf ) ( int ) = &fun;

创建函数指针pf并将其指向函数fun。在函数指针的初始化之前具有fun的原型是很重要的,否则编译器无法检查fun的类型与pf所指向的类型一致。

 

初始化声明后,我们可以有以下三种方式调用函数:

int ans;

1) ans = fun( 25 );

2) ans = ( *pf ) ( 25 );

3) ans = pf ( 25 );

语句1简单的使用名字调用函数fun。但它的执行过程可能跟你想的不一样:函数名fun首先被转换为一个函数指针,该指针指向内存中的一块位置。然后,函数调用操作符调用函数,执行开始于这个地址的代码。

语句2对pf执行间接访问操作,将pf转换为函数名。但这种转换其实是不必要的,编译器在执行函数调用操作符之前又会把它转换回去。

语句3和前两条执行效果一样的。

 

函数指针的常见用途就是把函数指针作为参数传递给函数,下面是例子。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
#include <string.h>
int compare_int( void const *a, void const *b)
{
     if ( *( int *)a == *( int *)b)
         return 0 ;
     else
         return 1 ;
}
int compare_char( void const *a, void const *b)
{
     if (strcmp (( char *)a, ( char *)b) == 0 )
         return 0 ;
     else
         return 1 ;
}
void Compare( void const *a, void const *b, int (*compare)( void const *, void const *))
{
     if (compare(a, b) == 0 )
         printf( "they are equal\n" );
     else
         printf( "not equal\n" );
}
int main( void )
{
     int m= 4 ,n= 5 ;
     Compare(&m, &n, compare_int);
     char a[ 4 ]= "abc" ,b[ 4 ]= "abc" ;
     Compare(a, b, compare_char);
} </string.h></stdio.h>

运行结果:

使用以上技巧的函数被称为回调函数(callback function)。用户将一个函数指针作为参数传递给其它函数,后者将“回调”用户的函数。分别为比较整型与字符串编写不同的比较函数compar_int(void const *,void const *)和compar_char(void const *,void const *),通过向Compare(const void *,const void *,int (*compare)(void const *, void const *))传递不同的函数指针,通过同一接口实现对不同类型数据的比较。

 

指针函数,指针函数是指带指针的函数,即本质是一个函数。函数都有返回类型(如果没有返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。

转载于:https://www.cnblogs.com/shsgl/p/4091059.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值