android ndk-02(c语言指针运算、结构体指针)

86 阅读3分钟

1.打印变量地址

void update(int *i) {
    printf("update 函数的i的内存地址是:%p\n", &(i)); // 这么取 取的是变量的地址值
    printf("update 函数的i的内存地址是:%p\n", &(*i)); // *i 拿到传入i的对象
    printf("update 函数的i的内存地址是:%p\n", i);// *i 拿到传入i的对象
    *i = 999;
}

int main() {
    printf("Hello, World!\n");
    int i = 100;
    update(&i);
    printf("main 函数的i的内存地址是:%p\n", &i);
    return 0;
}

//输出
Hello, World!
update 函数的i的内存地址是:0x16fc8b258
update 函数的i的内存地址是:0x16fc8b288
update 函数的i的内存地址是:0x16fc8b288
main 函数的i的内存地址是:0x16fc8b288

未命名绘图.drawio.png

2.多级指针

//1. 多级指针
int main(){
    int num = 999;
    //一级指针
    //在真实开发过程中最多3级指针 int ***
    int * num_p = # // 取出num的内存地址给num_P(一级指针)
    int ** num_p_p = &num_p; //取出num_p的内存地址给num_p_p(二级指针)
    printf("num_p的值是:%p,num_p_p的值是:%p\n",num_p,num_p_p);

    //我想输出999
    printf("获取最终的值%d\n",* num_p);
    printf("获取最终的值%d\n",** num_p_p);
    //获取最终的值999
    //获取最终的值999
    // *num_p_p  =  num_p   * 取出内存地址所对应的值、
    return 0;
}

原理跟上篇一样 image.png

3.指针运算模拟substring

#include <stdio.h>

void substrAction3(char * result, char * str, int start, int end) {
    for (int i = start; i < end; ++i) {
        *(result++) = *(str + i);
    }
}

int main() {
    char * str = "Derry is";

    // char * result = "ABCDEFG"; (会报错,因为不准修改常量值)
    // char * result = NULL;  (会报错,因为不准修改NULL值)
    // VS不允许野指针(严格)
    // char * result; // 这就是不通过的 才对的  VS 不通过对的
    // 在你的栈区开辟空间[推荐方式]
    char result[100] = "ABC";
    substrAction3(result, str, 3, 5);
    printf("%s\n", result);
    return 0;
}

//输出
ryC

通过*来取数组的值,将值赋值给result 未命名绘图.drawio.png

4.结构体指针 结构体类似于java类的概念

#include <stdio.h>
//定义一个结构体
struct Dog{
    //属性
    char name[10];
    int age;
    char sex;
};

int main() {
    struct Dog dog;
    return 0;
}

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

//第二种写法
struct Person {
    // 成员
    char * name; // 字符指针 = "赋值"
    int age;
    char sex;
    //可以在这里直接定义别名ppp,在main中可以直接调用
} ppp = {"Derry", 33, 'M'},
        ppp2,
        ppp3,
        pppp4,
        pppp5
// ...
;
struct Cat{
    char * name;
    int age;
};

int main() {
    // Person == ppp == struct Person ppp;
    printf("name:%s, age:%d, sex:%c \n", ppp.name, ppp.age, ppp.sex);
    // 赋值
    // strcpy(pppp5.name, "Derry5"); // Copy不进去
    pppp5.name = "DerryO";
    pppp5.age = 4;
    pppp5.sex = 'M';

    printf("name:%s, age:%d, sex:%c \n", pppp5.name, pppp5.age, pppp5.sex);

    struct Cat cat = {"mingzi",18};
    struct Cat * catzz = &cat;
    printf("名字%s",catzz->name);

    return 0;
}

5.结构体数组(栈上开辟与堆上开辟) malloc代表手动在对上开辟空间,使用完毕记得释放free

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Cat3 {
    char name[10];
    int age;
};

int main() {
    // 栈区 静态范畴 结构体数组
    struct Cat3 cat [10] = {
            {"小黄", 1},
            {"小白", 2},
            {"小黑", 3},
            {},
            {},
            {},
            {},
            {},
            {},
            {},
    };
    // ClION的写法
    struct Cat3 cat9 =  {"小黑9", 9};
    // cat[9] = cat9;
    *(cat + 9) = cat9;
    printf("name:%s, age:%d \n", cat9.name, cat9.age);
    printf("name:%s,age:%d \n",cat[9].name,cat[9].age);

    // 堆区 动态范畴 ==============================
    struct Cat3 * cat2 = malloc(sizeof(struct Cat3) * 10);
    // 【1元素地址的操作】给他赋值,请问是赋值,那个元素  (默认指向首元素地址)
    strcpy(cat2->name, "小花猫000");
    cat2->age = 9;
    printf("name:%s, age:%d \n", cat2->name, cat2->age);
    printf("%d\n",sizeof ("小花猫")); //10
    printf("%d\n",sizeof ("小花"));  //7
    printf("%d\n",sizeof ("小")); //4

    // 【8元素地址的操作】 给第八个元素赋值
    cat2 += 7;
    strcpy(cat2->name, "小花猫888");
    cat2->age = 88;
    printf("name:%s, age:%d \n", cat2->name, cat2->age);

    free(cat2);
    cat2 = NULL;
    return 0;
}

6.结构体指针、取别名

// 5.结构体与结构体指针 取别名。

#include <stdio.h>
#include <stdlib.h>

struct Workder_ {
    char name[10];
    int age;
    char sex;
};

typedef struct Workder_ * Workder1; // 给结构体指针取别名

int main() {
    // VS  CLion  他们都是一样的写法
    Workder1 workder = malloc(sizeof(Workder1));

    return 0;
}