1、截取指定字符串
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//第一種
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++;
}
}
//第二種 理解棧區(qū) 堆區(qū)分配
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; //不能讓一級指針指向容器,函數(shù)執(zhí)行結(jié)束后會回收容器,main函數(shù)里result會為空
//指向容器問題解決1:使用copy
strcpy(*result, resultArr);
//指向容器問題解決2:動態(tài)分配內(nèi)存
// char * resultArr = malloc(end-start);
// int count = 0;
// for (int i = start; i < end; ++i) {
// resultArr[count] = *(temp + i);
// count++;
// }
// *result = resultArr; //不能讓一級指針指向容器,函數(shù)執(zhí)行結(jié)束后會回收容器,main函數(shù)里result會為空
//但是使用第二種要手動釋放,但是已釋放,main函數(shù)里還是為空,所以要在main函數(shù)釋放,
// 但是這種做法不好,如果提供給別人使用,你還要別人去釋放,所以推薦第一種
//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("截取的內(nèi)容:%s", result);
return 0;
}
一、結(jié)構(gòu)體
1、幾種寫法
//第一種寫法
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
struct Dog {
// 成員
char name[10]; // copy進(jìn)去
int age;
char sex;
}; // 必須給寫;
int main() {
struct Dog dog; // 這樣寫完,成員是沒有任何初始化的,成員默認(rèn)值 是系統(tǒng)值(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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
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不進(jìn)去
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 <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
struct Study {
char * studyContent; // 學(xué)習(xí)的內(nèi)容
};
struct Student {
char name[10];
int age;
char sex;
// Study study; // VS的寫法
struct Study study; // Clion工具的寫法
struct Wan {
char * wanContent; // 玩的內(nèi)容
} wan;
};
int main() {
struct Student student =
{"李元霸", 88, 'm' ,
{"學(xué)習(xí)C"},
{"王者農(nóng)藥"}
};
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;
}
二、結(jié)構(gòu)體指針
//棧區(qū)
#include <stdio.h>
#include <string.h>
struct Cat {
char name[10];
int age;
};
int main() { // 棧
// 結(jié)構(gòu)體
struct Cat cat = {"小花貓", 2};
// 結(jié)構(gòu)體 指針 -> 調(diào)用一級指針成員
// 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;
}
//堆區(qū)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
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);
// 堆區(qū)的必須釋放
free(cat);
cat = NULL;
return 0;
}
三、結(jié)構(gòu)體數(shù)組
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Cat {
char name[10];
int age;
};
int main() {
//靜態(tài)棧區(qū)
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);
}
//動態(tài)堆區(qū)
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 <stdio.h>
#include <stdlib.h>
struct DAO {
char name[10];
int age;
char sex;
};
// 匿名結(jié)構(gòu)體的別名(這樣寫意義不大,因為沒有名字)
typedef struct {
char name[10];
int age;
char sex;
};
// 源碼是這樣寫的
// 給結(jié)構(gòu)體 取了一個別名Person
typedef struct {
char name[10];
int age;
char sex;
} Person;
// 取一個別名
typedef struct DAO DAO;
void show(DAO dao) {} // 在不同工具上 又的要加,又的不用加 又差異化
int main() {
// VS 不需要這樣寫, Clion工具 要加入關(guān)鍵字 代碼不統(tǒng)一
// struct DAO * dao = malloc( sizeof(struct DAO));
// 加別名后 代碼的統(tǒng)一了
DAO * dao = malloc( sizeof(DAO));
// 加別名后 代碼的統(tǒng)一了
// C庫的源碼,系統(tǒng)源碼...,為什么 typedef 還取一個和結(jié)構(gòu)體一樣的名字(兼容代碼的寫法,保持一致)
Person p= {"lisi", 54, 'M'}; // 結(jié)構(gòu)體 VS Clion xxx工具 兼容寫法
Person * p = malloc(sizeof(Person)); // 結(jié)構(gòu)體指針
return 0;
}
五、枚舉
#include <stdio.h>
// 枚舉 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;
}