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

3 篇文章 0 订阅
2 篇文章 0 订阅

随着直播领域、图片处理、流媒体等应用的房展,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);
}


打印结果

 

 


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值