Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值

时间:2022-02-07 21:45:57

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值


C中比较难的这一块,大概就是指针了,所以大家还是多翻阅一下资料,当然,如果只是想了解一下,看本篇也就够了,不过我也尽量陈述的很详细

一.指针

要说指针,其实通俗易懂的话来说,他应该是保存内存地址的一个变量,我们来看一下小例子

#include <stdio.h>
#include <stdlib.h>   

main(){
       //int 变量
       int i ;
       i = 5;
       //打印i的值
       printf("%d\n",i);
       //打印i的内存地址
       printf("%#x\n",&i);

      //定义一个指针变量
      //指针的含义是他是用来保存内存地址的
       int * j;
       j= &i;
        //打印指针
       printf("%#x",j);

        //让窗口停留
        int age ;
        scanf("%d",&age);

}

从这段话不难看出,我们定义一个i的话可以打印值和内存地址,但是我们定义一个指针j,也是可以赋值一个指针地址的,不信,我们打印一下

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值

可以看到,内存地址是一样的了,所以我们就可以清晰明了的知道了指针的概念了,指针指向的内存地址上村坊的数值是一个int类型

既然指针可以接收到内存地址,那他同样是可以转换成值的,我们继续来看

//打印指针值
printf("%d",*j); 

输出一个指针int类型的值

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值

就是5 了,*p指向内存地址上的值

二进指针

二进指针的概念,他也是一个指针变量,二级指针存放的地址必须是一个一级指针,也就是j

        //定义一个二进指针
       int ** k;
       //二级指针存放的地址必须是一个一级指针,也就是j
       k = &j; 

       //输出j的内存地址
       printf("%#x\n",&j);
       //打印二级指针‘
       printf("%#x\n",k); 

我们这段运行之后就是k的内存地址和j的是一样的了

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值

指针和指针变量的关系

  • 指针就是地址,地址就是指针
  • 地址就是内存单元的编号
  • 指针变量是存放地址的变量
  • 指针和指针变量是两个不同的概念
  • 我们陈述的时候会把指针变量说成指针,但是含义不一样

二.指针常见错误

我们有时候会碰到一些梗,这都是需要注意到的,我们定义一个指针

        //定义一个指针,在内存中开辟
        int * i;
        //打印i的内存地址
        printf("%#x\n",i); 

没有给这个i赋值,但是可以打印

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值

这里我们就知道,指针已定义就会有一个值了,这个本身不是错误,但是如果你

    *i = 3; 

你就有错误了,因为定义的时候是随机指向一个地址,你现在赋值这个地址为3,就错误了,正常是思路是


        //定义一个指针,在内存中开辟
        int * i;

        i= 5;
        //打印i的内存地址
        printf("%#x\n",i);

        *i = 3; 

这样输出的才是3

所以我们得到的结论就是指针复制之前,不要是桶*i赋值,指针的类型也不能混用

三,值传递和引用传递

这个概念在JAVA中也有,在排序中用到的比较多吧,其实就是定义一个中间变量去转换,我写个小例子大家就简单明了了

#include <stdio.h>
#include <stdlib.h>   

main(){
        //定义两个变量
        int i = 3;
        int j = 5;
        //定义中间变量
        int temp = i;   //temp = 3
        i = j;     // i = 5
        j = temp;  // j = 3 

        //让窗口停留
        int age ;
        scanf("%d",&age);

}

这样就把值给换过来了,不过这样做没什么意义,我们用函数去简化他,我们先来看下用JAVA的概念值传递是一个什么样式

#include <stdio.h>
#include <stdlib.h>   

void function(int i ,int j)
     {
        int temp = i;
        i = j;
        j = temp;
     }

main(){
        //定义两个变量
        int i = 3;
        int j = 5;
        //调用函数
        function(i,j); 

        printf("i的值为:%d\n",i);
        printf("j的值为:%d\n",j); 

        //让窗口停留
        int age ;
        scanf("%d",&age);

}

用JAVA的思想,应该是这样写,我们来运行一下

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值

然而你会发现,他们的值没有变化,这是因为在C中,值传递本身不会对变量产生什么影响,其实在JAVA中这样也不会发生什么改变,左右这里就牵扯出来一个引用传递了,我们写一个JAVA程序来打比方

/**
 * 测试类
 * @author LGL
 *
 */
public class Test {
    //定义两个全局变量
    int i = 3;
    int j = 5;

    public static void main(String[] args) {
        Test test = new Test();
        Function(test);
        System.out.println(test.i);
        System.out.println(test.j);
    }

    private static void Function(Test sTest){
        int temp = sTest.i;
        sTest.i = sTest.j;
        sTest.j = temp;
    }
}

用这个思想就可以把值转换了

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值

这就叫引用传递,但是再C中面向过程的思想是没有对象的,所以传地址也是可以实现的,我们试试看

#include <stdio.h>
#include <stdlib.h>   

void function(int* p ,int* q)
     {
        int temp = *p;
        *p = *q;
        *q = temp;
     }

main(){
        //定义两个变量
        int i = 3;
        int j = 5;
        //调用函数
        function(&i,&j); 

        printf("i的值为:%d\n",i);
        printf("j的值为:%d\n",j); 

        //让窗口停留
        int age ;
        scanf("%d",&age);

}

我们把内存地址传过去之后,进行转换,就可以了,运行如下

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值

值传递和引用传递的概念

  • 值传递:传递一个普通的值
  • 引用传递:传递一个内存地址

其实这些都应该叫值传递,只不过引用传递了一个地址罢了

四.指针返回值

为什么使用指针?

  • 指针是可以直接访问硬件的
  • 快速传递数据
  • 返回一个以上的值
  • 表示复杂的数据结构
  • 方便处理字符串
  • 指针有助于理解面向对象

要是让我们用JAVA去写一个返回值,大家都是用return,很方便,但是再C中,她是可以返回多个值的,我们写个例子

#include <stdio.h>
#include <stdlib.h>   

void function(int* p , int* q)
     {
        //进行操作
        *p = *p*2;
        *q = *q *2;

     }

main(){
        //定义两个变量
        int i = 3;
        int j = 5;
        //调用函数
        function(&i,&j); 

        printf("i的值为:%d\n",i);
        printf("j的值为:%d\n",j); 

        //让窗口停留
        int age ;
        scanf("%d",&age);

}

我们运行

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值

你会发现他变了,这就是C可以返回多个值的概念了,他都可用直接操作了

好的,这篇闲到这里,走到这里,对C已经有一个模糊的印象了,但是还没有摸到门槛,我们还得继续加油才是!

Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值的更多相关文章

  1. Android与JNI&lpar;三&rpar; ---- c&plus;&plus;调用java&lpar;转载&rpar;

    源码下载:JniDemo JNI就是Java Native Interface, 即可以实现Java调用本地库, 也可以实现C/C++调用Java代码, 从而实现了两种语言的互通, 可以让我们更加灵活 ...

  2. (转)C&plus;&plus; 值传递、指针传递、引用传递详解

    一直以来对函数的值传递引用传递理解很模糊,这篇文章可以说是给自己扫盲了. 值传递:实参不会发生改变,是因为形参传递的是不是实参的源地址(形参和实参地址不一样).不影响实参 指针传递:本质也是值传递,只 ...

  3. Android JNI编程(三)——C语言指针的初步认识、指针变量、互换两个数、函数返回多个值

    版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一.什么是指针? 简单来说: 指针就是内存地址      内存地址就是指针. ...

  4. Android For JNI&lpar;五&rpar;——C语言多级指针,结构体,联合体,枚举,自定义类型

    Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...

  5. Android For JNI&lpar;四&rpar;——C的数组,指针长度,堆内存和栈内存,malloc,学生管理系统

    Android For JNI(四)--C的数组,指针长度,堆内存和栈内存,malloc,学生管理系统 好几天每写JNI了,现在任务也越来越重了,工作的强度有点高,还有好几个系列的博客要等着更新,几本 ...

  6. OpenCV4Android释疑&colon; 透析Android以JNI调OpenCV的三种方式&lpar;让OpenCVManager永不困扰&rpar;

    OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰) 前文曾详细探讨了关于OpenCV的使用,原本以为天下已太平.但不断有人反 ...

  7. Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6786239 Android 系统的运行时库层代 ...

  8. Android系统智能指针的设计思路(轻量级指针、强指针、弱指针)

    本博客为原创,转载请注明出处,谢谢. 参考博文:Android系统的智能指针(轻量级指针.强指针和弱指针)的实现原理分析 C++中最容易出错的地方莫过于指针了,指针问题主要有两类,一是内存泄露,二是无 ...

  9. ZT自老罗的博客 Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析

    Android系统的智能指针(轻量级指针.强指针和弱指针)的实现原理分析 分类: Android 2011-09-23 00:59 31568人阅读 评论(42) 收藏 举报 androidclass ...

随机推荐

  1. lr&lowbar;save&lowbar;string 和 sprintf 的使用

    lr_save_string 和 sprintf 的使用 一.lr_save_string 使用介绍1.该函数主要是将程序中的常量或变量保存为lr中的参数.格式: //将常量保存为参数 lr_save ...

  2. 怎样实现excel隔行隔列变色效果的方法

    大家在使用excel的过程中,一定见过别人编排的excel文档,隔行添加单元格背景颜色,也就是通常所说的隔行变色效果.Excel中隔行变色效果的好处是:当在Excel中浏览一个非常大的工作簿中的数据时 ...

  3. 关于java文件扩展名认识

    ☆ 写在前面 一名新手在历经千辛万苦写好Java程序,怀揣激动的心情去编译和执行java程序时,结果出现错误,什么找不到文件,什么不存在,找不到main方法等等.我在这里就文件后扩展名,也叫文件后缀名 ...

  4. POJ 3130 How I Mathematician Wonder What You Are&excl;(半平面交求多边形的核)

    题目链接 题意 : 给你一个多边形,问你该多边形中是否存在一个点使得该点与该多边形任意一点的连线都在多边形之内. 思路 : 与3335一样,不过要注意方向变化一下. #include <stdi ...

  5. linux设置主机名

    第一种方式: hostname 在hostname 命名后面直接加想要更改的主机名,修改成功,键入hostname可以查看修改后的主机名,此种方式会立即生效,但是重启后还原.不会永久修改 第二种方式: ...

  6. Laravel分页

    Laravel使用的过程中,有些功能把前端页面的表达"写死了",比如分页的翻页按钮! 当然你会说Laravel的Bootstrap样式也很好看啊,但是实际项目中,翻页按钮常常需要满 ...

  7. 数据存储之Web存储(sessionStorage localStorage globalStorage )

    Web Storage 两个目标 提供一种在cookie之外的存储会话守数据的途径 提供一种存储大量可以跨会话存在的数据机制 最初的Web Storage规范包含两个对象 sessionStorage ...

  8. Flex核心属性整理

    main axis和cross axis的位置不一定是水平和垂直的,以flex-direction的值即为主轴方向 justify-content:主轴对齐方式 space-between:将多余空间 ...

  9. Vue中的~(静态资源处理)

    Webpacked 资源 首先要理解webpack是怎样处理静态资源的. 在*.vue组件中,所有的templates和css都会被vue-html-loader 和 css-loader解析,寻找资 ...

  10. Zabbix4&period;0&plus;第三方报警平台OneAlert监控报警

    1. 前言 告警将重要信息发送给运维「或者其他相关人」,及时发现并且处理问题.在所有开源监控软件里面,Zabbix 的告警方式无疑是最棒的.告警的方式各式各样,从 Email 告警到飞信.139/18 ...