NDK开发C语言基础(第一天)

环境准备

可以选择使用 VS2013开发,但是这个家伙比较重量级,所以我们还有一个选择就是使用 Clion,如果只使用 Clion需要配置 MinGW环境。

VS2013 

下载链接:https://pan.baidu.com/s/1uOMk6LEAazBG5YQf_R6Ssg  提取码:3ts6  

Clion 

Jetbrains旗下产品之一,主要用来开发C/C++,软件相比VS来说轻巧很多,官方下载链接:http://www.jetbrains.com/clion/?fromFooter

Clion的安装就是傻瓜式的下一步下一步,这里就不再赘述,太侮辱大家智商了,哈哈哈~ 安装好Clion之后,别急着运行,得先装MinGW,因为它才是真正执行C/C++程序的东东。

MinGW

链接:http://sourceforge.net/projects/mingw/files/

点击下载按钮:

运行安装包:

点击 Install:

点击Continue,等待安装完成之后,再点Continue:

安装完成之后,需要下载相关包的支持,如下图所示:点击左侧的 Basic Setup,勾选所有包:

点击 Installation→Apply Changes:

然后就是漫长的等待,大约半个小时左右后,右侧的包前面的框框变绿了,说明MinGW环境OK了。

第一个C程序

打开Clion,打开File→Settrings→Build,Execution,Deployment→Toolchains,可以看到 Clion会自动匹配 MinGW,因为我本地安装了 VS2013,所以这里会同时出现 MinGW和 VS,随便选择一个即可。

找到工具栏中的 File→New Project:

接着我们选择C Executable,再选择自己存放C工程的目录,C标准一般选择C99,然后点击 Create。

工程创建好之后,默认会创建一个 main.c文件,等工程加载完成之后,点击运行按钮即可。

PS:Clion只有30天的免费试用时间,点击加入我的安卓技术训练营,群共享中有无限试用的方法。

初识NDK

NDK是什么

  • NDK(C/C++) <-------------------> SDK(Java)性质是一样的
  • 定义:Native Development Kit,是 Android的一个工具开发包
  • 作用:快速开发C、 C++的动态库,并自动将so和应用一起打包成 APK
  • 提供了把.so和.apk打包的工具
  • 提供了交叉编译器,用于生成特定的CPU平台动态库
  • 提供了很多很多的native支持,就相当于SDK提供了很多上层的支持一样

NDK特点

  • 运行效率高
  • 代码安全性高
  • 功能拓展性好
  • 易于代码复用和移植

NDK能做什么

打开支付宝APK,微信APK,等等,里面就有很多native库

NDK的学习由哪些内容所组成

第一阶段:C语言的学习,C++语言的学习,JNI的学习。

第二阶段:CMake的学习,Linux基本操作,Linux Shell脚本编程。

第三阶段:各种实战(身份证识别,MMKV组件,QQ变声 等)。

第四阶段:FFmpeg视频播放器项目,RTMP直播流。

第五阶段:OpenCV人脸定位,OpenGL视频处理,OpenGL视觉效果。

目前先按这五个阶段一步一步来。

C语言基础

解读第一个程序

#include <stdio.h>

//#include "stdio.h"
//<>表示寻找系统库;如果用“”,则会先去寻找自定义的库,找不到才会去找系统的库
//.h  .hpp 是头文件,声明文件
//.c  .cpp 是实现文件
int main() {
    printf("Hello world!");
    return 0;//0表示程序执行完成后正常退出
}

基本数据类型

#include <stdio.h>

// 基本数据类型
int main() {

    int i = 100;
    double d = 200;
    float f = 300;
    long l = 400;
    short s = 500;
    char c = 'a';
    // 字符串
    char *str = "Luffy";

    // 不是随便打印的,需要占位
    printf("i的值是:%d\n", i); // d == decimal
    printf("d的值是:%lf\n", d); // lf == long float
    printf("f的值是:%f\n", f); // f == float
    printf("l的值是:%d\n", l); // d == decimal
    printf("s的值是:%d\n", s); // s == short
    printf("c的值是:%c\n", c); // c == char
    printf("字符串:%s\n", str); // s == string

    getchar();//阻塞程序
    return 0;
}


 关于getchar的作用移步这里:getchar()作用

#include <stdio.h>

/**
 * 基本类型占用的字节数(后续过程中,非常常用的)  sizeof获取字节数
 * 因为有些基本数据类型的所占字节数与操作系统有关,比如32位的系统int
 * 可能占2个字节,64位的占4个
 */
int main() {

    // int 占几个字节  == 4
    // double 占几个字节 == 8
    // char 占几个字节 == 8

    printf("int 数据类型所占的字节数:%d\n", sizeof(int));// 4
    printf("double 数据类型所占的字节数:%d\n", sizeof(double));// 8
    printf("char 数据类型所占的字节数:%d\n", sizeof(char));// 1

    return NULL; // NULL == 0
}

指针

概念

#include <stdio.h> // C99 标准库

// 地址概念
// Java ------ 万物皆对象
// C C++(对象) ------ 万物皆指针
// Linux ------ 万物皆文件
int main() {

    // 指针 == 地址
    // %p == 地址输出的占位
    // & == 取出地址

    int number = 100000;
    printf("number变量的地址是:%p\n", &number); // 地址 == 0061FF1C

    return NULL;
}

PS:解决打印语句在控制台输出中文乱码问题,双击shift,输入 File encoding修改编码格式。

取出指针保存的值

#include <stdio.h>

int main() {

    int number_int = 100;
    double number_double = 200;
    printf("number_int的值是:%d\n", number_int);
    printf("number_double的值是:%lf\n", number_double);

    // * 取出number_int地址所对应的值 == 100
    // 指针取出值
    // 既然任何变量都是地址,可以使用地址获取值
    printf("number_int的值是:%d\n", *(&number_int));
    printf("number_double的值是:%lf\n", *(&number_double));

    //   ================   难度升级

    // 在这里,赋值号左边的星号是为了声明指针变量
    int *intP = &number_int;
    double *doubleP = &number_double;

    // 输出 100  和 200
    printf("number_int的值是:%d\n", *intP);//printf格式化输出语句中,后面的星号是用来取地址的
    printf("number_double的值是:%lf\n", *doubleP);

    // 概念
    /**
       如果你去上网查询,指针的文章,就会发现,一些专业术语,导致大学老师一直说不清楚,成功劝退很多学生放弃:
       内存地址变量,内存地址别名,指针,指针变量,指针别名,.... 一大段的专业术语 ...

       理解:  大道至简 (化繁为简)
       内存地址 == 指针
       指针 == 内存地址
        int *  ------ (int类型的指针),double *  ------ (double类型的指针)      

        指针别名,指针变量 == 就是一个变量而已,只不过 是指针的 变量 而已
        上面代码中的 intP 和 doubleP 就是指针变量
     */

    return NULL;
}

 通过指针修改值

#include <stdio.h>

// 通过指针(地址)修改值
int main() {

    int i = 100;

    // p:我只接收地址,你给我一个100,不规范
    // int * p = i;
    int * p = &i;

    i = 200;

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

    *p = 300;//取出指针 p存放的数据,然后用 300覆盖给这个数据的原始值

    printf("通过指针修改i的值:%d\n", i);

    return 0;
}

 函数中的值传递和地址传递

#include <stdio.h>

// C语言不允许函数重载  Java可以,C++可以
//void change(int i); // 先声明 ------ 这样的是值传递,形参相当于change函数中的局部变量
void change(int *i); // 先声明 ------ 这样是地址传递

//调用函数修改值,传参需要用指针
int main() {

    int i = 100;

//    change(i);
    change(&i);
    printf("main中i的地址%p,i的值%d\n", &i, i);
    /*
        int * i;  定义指针
        *i = 666;  取出内存地址所对应的值修改成666
    */

    return 0;
}

// 函数不能写在 main的下面,会报错
// void change(int i) {}

// 再实现
//void change(int i) {
//
//    printf("change内存地址:%p\n", &i);
//
//    i = 200;
//}

// 再实现
// 使用指针 来修改
void change(int *i) {
    printf("change中 i 的内存地址:%p\n", i);
    *i = 666;
}

PS:可以这样理解,地址在内存中是真实存在的一段具体的空间的编号。

案例:交换两个整型变量的值

#include <stdio.h>

// 由于C语言不支持函数重载,所以声明的函数,不需要写参数 (只要函数名一样,
// 就会报错,即使返回值不一样也不行)
//int changeAction();

void changeAction();

int main() {
    int a = 100;
    int b = 200;

    changeAction(&a, &b);

    printf("交换完成后的效果:a = %d,b = %d\n", a, b);
    return 0;
}

// 只接收指针(内存地址)    内存地址 == 指针
void changeAction(int *a, int *b) {

    int temp = *a;

    *a = *b;

    *b = temp;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值