JNI C_指针

来源:互联网 发布:火龙女电影知乎 编辑:程序博客网 时间:2024/05/16 15:14

指针就是内存地址,内存地址就是指针


举个栗子来学习指针:

#include<stdio.h>#include<stdlib.h>main(){    int i=10;    int* p;//定义一个一级指针p     p=&i;//把i对应的内存地址,赋值给p     printf("*p取得的值是:%d\n\n",*p); //*p就是取值,就是把p对应的那个内存地址的值取出来               system("pause");}

结果是这样的:


但是要注意一点的是:

p=&i;

这一句代码,在C语言中是把i的内存地址,给了p。

画张图来分析一下:

那么由此可见,i的内存地址给了p之后,那p取得的值自然就是i的内存地址对应的那个值啦~


这里有4个问题:

  • 修改i,p的取值有无变化?p的内存地址有无变化?
#include<stdio.h>#include<stdlib.h>main(){    int i=10;    int* p=&i;    printf("修改i前,*p取得的值是:%d\n\n",*p);     i=100;     printf("修改i后,*p取得的值是:%d\n\n",*p);                system("pause");}

得到的结果是:

我们来分析分析,int* p=&i这句话,我们在上文已经分析过,其实就是把i的内存地址赋给了p,那么p打印出来的值,就是i对应的内存的地址的值,所以最初p打印的值,是i的值——10,而后,直接将i对应的内存地址的值改成了100,那等价关系推出来,自然p的值,也会变成100了。

我们再打印一下,i和p的内存地址,也可以很直观的看出来内存地址结果:

可以看到,对i直接赋值,i的内存地址虽然改变了,但是p的内存地址没有改变,换而言之,只是p的值即p对应的值的内存地址改变了,并不影响p本身的内存地址。所以,由此得到结论,改变i的值,对p的值有影响,而对p的本身的内存地址无影响。


  • 修改p,i的取值有无变化?i的内存地址有无变化?
#include<stdio.h>#include<stdlib.h>main(){    int i=10;    int* p=&i;    printf("修改p前,i取得的值是:%d\n\n",i);         int j=100;    p=&j;     printf("修改p后,i取得的值是:%d\n\n",i);                  system("pause");}

得到的结果是:

修改p前,i取得的值是:10

修改p后,i取得的值是:10


注意这两行代码:

    int j=100;    p=&j; 

看图分析:


可以看到,改变p的值,即是改变了p的值对应内存,使它指向了j的内存地址,但是对i是毫无影响的。所以,改变p的值,i的值没有影响,i的内存地址也没有影响。


  • 修改*p的值,对i的取值有没有影响?对i的内存地址有没有影响?
#include<stdio.h>#include<stdlib.h>main(){    int i=10;    int* p=&i;    printf("修改*p前,i取得的值是:%d\n\n",i);     *p=100;     printf("修改*p后,i取得的值是:%d\n\n",i);                  system("pause");}

运行这些代码过后,可以看到有如下结果:

修改*p前,i取得的值是:10

修改*p后,i取得的值是:100


可以看到,这个结果跟第1个问题的结果一样,那么这是为什么呢。在最开始的栗子里我们注释过,*p就是取值,就是把p对应的那个内存地址的值取出来,而在对*p重新赋值之前,实际上,是将i的内存地址给了p,那么*p其实取的就是i的内存地址对应的值,那么这个时候,如果对*p重新赋值,换句话说,就是对i的内存地址重新赋值,那么自然的,i的取值就会改变,而i的取值变了,i的内存地址也是会有影响的。


  • 指针中,如何互换两个数?

一般,我们的代码都会这样写:

#include<stdio.h>#include<stdlib.h>main(){    int a=10;    int b=20;       printf("互换前,a是:%d\n",a);    printf("互换前,b是:%d\n\n",b);        int temp=a;    a=b;    b=temp;    printf("互换后,a是:%d\n",a);    printf("互换后,b是:%d\n\n",b);               system("pause");}

那么运行的结果,两个数也确实进行了交换:

然而为了代码的实用性,我们一般会将互换的逻辑提取出来写成一个函数,以便供后面使用,这个时候,我们一般会将代码写成这个样子:

#include<stdio.h>#include<stdlib.h>void change(int a,int b){int temp=a;    a=b;    b=temp;}main(){    int a=10;    int b=20;       printf("互换前,a是:%d\n",a);    printf("互换前,b是:%d\n\n",b);        change(a,b);    printf("互换后,a是:%d\n",a);    printf("互换后,b是:%d\n\n",b);               system("pause");}

乍一看,没问题,毕竟我们在java中,也是直接将公共部分提取出来,那么运行上面的代码,得到的是一个怎样的结果呢:

运行过后发现,a的值和b的值,并没有交换,这是为什么呢?在C语言中,传值是无法改变值的。我们来打印a和b的地址来分析一下:

#include<stdio.h>#include<stdlib.h>void change(int a,int b){int temp=a;    a=b;    b=temp;        printf("互换后,a的内存地址是:%#x\n",&a);    printf("互换后,b的内存地址是:%#x\n\n",&b);}main(){    int a=10;    int b=20;       printf("互换前,a是:%d\n",a);    printf("互换前,b是:%d\n\n",b);        printf("互换前,a的内存地址是:%#x\n",&a);    printf("互换前,b的内存地址是:%#x\n\n",&b);        change(a,b);    printf("互换后,a是:%d\n",a);    printf("互换后,b是:%d\n\n",b);               system("pause");}

可以看到,互换前后,a和b的地址,根本就不是同一个地址了。那么这是为什么呢?画个图来分析一下:


在上面的代码中,我们是把转换的逻辑提出来成为了一个change()函数,那么这就意味着,change()函数里面的int a、int b和main()函数中的int a、int b根本就不是同一个,虽然它们长的一样且值一样,但是它们的本质,已然不是同一个。

如果要想将值真正的转换,我们就应该将a和b的地址传过去:

#include<stdio.h>#include<stdlib.h>void change(int* a,int* b){int temp=*a;//取a对应的值赋值     *a=*b;    *b=temp;        printf("互换后,a的内存地址是:%#x\n",a);    printf("互换后,b的内存地址是:%#x\n\n",b);}main(){    int a=10;    int b=20;       printf("互换前,a是:%d\n",a);    printf("互换前,b是:%d\n\n",b);        printf("互换前,a的内存地址是:%#x\n",&a);    printf("互换前,b的内存地址是:%#x\n\n",&b);        change(&a,&b);//将a和b的地址传过去     printf("互换后,a是:%d\n",a);    printf("互换后,b是:%d\n\n",b);               system("pause");}

结果如下:

两值成功互换,所以由此可见,单纯的传值是无法改变值的,只有传地址,才可以真正的改变值。


最后总结几点:

  • 指针就是内存地址,内存地址就是指针
  • &i,指取变量i的地址
  • p=&i,指变量i的地址赋给p
  • *p,指取值,把p对应的内存地址的值取出来


以上便是本人学习的小小总结,若有不对,请留言指出,谢谢~



0 0
原创粉丝点击