Android 之NDK实战系列(1)——常见的C语言操作

来源:互联网 发布:网站域名价值评估网 编辑:程序博客网 时间:2024/05/23 13:50

随着直播领域、图片处理、流媒体等应用的房展,NDK在Android 开发中的地位也越来越重要,于是决定写一个专题关于NDK的开发,主要从最基础的C语言讲起,接着是用Android通过NDK 输出helloworld,到后期还会有一些图片处理、音频处理的内容,由于工作比较忙,可能不定期更新。你可以催我,但是不可以骂我。

恩,就这样。

注:本文与JNI\NDK无关,只是先介绍C的常见用法,方便之后的NDK开发,如果你对C很熟练,本文对你的作用不是很大,当然,你也可以看看,权当复习,如有不对的地方,请指出。

在了解NDK之前,我们先了解JNI(Java Native Interface)java 原生接口,通过JNI 可以实现JAVA与C的交互

JNI具体是什么:

这个协议用来沟通java代码和外部的本地代码(c/c++).

通过这个协议,java代码就可以调用外部的c/c++代码

外部的c/c++代码也可以调用java代码

为什么要进行

首先,Java语言提供的类库无法满足要求,且在数学运算,实时渲染的游戏上,音视频处理等方面上C/C++相比效率稍

其次,Java语言无法直接操作硬件C/C++代码不仅能操作硬件而且还能发挥硬件最佳

最后,使用Java调用本地的C/C++代码所写的库,省去了重复开发的麻烦,并且可以利用很多开源的库提高程序效率。


接下来,我将会介绍一些C语言的常用操作:

 

C语言的常用操作

什么是指针

指针就是地址,地址就是指针

地址就是内存单元的编号

指针变量是存放地址的变量

指针和指针变量是两个不同的概念

但是要注意: 通常我们叙述时会把指针变量简称为指针,实际它们含义并不一样

举个例子

#include <stdio.h>  #include <stdlib.h> main() //入口函数  {     int *p;// p是变量的名字,*p是该地址对应的值,p存放了对应的地址 int i = 3; p = &i;//把i的地址传给p printf("p=%d\n",*p);}

 

代码块中,把i的地址传给了p*p为该地址块的值。

打印结果

 

 

通过指针,实现一个简单的交换运算

 

Cjava很相似,先写一个函数,然后在main()函数入口中写入参数,调用函数,代码如下:

void changNum(int i,int j){int k = j;j = i;i = k;}main(){int a = 3;int b = 5;changNum(3,5);printf("a=%d\nb=%d\n",a,b);}


我们打印下结果:

 

是不是很奇怪,我们分明调用了函数,交换了参数,但是打印出的结果依然没变。

这正是C语言的独特之处——指针,因为我们传入的参数他们指向的依然是同一个地址的值。正确的做法是,在函数的形参中传入地址值,通过地址交换。

正确代码如下:

void changNum(int *i,int *j){int k = *j;*j = *i;*i = k;}main(){int a = 3;int b = 5;changNum(&a,&b);printf("a=%d\nb=%d\n",a,b);}

打印结果:

 

 

指针函数

C中,每一个函数都有一个对应的地址块,可以用前面调用指针的方法,通过指针的地址进行函数的操作。

示例代码:

int add(int x , int y){        return x+y;    }  main(){             int (*hanshu) (int x, int y); //定义一个函数的指针的声明 名字叫hanshu  返回值 int 接受参数两个int         hanshu = add;       printf("result=%d\n", hanshu(2,6));        }


打印结果

 

 

二级指针:

二级指针就是指针的指针。

C中,每个值都有一个对应的地址,但是如果该地址也作为一个值进行操作,则这个值就也需要一个内存空间来存放,这个内存空间的值就是二级指针。

二级指针例子:

int *q;   //定义一个一级指针变量,它指向一个普通变量(即它存的是一个变量的地址)

int **p;   //定义一个二级指针变量,它指向一个指针变量(它存的也是一个变量地址,只不过是一个指针变量的地址)

int s;

q = &s;   //q中存的是整型变量s的地址,所以q是一级指针

p = &q;   //p中存的是一级指针q的地址,所以p是二级指针

示例代码:

main(){int **p;int *q;int i = 5;q = &i;p = &q;**p = 3;printf("%d\n",i);}

打印结果:

 

上例中,i 为一个普通参数,值为5q存放的是i的地址,p存放的是q的地址,所以**p对应的值就是q的地址对应的值,q存放i的地址,所以**p就是i的值

 

结构体:

结构体和Java 中的类用法和作用都是十分相似,在一个结构体重定义了该结构体需要用到的参数。

例子:

struct Person{int age;float height;char job;//c中没有String 类型,字符串通常存放在char[]中};main(){struct Person p =  {18,180,'i'};printf("job is %c\n height is %f\n age is %d\n ",p.job,p.height,p.age);}


打印结果

 

 

结构体指针:

指向结构体的指针,通过-> 操作获取结构体中的值

示例代码:

struct Person{int age;float height;char job;//c中没有String 类型,字符串通常存放在char[]中};main(){struct Person person =  {18,180,'i'};struct Person *p;p = &person;// p->age; p指向结构体中age变量,即(*p).age;printf("age is %d\n",p->age);}


打印结果

 

 


1 0