前方一大波指针正在赶来~

原创 2016年05月30日 13:34:59

我们知道,通常我们来访问数组元素和指针变量的时候都可以通过下标和偏移两种方式来访问,那么他们有什么不一样的地方呢?

wKioL1ZijAuQEKFXAABLi_GPCH0242.png

我们来看一个小栗子:

int main ( )
{
             int a [5] = { 1, 2 , 3, 4, 5 };
             int *ptr = (int *)(& a + 1 );
             printf( "%d %d\n" ,*(a+ 1),*(ptr -1));
             system("pause" );
             return 0 ;
}

##对指针进行的加一操作实际上加的是指针类型的大小而不是以字节为单位。

&a+1:取出数组的首地址,在该地址上面加上一个sizeof(a)的值,即&a+5*sizeof(int)

 a+1:数组第二个元素的地址

二维数组

int arr[i][j]  访问方式:*(*(arr+i)+j)       

int main ( )
{
             int arr [3][ 2] = { (0 , 1), ( 2, 3 ), (4, 5) };
             int  *p ;
             p = arr [0];
             printf( "%d" , p[ 0] );
             system("pause" );
             return 0 ;
}

结果:1

详解:在数组中我们用括号将元素包含在其中,我们认为它是逗号表达式,在数组初始化的时候之初始化逗号表达式里最后一个元素。所以arr[0][0]=1  

         上述程序中p=a[0]相当于p=&a[0][0]。 

int main ( )
{
             int a [5][ 5];
             int( *p )[4];
             p = (int (*)[4]) a;
             printf( "%p ,%d\n" , &p[ 4][2 ] - &a[ 4][2 ], &p[ 4][2 ] - &a[ 4][2 ] );
             system("pause" );
             return 0 ;
}

结果: FFFFFFFc  -4

详解:我们使用一个大小为4的数组指针来访问了一个大小为5 的数组,在p的眼中默认它的数组大小是4,所以每次它的外层下标加一被默认为越过了4个元素,

          而a的外层下标加一被默认为是越过了5个元素

int main ( )
{
             int aa [2][ 5] = { 1 , 2, 3, 4 , 5, 6, 7 , 8, 9, 0 };
             int *ptr1 = (int *)(& aa + 1 );
             int *ptr2 =/*(int *)*/(*( aa + 1 ));
             printf( "%d%d" , *(ptr1 - 1), *(ptr2 - 1) );
             system("pause" );
             return 0 ;
}

结果:10 5

详解:&aa+1指向0后面的元素,强转成int之后-1则向前偏移一个整形空间

          (aa+1) 其中aa表示一维数组的首址,aa的类型是int(*)[5]加一之后偏移五个整形空间指向6,再解引用相当于&aa[1][0]向前偏移一个字节空间指向5

二级指针:存放以及指针变量的地址

一维数组的传参

函数声明为int fun(int *p)

数组 int arr[10]的传参形式可以为: 1.fun(arr)  2.fun(&arr[])

二维数组传参

1.将其作为一维数组处理将首元素首址传参

int fun ( int * p )
int main( )
{
             int arr [3][ 4];
             fun( &arr [0][ 0] );
}

2.将指针指向整个内层一维数组传参

int fun ( int( * p )[4 ] )
int main( )
{
             int arr [3][ 4];
             fun( arr );
}

##在函数内部不能使用sizeof 来求数组的大小,所以必须传参获得数组的大小

利用二级指针的传参

当利用二级指针传参时,我们要将一级指针的地址传入

函数被声明为:int fun2(int **p){...} 我们在传参时可以这样传:fun2(&p) /*p为一个指针变量 */      fun2(&arr)   /*  arr被声明为char *arr[] ,其是一个指针数组  */

典型错误:内存泄漏 ,str开辟内存失败

原因:形参是实参的临时拷贝,对于指针变量也是同样,我们在平时使用的传址调用的成功实现是因为我们通过解引用访问了指针变量存放的地址的内容,而在这里,我们是直接对指针变量进行操作,我们所分配的空间都给了局部变量st而不是我们所期望的str

void getmemory ( char * st )
{
             st = (char *)malloc( 20 * sizepf( char ) );
             if (st == NULL)
            {
                         printf( "Out of memory!\n" );
                         exit( EXIT_FAILUR )
            }
}
int main ( )
{
             char *str = NULL;
             getmemory( &str );
             return 0 ;
}

改正:传进指针的地址即二级指针

void getmemory ( char ** st )
{
            * st = (char *)malloc( 20 * sizepf( char ) );
             if (*st == NULL)
            {
                         printf( "Out of memory!\n" );
                         exit( EXIT_FAILUR )
            }
}
int main ( )
{
             char *str = NULL;
             getmemory( &str );
             return 0 ;
}

典型错误:返回局部变量地址

char *getmemory ( )
{
             char arr [10];
             return arr ;
}
int main ( )
{
             char *str ;
             str = get memory( );
            strcpy( str, "abc" );
             return 0 ;
}

改正:将临时变量改成静态变量,空间不被销毁可以访问

char *getmemory ( )
{
             static char arr[ 10];
             return arr ;
}
int main ( )
{
             char *str ;
             str = get memory( );
            strcpy( str, "abc" );
             return 0 ;
}

函数指针

测试输出函数的地址:

printf( "&fun = %p\n" , &fun );

printf( "fun = %p\n" , fun );

输出结果相同

##在函数指针中fun和&fun没有任何区别,完全相同

调用函数:

fun( );

(*fun)();

(************fun)();

程序结果相同------*符号在此没有作用,编译器不识别!

函数的地址要保存在一个指针中

函数指针的书写形式:一般来说我们根据函数的类型来书写指针 【类型】【指针名】【函数的参数类型列表】

EG:   通过函数指针来访问函数

int add ( int a, int b ){ ... };
int main ( )
{
             int( *padd )(int, int) = add ;
             int ret = (*padd)( 1, 2 );
             return 0 ;
}

引入函数指针的意义:实现回调函数

int add ( int a, int b )
{
             return a + b;
}
int sub ( int a, int b )
{
             return a - b;
}
int operation ( int( * pfun )(int , int) )
{
             int num1 = 0;
             int num2 = 0;
             scanf( num1 , num2 );
             return pfun ( num1, num2 );
}
int main ( )
{
             int ret operation( add );
             printf( "%d\n" , ret );
             system( "pause" );
             return 0 ;
}

函数指针数组

int( *pfun [4] )( char *, const char *);
pfun[0 ] = fun;
pfun[1 ] = fun1;

调用:pfun[i]("123","123");

本文出自 “Zimomo” 博客,请务必保留此出处http://zimomo.blog.51cto.com/10799874/1719857

版权声明:本文为博主原创文章,未经博主允许不得转载。

一大波资源砸过来了~

借花献佛 各位小伙伴们,今天小编整理了一部分编程视频教程,教程内容是社会上比较知名的培训机构录制的,内容比较宽泛,涉及面广,有mysql ,nosql,linux,nginx,photo...
  • stonehan09
  • stonehan09
  • 2017年01月12日 10:27
  • 218

一大波智力题正在靠近~

1.两住香问题 题目:有两住不均匀的香,每住香烧完需要一个小时,问:怎样用两住香切出一个15分钟的时间段?这个问题的重点是怎么切。 将甲香的一头点燃,将乙香的两头点燃,当乙香烧完时说明甲香也正好燃...
  • NV_li_JCF
  • NV_li_JCF
  • 2017年08月05日 21:07
  • 92

摄影测量后方交会-前方交会(C#)

双像解析摄影测量中的后交-前交解法,常用于已知像片的外方位元素、需确定少量待定点坐标的情况。解算过程分为两个阶段:后方交会、前方交会。 思路为利用后方交会计算外方位元素,利用前方交会解算待定地面点坐...
  • u011670396
  • u011670396
  • 2015年09月05日 20:39
  • 3167

赶来

开启csdn
  • u012481607
  • u012481607
  • 2013年10月30日 11:46
  • 506

没有死!阿里公开Weex技术架构,还开源了一大波组件

阿里妹导读:本文主要为大家介绍飞猪 Weex 技术体系从无到有的过程,包括 Weex Ui 组件库的开发和发展,重点分享在 Weex Ui 层建设的一些经验,希望能对大家有所启发。 ...
  • zz901214
  • zz901214
  • 2018年01月26日 09:35
  • 1009

前方交会

目 录 第1章 计算公式    1 1.1 角度前方交会    1 1.1.1 公式推导    1 1.1.2 验证代码    3 1.2 ...
  • Hanford
  • Hanford
  • 2016年12月15日 09:23
  • 649

C++面试题一大波

//打印1到最大的n位数。 //题目:输入数字n,按顺序打印出从1到最大的n位十进制数。比如: //输入3,则打印出1、2、3一直到最大的3位数999. //[陷阱]:这个题目很容易想到的办法就是先求...
  • liuhuiyan_2014
  • liuhuiyan_2014
  • 2015年07月09日 15:27
  • 653

热门应用借微信玩花样:一大波红包正在来袭

春节期间的微信红包一经诞生就迅速引起用户的广泛关注,同时也印证了一个社交产品的成功。 近来,随着滴滴打车和快的打车同时停止补贴,滴滴打车在朋友圈和微信群里玩儿出了新花样——向乘客派发10亿滴滴红...
  • u011517398
  • u011517398
  • 2014年05月29日 13:13
  • 712

新iPhone的一大波吐槽正在袭来

西雅图IT圈:seattleit【今日作者】PowerBall选号机身体和灵魂总有一个要走在买PowerBall的路上在今天的表演开始前给大家出一道题到今年11月iPhone X发布后,届时你可以在官...
  • m68FUTKMUrmtj
  • m68FUTKMUrmtj
  • 2017年09月15日 00:00
  • 73

2644 线段树练习题一

题目 题解 代码题目桌子上零散地放着若干个盒子,桌子的后方是一堵墙。如右图所示。现在从桌子的前方射来一束平行光, 把盒子的影子投射到了墙上。问影子的总宽度是多少? 题解这道题目是一个经典的模型。在这里...
  • yjy_aii
  • yjy_aii
  • 2017年04月27日 16:02
  • 138
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:前方一大波指针正在赶来~
举报原因:
原因补充:

(最多只允许输入30个字)