坚持一年,目标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
}
网友评论