C指针的值和地址 [李园7舍_404]

   在C语言中,函数传参分为两种:传址和传值。
   传值是一个复制的过程。
   传址对于变量和对象来说是传址,而针对于同一级的指针来说也是传值。传址针对的对象是指针指向的对象,此时对指针的一切行为都是为了间接的操作指针所指向的对象。但如果想要操作指针本身的内容值,那么就需要在指针层面再往下一层,让指针本身上升为变量的地位,让深一层的指针( 二级指针 )指向指针变量,二级指针在函数参数作为输出参数时用得较广。
 

1 指针和指向的变量

      指针是C语言数据类型中一种独立的数据类型:指针类型。作为C语言的精华,当定义一个指针变量时,此变量的作用就是用来存相应数据结构(变量、函数)的地址。然后通过变量的地址(指针变量的值)取地址内容的方式(*指针变量)访问(读、写)相应的变量。

如定义一个整形变量和一个整形指针,用指针指向整形变量。

int i;
i = 1;
int *p = NULL;
p = &i;
*p = 2;       


 

       此小段程序的功能就是通过指针p访问所指向的i,并通过p改变了所指向的变量i的内容。p地址通过取地址内容符*就能访问地址中存的变量了(变量作为地址的内容)。

它们的关系如下i, p的关系如下:

 

图1 指针和变量

        指针本身作为一个变量,也有自己的地址。指针作为一种特殊的变量作用是用来存地址,指针获取数据结构的地址之后可以通过指针变量访问(读写)到对应的数据结构。通过*p的形式访问的是变量,改变的是指针存的内容中的内容。如上图中,*p = 2;时是通过指针p改变的0x0001(指针值)中的i(0x0001地址中存的内容)的值。

 

2 改变指针的内容

     试想一下,在外定义一个指针变量p1,并将它指向某个变量( var )。当向函数传递一个一级指针时,它传递给函数指针参数p2的是var变量的地址,如果在函数内对p2操作的代码是*p2( 访p2地址中的内容 ),那么所涉及的内容都是var变量;如果在函数内对p2的操作代码是p2,如p2 = var1( 另一个变量 ),那么只能代表p2指向的目标变量发生了变化,p2的值也发生了变化。综上,对p2的任何操作都跟外部定义的指针p1无关,p1不会受到任何影响

 

2.1指针内容和指针指向的内容(变量)

       指针内容是指指针的值,是指针指向内容的地址(如i的地址0x0001)。指针指向的内容是指指针指向的那个变量(如p指向的是变量i)。

 

2.2 通过指针赋值的形式改变指针内容

        同类型的指针可以相互赋值。被重新赋值的指针内容就会被改变,然后就可以访问到新指针内容的变量。

int i = 1;
int j = 2;
int *p1 = NULL, *p2 = NULL;
p1 = &i;
p2 = &j;
p1 = p2;
//Do something

 原本p1指向i,存i的地址;p2指向j,存j的地址;p1=p2时,两个指针指向同一块内存,都是存的变量j的地址,两个指针都可以访问到变量j

 

这是两个指针在同一个作用域内指针内容改变的形式:指针赋值即可改变。

那么如何让一个函数来改变指针的值呢?

 

2.3 将指针作为函数参数改变指针内容

传址函数 void fun(int *p);

根据图1知,调用函数fun(p);//(p = &i)

       形参为地址(指针)时,函数传参为传址方式即将指针的内容(一个变量的地址)传了进去。然后通过*p(函数参数)操作的都是传进来那个地址所存的变量,而对于这个函数来说,此地址对应的变量的作用域和生存期都还在,这样就间接的操作了传进地址中存的变量,改变的当然是变量(p所指向的变量i了),但未能改变实参指针p的内容(指针内容)。

       

 

        所以,如果要改变指针的内容且通过将自己作为函数的参数来实现,那就要使作用域比传入指针变量作用域小的指针访问传入指针的指针内容(说起来有点绕)。图示记录


 

图2 二级指针和指针关系

所以,经过fun(&p1)之后,p1指针内容自然就被改变指向变量j了。这样就实现了指针作为函数参数传入后指针内容被改变。此种方式在程序设计的时候可以采用的^-^。需要做到的一点就是让外部指针的地址作为函数指针参数的值,即函数指针参数在一级指针(*p)形式下所访问的是外部指针变量。函数指针参数的二级指针(**p)形式才是访问外部指针所指向的变量。

 

C Note Over。

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值