堆栈空间
C源代码进过预处理、编译、汇编和链接4步生成一个可执行程序。程序在没有运行之前,也就是说程序没有被加载到内存前,可执行程序内部已经分好3段信息,分别是代码区(text)、数据区(data)和未初始化数据区(bss)三个部分。(部分人直接把data和bss合起来叫做全局区或静态区)。
运行可执行程序,系统把程序加载到内存,除了根据可执行程序的信息分出代码区、初始化数据区和未初始化数据区之外,还额外增加了栈区和堆区。

linux下的内存分配:

结构体和结构体指针的内存申请
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct student//typedef可以将struct student结构体类型用std替代 { char name[20]; int number; char subject[20]; float scores; }std;
int main() { std student1; memset(&student1,0,sizeof(std)); printf("name:"); scanf("%s",student1.name); printf("%s\n",student1.name); std* student2 = (std*)malloc(sizeof(std)); if(student2 == NULL) { printf("malloc use failure"); return 1; } memset (student2,0,sizeof(std)); printf("name\n"); scanf("%s",student2->name); printf("name:%s\n",student2->name); free(student2); student2 = NULL; return 0; }
|
文件中读取结构体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include <stdio.h>
struct student { char name[20]; int age; };
int main() { struct student s1 = {"Tom", 18};
FILE *p = fopen("D:/File/student.dat", "w"); if(p == NULL) return 0; fwrite(&s1, 1, sizeof (struct student), p); fclose(p); struct student s2 = {0};
FILE *p2 = fopen("D:/File/student.dat", "r"); if(p2 == NULL) return 0; fread(&s2, 1, sizeof (struct student), p2); fclose(p2); printf("student : name=%s, age=%d\n", s2.name, s2.age); return 0; }
|
读取结构体数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include <stdio.h>
struct student { char name[20]; int age; };
int main() { struct student s1[2] = {{"Tom", 18}, {"Jerry", 20}};
FILE *p = fopen("D:/File/student.dat", "w"); if(p == NULL) return 0;
fwrite(s1, 2, sizeof (struct student), p); fclose(p);
struct student s2[2] = {0};
FILE *p2 = fopen("D:/File/student.dat", "r"); if(p2 == NULL) return 0;
fread(s2, 2, sizeof (struct student), p2); fclose(p2);
int i = 0; for(i = 0; i < 2; i ++) printf("student : name=%s, age=%d\n", s2[i].name, s2[i].age);
return 0; }
|
数据结构对于文件的增删查改
做了一个小系统遇到的问题
图书馆管理系统.c (gitee.com)
首先关于清屏linux有三种方式
1 2 3
| system("clear"); printf("x1b[Hx1b[2J"); printf ("033c");
|
虽然都是清屏但是略有区别,首先是system(“clear”)好处可以替代windows中的system(“clr”)不知道是什么问题调用写的次数多了,会有不执行的情况.之后是printf(“033c”)会清楚掉之前对于终端命令行打印颜色的命令,所以它应该是重置整个终端。
之后的一些问题基本都是结构体的问题都写在了前面。
stdout与stdin,stderr的区别
当一个用户进程被创建的时候,系统会自动为该进程创建三个数据流, 一个程序要运行,需要有输入、输出,如果出错,还要能表现出自身的错误。这是就要从某个地方读入数据、将数据输出到某个地方,这就够成了数据流。
因此,一个进程初期所拥有的这么三个数据流,就分别是标准输出、标准输入和标准错误,分别用stdout, stdin, stderr来表示。。这3个文件分别为标准输入(stdin)、标准输出(stdout)、标准错误(stderr)。
输出重定向是指把命令(或可执行程序)的标准输出或标准错误输出重新定向到指定文件中。这样,该命令的输出就不显示在屏幕上,而是写入到指定文件中。
使用 “ > ”符号,将标准输出重定向到文件中。形式为:命令>文件名
使用“ >> ”符号,将标准输出结果追加到指定文件后面。形式为:命令>>文件名
使用“ 2> ”符号,将标准错误输出重定向到文件中。形式为:命令 2> 文件名
使用“ 2>> ”符号,将标准错误输出追加到指定文件后面。形式为:命令 2>>文件名
使用“ 2>&1 ”符号或“ &> ”符号,将把标准错误输出stderr重定向到标准输出stdout
1 2 3 4 5 6
| int main(){ fprintf(stdout,"Hello "); fprintf(stderr,"World!"); return0; }
|
原理:在默认情况下,stdout是行缓冲的,他的输出会放在一个buffer里面,只有到换行的时候,才会输出到屏幕。
而stderr是无缓冲的,会直接输出,举例来说就是printf(stdout, “xxxx”) 和 printf(stdout, “xxxx\n”),前者会憋住,直到遇到新行才会一起输出。而printf(stderr, “xxxxx”),不管有么有\n,都输出。