美文网首页
NDK-010:C5: 结构体 枚举

NDK-010:C5: 结构体 枚举

作者: xqiiitan | 来源:发表于2024-12-31 19:32 被阅读0次

坚持一年,目标20k。

1.字符串的替换 aabbaabbddaa 替换aa为cc

指针的操作。

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

char* sub_str(char* str, int start, int end) {
    // 开辟一个字符串,去存储数据
    //char sub[end-start];
    char* sub = (char *)malloc((end-start)*sizeof(char) +1);
    // 注意:malloc一定要free掉。

    // 遍历赋值
    int len = end-start;
    str += start; // 指针往后挪动
    for(int i=0; i<len; i++) {
        sub[i] = *str;
        str++; // 指针后移
    }
    sub[len] = '\0'; // 指针最后,标记字符串结尾,否则print无法判断字符串结束
    // free(sub);
    return sub;
}

// 替换字符串的方法
char *str_replace(char* str, char* src, char* dest) {
    // 1.有没有aa,
    char* pos = strstr(str, src);
    if(!pos) { // 没找到. 结束语句。
        return str;     
    }

    // 2.重新计算数组的大小 = 原数组大小- 要替换的+ 被替换的
    int newArrSize = strlen(str) -strlen(src)+strlen(dest);
    // AS:char* result[newArrSize];
    char* result = (char*)malloc(sizeof(char) *newArrSize);

    // 3.就行拼接,aabbcc bb->fff    aafffcc, 字符串截取。
    // 3.1 第一部分的尾巴。
    int start_end_pos = pos - str;
    char* start = sub_str(str, 0, start_end_pos);
    // 3.2 中间部分:bb-》fff

    // 3.3 最后部分:
    int end_start_pos = start_end_pos + strlen(src);
    char* end = sub_str(str, end_start_pos, strlen(str));
    // 3.4 拼接
    strcpy(result, start);
    strcat(result, dest);
    strcat(result, end);

    // 4.多个替换,使用while循环 或递归。
    return str_replace(result, src, dest);
}

void main() {
    char* str = str_replace("aabbaabbddaa", "aa", "ccc");
    printf("最终结果:%s", str);
}

2. 结构体和结构体指针。

  • 结构体的定义和使用
  • 结构体指针和动态内存开辟
  • 结构体大小计算(字节对齐)
  • 结构体和结构体指针取别名
  • 联合体的定义和使用
  • 联合体大小计算
  • 枚举的定义和使用。

类似java里面的对象,用来定义一个功能。
struct

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

#### 2.1. 定义结构体,类似java的class,但是不能继承。
struct Worker {
    char name[10];
    int age;
    double salary;
};
void main() {
    struct Worker worker = {"Tom", 23, 1000}; // 初始化,没初始化时里面所有属性都是没初始值的。
    printf("name:%s, age:%d, salary:%lf。\n", worker.name,worker.age,worker.salary);    
    worker.age = 55;
    // worker.name= "Jerry";
    strcpy(worker.name, "Jerry"); // 字符串赋值
}
#### 2.2.直接取名字
struct Worker {
    char name[10];
    int age;
    double salary;
} jack, darren;  // 这种定义的方式,有默认的初始值。字符串是""
void main() {
    strcpy_s(jack.name, "Jack");
    jack.age = 99;
}
struct Worker {
    char name[10];
    int age;
    double salary;
} darren = {"Darren",22,1000}; // 直接给结构体赋值。
printf("name:%s, age:%d, salary:%lf。\n", darren.name,darren.age,darren.salary);

2.3.结构体嵌套,类似内部类。

struct Wrok{
    char name[10];
    char gradle[10]; // 等级
};

struct Worker {
    char name[10];
    int age;
    double salary;

    Wrok work;
} jack;
void main (){
    // 嵌套的初始化, 访问值。
    struct Worker worker = {"Darren",22,1000, {"Android", "中级"}};
    printf("w_name:%s, w_gradle%s \n", worker.work.name, worker.work.gradle);
}
#### 2.4.内部类的形式 结构体嵌套。
struct Worker {
    char name[10];
    int age;
    double salary;

    struct Wrok{
        char name[10];
        char gradle[10]; // 等级
    } work;
} jack;

2.5 结构体指针,可以使用箭头访问->.

通过结构体指针,可以操作数据。

struct Worker worker = {"tom", 23};
Worker* worker_p = &worker; 
// worker.age = 23;
worker_p->age = 23; // 另一种结构体操作方式。较常用。 
strcpy_s(worker_p->name, "Jack");
printf("name=%s, age=%d\n", worker_p->name, worker_p->age);

2.6 最常用,直接使用指针。

// Worker* worker = new Worker(); // 相当于创建了一个 结构体指针,初始化指针。
Worker* worker = (Worker*)malloc(sizeof(Worker)); // include <malloc.h>
worker-> age = 24;
strcpy_s(worker_p->name, "Jack"); //char* 赋值
printf("name=%s, age=%d\n", worker_p->name, worker_p->age);

if(worker) { // 释放
    free(worker); 
    worker=NULL;
}

3.结构体数组

void main(){
    // 创建结构体数组,第一种:静态开辟
    // Worker worker[10] = { {"Darren",23,1000},{},{},{},{} };// 创建了 10 个 ,静态开辟
    // worker[9] = {"Darren9",24,200};
    // printf("name = %s, age = %d\n", worker[9].name, worker[9].age);

    // 第二种:动态内存开辟 Worker* 结构体的指针
    Worker* worker = (Worker*)malloc(sizeof(Worker)*10); // 指针:有10个结构体
    strcpy_s(worker->name, "Darren0");
    worker->age = 10;
    printf("name = %s, age = %d\n", worker->name, worker->age); 

    // 对第10个位置数据进行操作?
    worker += 9; // 往后挪动9个位置。
    strcpy_s(worker->name, "Darren9");
    worker->age = 9;
    printf("name = %s, age = %d\n", worker->name, worker->age);
    getchar();
}

4.结构体占用大小的计算:字节对齐

struct Worker{// 定义一个结构体,相当于 java 的 class
    char name[18]; // 10,18 
    int age; // 4
    double salary;// 8
    // char name[10] 24 = 8+8+8。只按基本数据类型处理。
    // char name[18] 32 = 
    // 32 怎么来的? 18 + 4 +8 = 30 ,32
    // char name[12]; 结构体占用24字节;
    // char name[13]; 结构体占用32字节;
    // char name[20]; 结构体占用32字节;
    // char name[21]; 结构体占用40字节;
};

void main(){
    int size = sizeof(Worker);// 16字节(int age; double salary;)4字节要补成8字节。8+8=16
    // 计算的规则:
    // 1. 按照最大的字节去计算; 
    // 2. 算得时候只会按照基本数据类型去算;
    // 3. 首先会把所有字节数加起来,是否能够整除最大属性的字节数,如果不够为往上累加,一直加到能整除为止.
        // 8字节对齐(最大的double决定的),超出要补齐。
    // 4. 进阶:结构体单独加占用字节数。
    printf("size = %d", size); 
    getchar();
}
struct date { // 12字节 = 4+4+4字节
    int year;
    int month;
    int day;
};
struct student { // 结构体嵌套。36个字节 = 4+4+4+12 + 12 
    int number;// 4
    char sex;// 1
    int age;// 4
    char name[10];// 10 
    struct date birthday;// 12

    // 31%4  32%4  32字节? 还是36个字节?
};

struct Teacher { // 28字节 = 4+4+4 + 4+4+4+4 
    char d;
    int e;
    short f;
    int g;
} teacher;
struct tClass {
    char a;
    int b;
    short c;
    struct Teacher teacher1;
} tClass;
void main() {
    printf("date len:%d\n", sizeof(date)); // 12=4+4+4
    printf("struct len:%d", sizeof(student)); // 36字节
    printf("teacher len:%d\n", sizeof(teacher)); // 16=4+4+4+4
    printf("tClass len:%d", sizeof(tClass)); // 28字节。
    getchar();
}

5. 结构体取别名: typedef

typedef Worker Worker_, Person;
可以取多个别名。

void main(){
    Worker_ worker = {"tom",22, 23}; // 可以省略struct 关键字。
    printf("%s, %d, %lf\n", worker.name, worker.age, worker.salary); 

}

结构体的指针 取别名

typedef Worker* Worker_; // Worker_就是个指针。
Worker worker = (Worker*)malloc(sizeof(Worker_));
printf("%s, %d, %lf\n", worker.name, worker->age, worker->salary); 


// jni.h
struct _jfieldID; 
typedef struct _jfieldID* jfieldID;

6.联合体: union 使用上和结构体差不多。

联合体中,只能出现一种东西,只能拿到最后赋值的。
里面的元素,只能存在一个要么是name,要么是age。
比结构体更节省内存。初始化的时候,只能设置一个。

大小计算:取的最大值(最大成员的字节数)10, 由于不能被4整除,所以是12.
不用累加取最大值。

union Person
{
    // 最能出现一个 ,不用累加,找最大值 10-》 12字节
    char name[17]; // 10 
    int age; // 4 
    double salary;// 8
};

// 5. 联合体的定义和使用,联合体只能存在一个,要么是 age ,要么是 name 
void main() {
    // Person person = {"abc"};
    Person person;
    strcpy_s(person.name, "Tom");
    person.age = 33;
    printf("%s, %d,\n", person.name, person.age);
    printf("union size: %d", sizeof(person)); 
    // 10、4 =12(10向上 被4整除)
    // 10、4、8 =16(10向上 被8整除,12不能被8整除)
    getchar();
}

7.枚举的定义和使用。

枚举本质是int类型,默认从0开始累加。
后面的在前面基础上,累加。

enum CommentType {
    TEXT=10, TEXT_IMAGE, IMAGE
};
void main() {
    CommentType commentType1 = TEXT;
    CommentType commentType2 = TEXT_IMAGE;
    CommentType commentType3 = IMAGE;
    printf("cmt type: %d, %d,%d", commentType1,commentType2,commentType3);
    // 10,11,12
}

相关文章

网友评论

      本文标题:NDK-010:C5: 结构体 枚举

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