美文网首页
Android NDK开发-C/C++基础

Android NDK开发-C/C++基础

作者: Lucky胡 | 来源:发表于2019-11-10 11:44 被阅读0次

    mac下开发C/C++,IDE使用CLion。
    因为Visual Studio在mac下支持不好,XCode不好用。

    1、基础

    1. 函数指针
      是一个变量,该变量需要赋值为函数。
    //函数指针,相当于一个变量,只不过该变量是个函数,需要赋值一个函数给他
    void (*func)();
    
    void funcImp(){
        printf("funcImp");
    }
    
    //调用
    int main() {
        func = funcImp;
        func();
        return 0;
    }
    
    
    1. 指针函数
      是一个函数,返回类型为指针的函数。
    int *f(void* param){
        int b = 10;
        int*p = &b;
        return p;
    }
    
    //调用
    
    int main() {
        int a = 10;
        int *p = f(&a);
        int c = *p;
        return 0;
    }
    

    2、数组、指针、指针数组

    指针

        int arr[] = {0, 1, 2};
        int *p_arr = arr;
        //指针指向arr的首地址
        *p_arr = 10;
        //指针指向arr的第二个元素地址
        *(p_arr + 1) = 11;
        for (int i = 0; i < 3; ++i) {
            printf("%d \n", arr[i]);
        }
    

    指针数组

        //指针数组
        int*p[3];
        int arr[] = {1,2,3};
        for (int i = 0; i < 3; ++i) {
            p[i] = &arr[i];
        }
    
        for (int j = 0; j < 3; ++j) {
            printf("%d \n",*p[j]);
        }
    

    数组指针

        //数组指针,指向含4个元素的一维数组
        int (*p)[4];
        int a[3][4];
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 4; ++j) {
                a[i][j] = i + j;
            }
        }
        //此时p指向了二维数组的首地址
        p = a;
        //p[0]指向二维数组a的第一行的首地址的第一个元素
        printf("%d\n",*p[0]);
    
        //此时p向后跳过了4个元素,p[0]指向了二维数组a的第二行的首地址的第一个元素
        p++;
        printf("%d\n",*p[0]);
    
    指针数组和数组指针的区别

    结构体和共用体

    结构体

    
    struct Student{
        int age;
        short score;
    };
    
    
    
    int main() {
        struct Student student;
        student.age = 10;
        student.score = 1;
    
        printf("结构体大小:%lu", sizeof(student));
    
    }
    

    输出结构体大小为8。一个short+int长度为6。

    内存对齐

    1、结构体中成员的变量偏移量必须是成员大小的整数倍。
    例如32位CPU是4个字节的,short只有两个字节,结构体中就给分配了4个字节,两个字节空着。
    2、结构体大小必须是所有成员大小的整数倍,即所有成员大小的公倍数。

    共用体

    为了节约内存,用共用体来存放数据,长度只占用最长的成员的长度。
    所有成员的地址都是一样的,但是每次存放的是最后一次赋值的变量。

    union Data {
        int i;
        float f;
        char c[10];
    };
    
    
    int main() {
        union Data data;
        data.i = 10;
        data.f = 10.0f;
        //最后赋值的会擦除前面赋值的
        for (int i = 0; i < 10; ++i) {
            data.c[i] = 'a';
        }
        //共用体大小取决于最长的成员变量长度
        printf("共用体大小:%lu \n", sizeof(data));
        //无法拿到值
        printf("i=%d\n", data.i);
        //无法拿到值
        printf("i=%f\n", data.f);
        //可以拿到值
        printf("i=%c\n", data.c[0]);
        data.f = 10.0f;
        printf("i=%f\n", data.f);
    }
    

    动态库与编译

    动态库编译过程:


    动态库编译过程

    动态库与静态库区别
    1、静态库文件比较大,动态库比较小
    2、静态库需要在编译时被链接在目标代码中,动态库在运行时才会被加载到目标代码中;
    3、静态库类似于Android的mudule,一旦打包apk需要重新进行编译;
    4、动态库类似于jar包,打包不需要重新进行编译。

    相关文章

      网友评论

          本文标题:Android NDK开发-C/C++基础

          本文链接:https://www.haomeiwen.com/subject/przobctx.html