Android For JNI(三)——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已经有一个模糊的印象了,但是还没有摸到门槛,我们还得继续加油才是!
Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值的更多相关文章
- C++之值传递&指针传递&引用传递详解
C++之值传递&指针传递&引用传递详解 目录 C++之值传递&指针传递&引用传递详解 1.函数基础 2.值传递 3.指针传递 4.引用传递 1.函数基础 一个函数由以下 ...
- Android与JNI(三) ---- c++调用java(转载)
源码下载:JniDemo JNI就是Java Native Interface, 即可以实现Java调用本地库, 也可以实现C/C++调用Java代码, 从而实现了两种语言的互通, 可以让我们更加灵活 ...
- (转)C++ 值传递、指针传递、引用传递详解
一直以来对函数的值传递引用传递理解很模糊,这篇文章可以说是给自己扫盲了. 值传递:实参不会发生改变,是因为形参传递的是不是实参的源地址(形参和实参地址不一样).不影响实参 指针传递:本质也是值传递,只 ...
- Android JNI编程(三)——C语言指针的初步认识、指针变量、互换两个数、函数返回多个值
版权声明:本文出自阿钟的博客,转载请注明出处:http://blog.csdn.net/a_zhon/. 目录(?)[+] 一.什么是指针? 简单来说: 指针就是内存地址 内存地址就是指针. ...
- Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型
Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...
- Android For JNI(四)——C的数组,指针长度,堆内存和栈内存,malloc,学生管理系统
Android For JNI(四)--C的数组,指针长度,堆内存和栈内存,malloc,学生管理系统 好几天每写JNI了,现在任务也越来越重了,工作的强度有点高,还有好几个系列的博客要等着更新,几本 ...
- OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)
OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰) 前文曾详细探讨了关于OpenCV的使用,原本以为天下已太平.但不断有人反 ...
- Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6786239 Android 系统的运行时库层代 ...
- Android系统智能指针的设计思路(轻量级指针、强指针、弱指针)
本博客为原创,转载请注明出处,谢谢. 参考博文:Android系统的智能指针(轻量级指针.强指针和弱指针)的实现原理分析 C++中最容易出错的地方莫过于指针了,指针问题主要有两类,一是内存泄露,二是无 ...
随机推荐
- 集群技术(二) MySQL集群简介与配置详解
when?why? 用MySQL集群? 减少数据中心结点压力和大数据量处理(读写分离),采用把MySQL分布,一个或多个application对应一个MySQL数据库.把几个MySQL数据库公用的数据 ...
- java.lang.ClassNotFoundException:org.springframework.web.context.ContextLoaderListener问题解决
今天搭建SSH项目的时候出现了如下错误: 严重: Error configuring application listener of class org.springframework.web.con ...
- 深入Java虚拟机(2)——Java的平台无关性
一.平台无关性的好处 Java技术在网络环境下非常有用,其中一个关键理由是,用Java创建的可执行二进制程序,能够不加改变地运行于多个平台. 这样的平台无关性随之带来许多的好处.这将极大地减轻系统管理 ...
- 【我的书】Unity Shader的书 — 目录(2016.5.19最后一次更新)
写在前面 感谢所有点进来看的朋友.没错,我目前打算写一本关于Unity Shader的书. 出书的目的有下面几个: 总结我接触Unity Shader以来的历程,给其他人一个借鉴.我非常明白学Shad ...
- lucene内存索引库、分词器
内存索引库 特点 在内存中开辟一块空间,专门为索引库存放.这样有以下几个特征: 1) 因为索引库在内存中,所以访问速度更快. 2) 在程序退出时,索引库中的文件也相应的消失了. 3) ...
- Java基本语法-----java运算符
这块的东西比较多 我写了太慢了 于是在word里写好贴出来供大家一起学习 运算符 -赋值运算符 -比较运算符 -逻辑运算符 -位运算符 -移位操作符 -三元运算符 [正在看本人博客的这位童鞋,我看你气 ...
- Erlang edoc 多级目录出错
Erlang edoc 多级目录出错使用rebar doc来生成项目文档.但是当erl源文件目录src下建立子目录,并新建erlang文件后,就无法生成文档. 例如,新建 src/tttt/, 并添加 ...
- FFmpeg源代码结构图 - 编码
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- MySQL聚簇索引的使用介绍
MySQL聚簇索引保证关键字的值相近的元组存储的物理位置也相同(所以字符串类型不宜建立聚簇索引,特别是随机字符串,会使得系统进行大量的移动操作),且一个表只能有一个聚簇索引.因为由存储引擎实现索引,所 ...
- 《java入门第一季》之UDP协议下的网络编程详解
首先看一下UDP协议的图解: 可以看到,分为发送端和接收端程序. 直接上代码: 发送端程序: import java.io.IOException; import java.net.DatagramP ...