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

简介: <div class="markdown_views"><h1 id="android-for-jni三c的指针指针变量指针常见错误值传递引用传递返回多个值">Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值</h1><hr><blockquote> <p>C中比较难的这一块,大概就是指针了,所以大家还是多翻阅一

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,也是可以赋值一个指针地址的,不信,我们打印一下

这里写图片描述

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

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

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

输出一个指针int类型的值

这里写图片描述

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

二进指针

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

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

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

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

这里写图片描述

指针和指针变量的关系

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

二.指针常见错误

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

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

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

这里写图片描述

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

    *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的思想,应该是这样写,我们来运行一下

这里写图片描述

然而你会发现,他们的值没有变化,这是因为在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;
    }
}

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

这里写图片描述

这就叫引用传递,但是再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);

}



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

这里写图片描述

值传递和引用传递的概念

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

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

四.指针返回值

为什么使用指针?

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

要是让我们用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);

}



我们运行

这里写图片描述

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

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

目录
相关文章
|
11月前
|
存储 C++
C++语言中指针变量int和取值操作ptr详细说明。
总结起来,在 C++ 中正确理解和运用 int 类型地址及其相关取值、设定等操纵至关重要且基础性强:定义 int 类型 pointer 需加星号;初始化 pointer 需配合 & 取址;读写 pointer 执向之处需配合 * 解引用操纵进行。
777 12
|
Java Android开发 C++
Android Studio JNI 使用模板:c/cpp源文件的集成编译,快速上手
本文提供了一个Android Studio中JNI使用的模板,包括创建C/C++源文件、编辑CMakeLists.txt、编写JNI接口代码、配置build.gradle以及编译生成.so库的详细步骤,以帮助开发者快速上手Android平台的JNI开发和编译过程。
1507 1
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
魔法指针 之 指针变量
魔法指针 之 指针变量
152 1
|
C++
析构造函数就是为了释放内存,就是在局部指针消失前释放内存,拷贝构造函数就是以构造函数为模块,在堆里面新开一块,同一个变量在堆里面的地址
本文讨论了C++中构造函数和析构函数的作用,特别是它们在管理动态内存分配和释放中的重要性,以及如何正确地实现拷贝构造函数以避免内存泄漏。
269 2
|
C语言 C++
【C语言】指针篇-一篇搞定不同类型指针变量-必读指南(3/5)
【C语言】指针篇-一篇搞定不同类型指针变量-必读指南(3/5)
319 1
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
941 4
|
存储 安全 C++
C++:指针引用普通变量适用场景
指针和引用都是C++提供的强大工具,它们在不同的场景下发挥着不可或缺的作用。了解两者的特点及适用场景,可以帮助开发者编写出更加高效、可读性更强的代码。在实际开发中,合理选择使用指针或引用是提高编程技巧的关键。
291 1
|
人工智能
魔法指针 之 指针变量的意义 指针运算
魔法指针 之 指针变量的意义 指针运算
235 0
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
235 0