1、截取指定字符串
#include
#include
#include
//第一种
void substrAction1(char *result, char *str, int start, int end) {
char *temp = str; //定义临时指针,不破坏str
int count = 0;
while (*temp) {
if (count >= start && count < end) {
*result = *temp; //边移动指针边接收值
result++;
}
temp++;
count++;
}
}
//第二种 理解栈区 堆区分配
void substrAction2(char **result, char *str, int start, int end) {
char *temp = str;
//合理分配,用多少分配多少
char resultArr[end - start];
int count = 0;
for (int i = start; i < end; ++i) {
resultArr[count] = *(temp + i);
count++;
}
// *result = resultArr; //不能让一级指针指向容器,函数执行结束后会回收容器,main函数里result会为空
//指向容器问题解决1:使用copy
strcpy(*result, resultArr);
//指向容器问题解决2:动态分配内存
// char * resultArr = malloc(end-start);
// int count = 0;
// for (int i = start; i < end; ++i) {
// resultArr[count] = *(temp + i);
// count++;
// }
// *result = resultArr; //不能让一级指针指向容器,函数执行结束后会回收容器,main函数里result会为空
//但是使用第二种要手动释放,但是已释放,main函数里还是为空,所以要在main函数释放,
// 但是这种做法不好,如果提供给别人使用,你还要别人去释放,所以推荐第一种
//free(resultArr);
printf("%s\n", resultArr);
}
//第三中
void substrAction3(char *result, char *str, int start, int end) {
for (int i = start; i < end; ++i) {
*(result++) = *(str + i);
}
}
//第三中
void substrAction4(char *result, char *str, int start, int end) {
strncpy(result,str+start,end-start);
}
int main() {
char *str = "HelloWorld";
char *result;
//substrAction1(result, str, 2, 5);
//substrAction2(&result, str, 2, 5);
//解决指向容器问题的,第二种方法的释放
// if (result){
// free(result);
// result = NULL;
// }
//substrAction3(result, str, 2, 5);
substrAction4(result, str, 2, 5);
printf("截取的内容:%s", result);
return 0;
}
一、结构体
1、几种写法
//第一种写法
#include
#include
#include
#include
struct Dog {
// 成员
char name[10]; // copy进去
int age;
char sex;
}; // 必须给写;
int main() {
struct Dog dog; // 这样写完,成员是没有任何初始化的,成员默认值 是系统值(name:?@, age:3133440, sex:)
printf("name:%s, age:%d, sex:%c \n", dog.name, dog.age, dog.sex);
// 赋值操作
// dog.name = "旺财";
strcpy(dog.name, "旺财");
dog.age = 3;
dog.sex = 'G';
printf("name:%s, age:%d, sex:%c \n", dog.name, dog.age, dog.sex);
return 0;
}
//第二种写法
#include
#include
#include
#include
struct Person {
// 成员
char * name; // 字符指针 = "赋值"
int age;
char sex;
} ppp = {"Derry", 33, 'M'},
ppp2,
ppp3,
pppp4,
pppp5
// ...
;
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);
return 0;
}
//第三种
#include
#include
#include
#include
struct Study {
char * studyContent; // 学习的内容
};
struct Student {
char name[10];
int age;
char sex;
// Study study; // VS的写法
struct Study study; // Clion工具的写法
struct Wan {
char * wanContent; // 玩的内容
} wan;
};
int main() {
struct Student student =
{"李元霸", 88, 'm' ,
{"学习C"},
{"王者农药"}
};
printf("name:%s, age:%d, sex:%c,study:%s, wan:%s \n",
student.name, student.age, student.sex, student.study.studyContent, student.wan.wanContent);
return 0;
}
二、结构体指针
//栈区
#include
#include
struct Cat {
char name[10];
int age;
};
int main() { // 栈
// 结构体
struct Cat cat = {"小花猫", 2};
// 结构体 指针 -> 调用一级指针成员
// VS的写法:Cat * catp = &cat;
struct Cat * catp = &cat;
catp->age = 3;
strcpy(catp->name, "小花猫2");
printf("name:%s, age:%d \n", catp->name, catp->age);
return 0;
}
//堆区
#include
#include
#include
struct Cat2 {
char name[10];
int age;
};
int main() { // 堆
// VS的写法:Cat2 * cat = (Cat2 *) malloc(sizeof(Cat2));
struct Cat2 *cat = malloc(sizeof(struct Cat2));
strcpy(cat->name, "金色猫");
cat->age = 5;
printf("name:%s, age:%d \n", cat->name, cat->age);
// 堆区的必须释放
free(cat);
cat = NULL;
return 0;
}
三、结构体数组
#include
#include
#include
struct Cat {
char name[10];
int age;
};
int main() {
//静态栈区
struct Cat cat[5] = {
{"小白", 3},
{"小黑", 4},
{"小黄", 5},
{},
{}
};
//VS写法
//cat[4] = {'小红',6};
//Clion
struct Cat cat1 = {"小红", 6};
//cat[4] = cat1;
*(cat + 4) = cat1;
for (int i = 0; i < 5; ++i) {
printf("%s的年龄是%d\n", cat[i].name, cat[i].age);
}
//动态堆区
struct Cat *cat2 = malloc(sizeof(struct Cat) * 5);
//赋值
strcpy(cat2->name, "小狼"); //首地址第一个元素
cat2->age = 6;
printf("name:%s,age:%d\n", cat2->name, cat2->age);
//给第三个赋值
cat2 += 2;
strcpy(cat2->name,"小虎");
cat2->age = 7;
printf("name:%s,age:%d", cat2->name, cat2->age);
free(cat2);
cat2 = NULL;
return 0;
}
四、别名
#include
#include
struct DAO {
char name[10];
int age;
char sex;
};
// 匿名结构体的别名(这样写意义不大,因为没有名字)
typedef struct {
char name[10];
int age;
char sex;
};
// 源码是这样写的
// 给结构体 取了一个别名Person
typedef struct {
char name[10];
int age;
char sex;
} Person;
// 取一个别名
typedef struct DAO DAO;
void show(DAO dao) {} // 在不同工具上 又的要加,又的不用加 又差异化
int main() {
// VS 不需要这样写, Clion工具 要加入关键字 代码不统一
// struct DAO * dao = malloc( sizeof(struct DAO));
// 加别名后 代码的统一了
DAO * dao = malloc( sizeof(DAO));
// 加别名后 代码的统一了
// C库的源码,系统源码...,为什么 typedef 还取一个和结构体一样的名字(兼容代码的写法,保持一致)
Person p= {"lisi", 54, 'M'}; // 结构体 VS Clion xxx工具 兼容写法
Person * p = malloc(sizeof(Person)); // 结构体指针
return 0;
}
五、枚举
#include
// 枚举 int 类型的
enum CommentType {
TEXT = 10,
TEXT_IMAGE,
IMAGE
};
typedef enum CommentType CommentType;
int main() {
// Clion工具的写法如下:
// enum CommentType commentType = TEXT;
//enum CommentType commentType1 = TEXT_IMAGE;
// enum CommentType commentType2 = IMAGE;
// VS工具的写法如下:
// CommentType commentType = TEXT;
//取别名后
// CommentType commentType = TEXT;
printf("%d, %d, %d \n", commentType, commentType1, commentType2);
return 0;
}