本节内容
-
1.动态分配内存
-
2.文件的相关内容
-
3.动态分配内存实战——名字的输入与输出
-
4.结构体
(一)动态分配内存
-
1.常量区:常量字符串的空间由系统自动分配,在常量区分配,当程序结束时才会释放。在常量区存放常量:const int a=1;
-
2.静态区:static,静态变量只会被定义一次。static int a=0;静态变量的生命周期——从开始到结束;预编译就已经开始了。
-
3.堆:在堆存放局部变量,离开作用域就会被系统自动收回。
-
4.栈:栈是自己申请的内存空间,如malloc,realloc,calloc都是申请内存的函数,必须由自己释放,用free函数。
-
5.为什么需要动态分配内存?(1)存储的数据需要延长生命周期。(2)一个指针变量需要存储内存数据,变量本身只能存地址,不能存数据
-
6.如果使用指针变量接收数据,那么就必须先为这个指针变量分配内存空间,有内存空间,才能存数据。导入头文件#include<stdlib.h>,使用malloc申请内存空间。name=(char )malloc(10sizeof(char));为字符串申请内存。
-
7.空指针里没有内存,如果只是定义一个指针,那么它没有内存。
-
8.使用realloc动态改变已经分配内存的大小,或增加或减少。
-
9.结束时,必须使用free函数将已经申请的内存释放掉。
(二)文件的相关内容
一般的普通变量、常量、静态变量等,在程序结束后也就没了。自动申请的内存,在电脑关机后也没了。但是电脑的开机密码,不论是程序结束还是电脑重启,都一直存在,这个数据永久被保存。内存只是为正在运行的程序分配空间,而硬盘,则可以在文件中永久保存这些数据。
FILE *fp=fopen("\\Users\\86178\\Pictures\\Saved Pictures\\test.txt",
"r");
中间的\Users\86178\Pictures\Saved Pictures是某张图片的位置。后面的r则是read。
fputs("你好",fp);
//读取内容 一行一行地读取
fgetc(fp);
//按照一定的格式写入内容
int num[5]={1,2,3,4,5};
//写入的是二进制 图片 视频 音频 结构体
fwrite(num,sizeof(num),1,fp);
// 写什么 这个写的东西多大 写几个 写到哪里去
int num2[5]={};
fread(num2,sizeof(num2),1,fp);
for(int i=0;i<5;i++){
printf("%d",num2[i]);
}
fclose(fp);
return 0;
}
以上的相关操作可以在我们用程序创建的文件夹中产生1,2,3,4这几个数字。
(三)动态分配内存实战——名字的输入与输出
项目内容:合理的分配内存,从终端输入一个名字之后,系统再打印出这个人名。并且询问用户是否继续,是的话就接着输入,否则就结束。
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
.......
//从终端接收字符串,并返回这个字符串的首地址
char *inputName(){
//1.定义一个指针变量,指向字符串的首地址。
char*pName =NULL;
//2.接收输入
int i=0;
//3.提示操作
printf("请输入人名:");
while(1){
//接收一个字符
char c=getchar();
//判断这个字符是不是\n
if(c=='\n'){
break;}
//判断是不是第一个字符
if(i==0){
//使用malloc分配内存
pName=(char*)malloc(1*sizeof(char));
//判断是否分配成功
if(pName==Null){
exit(EXIT_FAILURE);}
pName[0]=c;
}else{
//使用realloc在之前的基础上再加上一个
pName=realloc(pName,(i+1)*sizeof(char));
//判断是否分配成功
if(pName=NULL){
exit(EXIT_FAILURE);}
pName[i]=c;}
i++;
}
//将当前的字符串首地址返回
return pName;}
以上内容可分为一下几个步骤
-
1.先从终端接收一个字符。
-
2.判断这个字符是不是'\n',如果是的话就break;如果不是的话就判断这是否为从终端接收的第一个字符。如果是第一个字符,那么就用malloc首先为它分配一个内存。如果不是第一个字符,就根据它是第几个字符,使用realloc函数来扩大内存。
-
3.在每次分配完内存后,都要判断一下是否分配成功。如果分配失败就退出,如果分配成功就把c的值赋给p[i]。
-
4.每次结束后就i++一次。
//是否继续
bool isCountinue(){
peintf("是否继续(y\n)?:");
while(1){
char c=getchar();
getchar();//接收回车
if(c=='y'){
return ture;}else if(c=='n'){
return false; }else{
printf("输入格式不对,请重新输入:");}
}
}
以上内容便是,在用户输入了一个名字之后,提示用户是否要继续。
//初始化整个数组
char **initNames(int *pNum){
//1.定义指针变量指向每个名字的首地址的内存
char**pHead=NULL;
//2.记录元素个数
int i=0;
while(1){
//判断是不是第一个
if(i==0){
pHead=malloc(1*sizeof(char*));
if(pHead=NULL){
exit(EXIT_FAILURE);
}
//输入人名,将地址放到pHead对应的位置
pHead[i]=inputName();
}else{
//使用realloc重新再增加一个元素
pHead=realloc(pHead,(i+1)*sizeof(char*));
if(pHead=NULL){
exit(EXIT_FAILURE);}
//输入人名,将地址存放到pHead对应的位置
pHead[i]=inputName();
}
i++;
//是否继续
bool result =isCountinue();
if(result==false){
break ;
}
}
*pNum=i;
return pHead;
}
void show(char**pHead,int num){
printf("输入%d个名字:\n",num);
for(int i=0;i<num;i++){
printf("%s\n",pHead[i]);}
printf("\n");
}
以上内容是对整个数组的初始化,最后在main函数中实现就行了。
int main(){
char**pHead=NULL;
int count=0;
pHead=initNames(&count);
show(pHead,count);
return 0;
}
(四)——结构体
-
像int ,float ,char这些数据类型只能存单个数据。int num[];数组可以存多个数据,但必须是同种类型。如果我们想要存储多个不同的数据类型的数据时,就需要使用我们的结构体了。
-
1.为什么使用结构体——需要使用一种类型,这种类型可以保存多种数据
-
2.结构体是什么——一种数据类型
-
3.如何定义结构体类型——注意:定义结构体类型时,内部类型不能赋初值。
struct student{
int age;
char sex;
char name[10];
}
struct student xw;
struct student lw={40,'m',"隔壁老王"};
lw.age=35;//给结构体内部的变量赋值
-
5.结构体类型内存字节数计算——对齐方式,小内存->大内存。
-
例如:如果结构体内有int a 和char b,则总的字节数就为4+4=8;因为char类型向int对齐,所以都是四个字节。
好了,以上就是我们今天的全部内容啦。期末就要来了,祝大家好好学习,考出一个好成绩。