#include
#include
#include
typedef struct student {
int age;
int grade;
char name[20];
} stu;
// 1.排序功能
int sort(stu* p, int length) {
stu temp;
int i, j;
for (i = 0; i < length; i++) {
for (j = 0; j < length - 1 - i; j++) {
// 1.排序规则:比较成绩,若成绩相同比较名字首字母
if (p[i + 1].grade > p[i].grade) {
temp = *(p + i); //*()=[]:——>*(p+i)=p[i]
p[i] = p[i + 1];
p[i + 1] = temp;
} else if (p[i + 1].grade == p[i].grade &&
p[i + 1].name[0] > p[i].name[0]) {
temp = p[i];
p[i] = p[i + 1];
p[i + 1] = temp;
}
}
}
return 1;
}
// 2.将数据加载到文件中
void ToFile(FILE* fp, stu* p, int length) {
int i, j;
// 2.追加内容
for (i = 0; i < length; i++) {
fprintf(fp, "学生成绩:%d\t学生年龄:%d\t学生姓名:%s\n",
(p + i)->grade, (p + i)->age, (p + i)->name);
printf("学生成绩:%d\t学生年龄:%d\t学生姓名:%s\n", (p + i)->grade,
(p + i)->age, (p + i)->name);
}
printf("追加完毕!\n");
}
// 3.寻找指定数据
void search(stu* p, char s_name[], int length) {
int i;
for (i = 0; i < length; i++) {
// 1.根据name名称寻找对应数据
if (strcmp((*(p+i)).name, s_name)==0) {
printf("%s的成绩:%d,当前年龄:%d\n", p[i].name, (*(p + i)).grade,
(p + i)->age);
}
}
}
int main() {
int i, j;
FILE* fp;
// 1.首先给stu声明一个结构体变量
stu s[3] = {{19, 90, "Fairy"}, {21, 88, "Barry"}, {23, 91, "Fox"}};
stu* p = s; //补充:s是一个数组,所以不需要用取地址符了&
int len = sizeof(s) / sizeof(stu);
// 1.打开文件,这里注意将读取文件放在外面,因为放在函数中,函数外的文件读写操作就会作废
fp = fopen("Grade.txt", "a");
if (fp == NULL) {
printf("OPEN ERROR!");
exit(0);
}
// 2.上传排序前的文件
fputs("排序前数据\n", fp);
ToFile(fp, p, len);
// 4.对数据进行排序
int success = sort(p, len);
printf("排序完毕\n");
// 5.输出排序后的数据
fputs("排序后的数据\n", fp);
ToFile(fp, p, len);
// 6.寻找数据
char name[20];
printf("请输入你想要搜索的名字\n");
scanf("%s", name);
search(p, name, len);
return 0;
}
结果:
开始运行...
学生成绩:90 学生年龄:19 学生姓名:Fairy
学生成绩:88 学生年龄:21 学生姓名:Barry
学生成绩:91 学生年龄:23 学生姓名:Fox
追加完毕!
排序完毕
学生成绩:90 学生年龄:19 学生姓名:Fairy
学生成绩:91 学生年龄:23 学生姓名:Fox
学生成绩:88 学生年龄:21 学生姓名:Barry
追加完毕!
请输入你想要搜索的名字
Fox
Fox的成绩:91,当前年龄:23
#include
#include
int main() {
/**
文件类型:
(1)文本文件:以字符编码的方式保存。(2)二进制文件:将内存中的数据原封不动的放至文件中,主要以非字符数据为主
1.fopen("文件名","打开方式:r,w,a"):文件的打开
r:只读,若文件不存在则打开失败
w:只写:如果文件不存在则会创建文件,若存在则会清空文件再写(非追加方式)
a:append:文件不存在会创建文件,若文件存在则会在已有内容的基础上进行追加
2.fpuc("具体字符","文件指针"):将一个字符输入到文件
3.fpus("字符串","文件指针"):将文件输入一串字符串
**/
int i, j;
FILE* fp = fopen("P211.txt", "w+");
char s[10];
char ch;
if (fp == NULL) {
printf("打开文件失败!\n");
exit(0);
}
// 1.输入s的内容(关键函数:(1)puts:将控制台输入的字符串->s数组中)
// (2)fputc:将单个字符输入到fp文件中
printf("给文章添加内容(串):\n");
gets(s);
for (i = 0; s[i] != '\0'; i++) {
fputc(s[i], fp);
}
// 2.给文章添加单个字符
printf("给文章添加内容(单个字符):\n");
scanf("%c", &ch);
printf("您输入的字符是%c\n", putchar(ch));
fputc(ch, fp);
/**
2.
fgetc("文件指针"):从文件读出一个字符
注意:EOF视为文件的结束符
putchar("字符"):将字符输出的控制台上
**/
ch = fgetc(fp);
while (fp!= EOF) {
putchar(ch); //2.如果字符不是EOF结束符就将其输出到控制台
ch = fgetc(fp); //3.从fp所指向的文件中继续获取字符
}
/**
3.
fprintf(文件指针,格式字符串,输出列表)
fscanf(文件指针,格式字符串,输出列表)
**/
for(i=1;i<=9;i++){
for(j=1;j<=i;j++){
fprintf(fp, "%d*%d=%d\t", j,i,j*i);
}
fprintf(fp, "\n");
}
fclose(fp);
}
#include
#include
#include
#define N 2 + 3
#define f(x) x* x
/**
1.编译预处理
1.三种:宏定义,文件包含,条件编译
2.预处理:以#开头,每一行只能写预处理命令
3.不加分号
4.宏定义: #define 宏名 替换文本(不能作表达式运算)
注意宏定义可以定义函数
5.文件包含:#include
<文件名>:查找系统指定目录所包含的文件/"文件名":查找用户目录的指定文件
**/
typedef struct student {
int age;
char name[20];
} stu;
/**
2.结构体的性质:
2.1结构体数据类型定义s部分不占内存,变量占内存(先定义类型,再使用变量)
2.2:typedef int IN:目的:起别名,表示给数据类型起别名,名字为IN
2.3:typedef struct s{
}student;中s和student的区别:student是别名,而s是结构体类型的声明,student是为该声明进行简化来的
--------------------
typedef struct和普通struct的区别:
前者是取别名,具体的变量引用还需要在main方法中声明结构体变量;
后者是帮助结构体声明了引用变量 ;
eg.
struct student{
.....
}stu;
main{
stu.age即可
}
而typedef struct student{
.....
}stu;只是充当起别名作用
main{
还需要定义引用变量
stu s={xx,"xx"};
}
--------------------
2.4:结构体成员的引用
@1.结构体变量.成员名
@2.结构体指针——>成员名
@3.*(结构体指针).成员名
----------------------
2.5:
在结构体typedef结构体定义中,不能直接对结构体进行初始化赋值——>1.可以将typedef
struct student改为struct student即可
-----------------------
2.6补充sizeof字节数:
struct student {
int age;
char name[20];
} stu,*p&stu;中sizeof(p)=?:获取指针变量的大小,与结构体无关
--------------------------
**/
int main() {
int a, b;
a = N * N;
b = N / N;
// 1.函数宏定义
a = f(a) + f(b);
printf("%d\n", a);
printf("--------结构体-----------\n");
stu s = {18, "mike"};
stu* p = &s;
// 1.结构体变量的引用
printf("%s年龄:%d\n", p->name, p->age);
printf("%c是%s的首字母\n", p->name[0], p->name);
printf("%c是%s的首字母\n", s.name[0], p->name);
// 2.引用所指向内容的修改(strcpy(目标指针指向的内容,src))
strcpy(p->name, "Fairy");
strcpy(s.name, "Fairy同学");
printf("%s年龄:%d\n", p->name, p->age);
//3.指针变量的大小:64bit为8,32位为4
//VC下,int通常占4字节,char1字节,double占8字节,long是4字节,float也是4字节
printf("%zu",sizeof(p));
return 0;
}
#include
#include
#include
typedef struct Student {
int no;
char name[20];
struct Student* next;
} StudentNode;
// 创建学生节点
StudentNode* createStudentNode(int no, const char* name) {
StudentNode* node = (StudentNode*)malloc(sizeof(StudentNode));
node->no = no;
strcpy(node->name, name);
node->next = NULL;
return node;
}
// 插入学生节点
void insertStudentNode(StudentNode** head, int no, const char* name) {
StudentNode* newNode = createStudentNode(no, name);
if (*head == NULL) {
*head = newNode;
} else {
StudentNode* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
}
// 删除学生节点
void deleteStudentNode(StudentNode** head, int no) {
if (*head == NULL) {
return;
}
StudentNode* temp = *head;
if (temp->no == no) {
*head = temp->next;
free(temp);
return;
}
StudentNode* prev = NULL;
while (temp != NULL && temp->no != no) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) {
return;
}
prev->next = temp->next;
free(temp);
}
// 修改学生节点
void modifyStudentNode(StudentNode* head, int no, const char* name) {
StudentNode* temp = head;
while (temp != NULL) {
if (temp->no == no) {
strcpy(temp->name, name);
return;
}
temp = temp->next;
}
}
// 查找学生节点
StudentNode* searchStudentNode(StudentNode* head, int no) {
StudentNode* temp = head;
while (temp != NULL) {
if (temp->no == no) {
return temp;
}
temp = temp->next;
}
return NULL;
}
// 打印链表中的学生信息
void printStudentList(StudentNode* head) {
StudentNode* temp = head;
while (temp != NULL) {
printf("No: %d, Name: %s\n", temp->no, temp->name);
temp = temp->next;
}
}
// 释放链表内存
void freeStudentList(StudentNode** head) {
StudentNode* temp = *head;
while (temp != NULL) {
StudentNode* nextNode = temp->next;
free(temp);
temp = nextNode;
}
*head = NULL;
}
int main() {
StudentNode* head = NULL;
// 插入学生节点
insertStudentNode(&head, 1, "Alice");
insertStudentNode(&head, 2, "Bob");
insertStudentNode(&head, 3, "Charlie");
// 打印链表中的学生信息
printf("Initial student list:\n");
printStudentList(head);
// 修改学生节点
modifyStudentNode(head, 2, "Brian");
printf("\nAfter modifying student 2:\n");
printStudentList(head);
// 删除学生节点
deleteStudentNode(&head, 1);
printf("\nAfter deleting student 1:\n");
printStudentList(head);
// 查找学生节点
StudentNode* student = searchStudentNode(head, 3);
if (student != NULL) {
printf("\nFound student 3: No=%d, Name=%s\n", student->no, student->name);
} else {
printf("\nStudent 3 not found.\n");
}
// 释放链表内存
freeStudentList(&head);
return 0;
}
1
注意事项:
对于字符串数组 char str1[5] = “apple”,数组的大小为 5。这是因为在 C 语言中,字符串必须以结束符 \0 结尾,占据一个额外的字节空间。
在这个例子中,虽然字符串 “apple” 本身只包含 5 个字符(a、p、p、l、e),但编译器会自动在字符串的末尾添加一个结束符 \0。因此,实际上占据了 6 个字节的内存空间。
所以,尽管数组 str1 的大小为 5,但是为了容纳字符串 “apple” 及其结束符,编译器会自动将其扩展到 6 个字节的空间,最后一个字节用于存储结束符 \0。
要注意的是,由于数组大小只有 5,而字符串需要的空间至少为 6(包括结束符),所以在这种情况下会发生缓冲区溢出的问题。应该确保数组大小足够容纳字符串及其结束符 \0,以避免潜在的问题。
#include
#include
int main() {
char str1[] = "apple";
char str2[] = "bababa";
// 1.strcmp用来对比两个字符串是否相同?0(相同);<0(str1
printf("-------------strcmp---------\n");
int res = strcmp(str1, str2);
if (res == 0) {
printf("字符串相同\n");
} else if (res < 0) {
printf("str1小于str2\n");
} else {
printf("str1>str2\n");
}
// 2.strcat():用于将字符串进行拼接
printf("-------------strcat----------\n");
strcat(str1, str2);
printf("%s\n", str1);
//strcat并不会改变字节数,但是会改变长度
int len=strlen(str1);
printf("字节数:%zu\t串长度为:%d\n", sizeof(str1),len);
//3.strcpy作用:将str1复制到str3(第一个参数是接受的,第二个参数是输出的)
printf("----------strcpy----------\n");
char str3[2];
strcpy(str3,str1);
int length=strlen(str3);
printf("str3:%s\t长度为%d\t字节数为%zu\n",str3,length,sizeof(str3));
return 0;
}