苏小红C语言程序设计第十二、十三章知识总结

第十二章、结构体和共用体

12.1 结构体

  • 数组:是将同种属性的数据进行一次处理
  • 结构体:将不同类型的数据成员组织到统一的名字下
  • 共用体:将不同类型的数据成员组织到统一的名字下,但是每一时刻只有一个数据成员起作用
struct student
{long studentID;//学号char studentName;//姓名char studentSex;//性别int yearOfBirth;//出生年int score[4];//4门课的成绩
};

注意:结构体模板只声明了一种数据类型,并未声明结构体类型变量。编译器不为其分配内存空间,正如编译器不为int型分配内存一样

1、 先声明结构体模板,在定义结构体变量:struct student stu1;

2、在声明结构体变量的同时定义结构体变量,也可以不出现结构体名(student)

struct student
{
long studentID;//学号
char studentName;//姓名
char studentSex;//性别
int yearOfBirth;//出生年
int score[4];//4门课的成绩
}stu1;

用typedef定义数据类型

typedef int INTEGER;INTEGER和int是同义词。

typedef struct student STUDENT;
//等价于
typedef struct student
{
long studentID;//学号
char studentName;//姓名
char studentSex;//性别
int yearOfBirth;//出生年
int score[4];//4门课的成绩
}STUDENT;

二者为struct student结构体定义了一个新名字STUDENT。

结构体变量的初始化

STUDENT stu1={111,“张三”,“男”,1991,{80,80,80,80}};
//等价于:
struct student stu1={111,“张三”,“男”,1991,{80,80,80,80}};

嵌套的结构体

typedef struct date
{int year;int month;int day;
}DATE;typedef struct studet
{long studentID;//学号char studentName;//姓名char studentSex;//性别DATE Birthday;//出生年月日int score[4];//4门课的成绩
}STUDENT;
STUDENT stu1={111,“张三”,“男”,{1998,6,4},{80,80,80,80}};

结构体变量的引用和赋值 

#include
typedef struct date
{int year;int month;int day;
}DATE;typedef struct student
{long studentID;char studentName[20];char studentSex;DATE birthday;int score[4];
}STUDENT;int main()
{STUDENT stu1={111,"张三","男",{1998,6,4},{80,80,80,80}};STUDENT stu2;stu2=stu1;//相同类型的结构体的变量可以整体赋值printf("%ld%s%c%d/%d/%d%d%d%d%d\n",stu2.studentID,stu2.studentName,stu2.studentSex,stu2.birthday.year,stu2.birthday.month,stu2.birthday.day,stu2.score[0],stu2.score[1],stu2.score[2],stu2.score[3]);return 0;
}

并非所有的结构体成员都可以用赋值运算符(=)进行赋值,对于字符数组类型的结构体成员赋值时,必须用字符串处理函数strcpy():strcpy(stu2.studentName,stu2.studentName);

在函数体外声明的结构体可以为所有函数使用,称为全局声明;在函数体内声明的结构体可以为所有函数使用,称为局部声明;结构体变量的地址是结构变量所占内存空间的首地址。而结构体成员的地址与结构体成员在结构体中的位置和该成员所占内存空间大小有关。

结构体所占内存的字节数

#include
typedef struct sample
{char m1;int m2;char m3;
}SAMPLE;
int main()
{SAMPLE S={'A',2,'b'};printf("%d\n",sizeof(s));return 0;
}

输出:12

按道理应该1+1+4=6,但是为了满足处理器的对齐要求,可能会在较小的成员后加入补位。

结构体数组的定义和初始化

#include
typedef struct date
{int year;int month;int day;
}DATE;
typedef struct student
{long studentID;char studentName[20];char studentSex;DATE birthday;int score[4];
}STUDENT;
int main()
{int i,j,sum[30];STUDENT stu[30]={{111,"张三","男",{77,77,77,77}},{112,"李四","男",{77,77,77,77}},{113,"王五","女",{77,77,77,77}},{114,"周六","女",{77,77,77,77}}};for(i=0;i<4;i++){sum[i]=0;for(j=0;j<4;j++){sum[i]+=stu[i].score[j];}printf("%ld%s%c%d/%d/%d%d%d%d%d%f\n",stu2.studentID,stu2.studentName,stu2.studentSex,stu2.birthday.year,stu2.birthday.month,stu2.birthday.day,stu2.score[0],stu2.score[1],stu2.score[2],stu2.score[3],sum[i]/4.0);}return 0;
}

结构体指针定义和初始化

STUDENT *p;
p = &stu1;
//等价于
STUDENT *P = &stu1;

指针变量指向的结构体成员用指向运算符

p->studentID=111;
//等价于:
(*p).studentID=111;
p->birthday.year=1991;//对于结构体内部数组成员的访问

向函数传递结构体

#include
struct date
{int year;int month;int day;
};
//void fun(struct date *p)
void fun(struct date p)
{p.year=2000;p.month=5;p.day=22;
}
int main()
{struct date b;b.year=1999;b.month=4;b.day=21;//fun(&b);传址调用,结构体变量的成员值会修改fun(b);//结构体变量作为实参,传值调用,结构体变量的成员值不会修改return 0;
}#include
struct date
{int year;int month;int day;
};
struct date fun(struct date p)
{p.year=2000;p.month=5;p.day=22;return p;
}
int main()
{struct date b;b.year=1999;b.month=4;b.day=21;b=fun(b);//将函数返回值作为结构体变量的值return 0;
}

 12.2共用体

#include
union sample
{short i;char ch;float f;
};
typedef union sample SAMPLE;
int main()
{printf("%d\n",sizeof(SAMPLE));SAMPLE num; num.i=20;return 0;
}

输出4个字节。共用体类型所占内存空间的大小取决于其成员中占内存空间最大的哪一个。在每一瞬间起作用的成员就是最后一次被赋值的成员,不能为共用体的所有成员同时进行初始化,只能对第一个成员进行初始化共用体不能进行比较操作,也不能作为函数的参数

枚举数据类型

enum response{no,yes,none};//定义了一个枚举类型,no->0,yes->1,none->2;
enum response answer;//定义了一个枚举类型的变量
if(answer==yes)
{…;
}
//定义并初始化
enum{no,yes,none}answer;

定义一个枚举类型的数组

enum response answer[10];
enum response{no=-1,yes=1,none=0};//指定枚举常量的值
enum response{no=1,yes,none};//其后依次递增1

枚举常量虽然是字符串,但是以整数值表示。

12.3动态数据结构—单向链表

//链表只能顺序访问,不能随机访问,尾插法
#include
struct link
{int date;struct link *next;
};
struct link *AppendNode(struct link *head)
{struct link *p=NULL,*pr=head;int date;p=(struct link *)malloc(sizeof(struct link));if(p==NULL){exit(0);}if(head==NULL){head=p;}else{while(pr->next!=NULL){pr=pr->next;}pr->next=p;scanf("%d",&date);p->date=date;p->next=NULL;return head;}
}void DisplyNode(struct link *head)
{struct link *p=head;while(p!=NULL){printf("%d ",p->date);p=p->next;}
}void DeleteMemory(struct link *head)
{struct link *p=head,*q=NULL;while(p!=NULL){q=p;p=p->next;free(q);}
}int main()
{int i=0;//节点的个数char c;struct link *head=NULL;scanf(" %c",&c);//前面有一个空格while(c='y'||c='Y'){head=AppendNode(head);DisplyNode(head);scanf(" %c",&c);i++;}DeleteMemory(head);return 0;
}

第十三章、文件操作

13.1二进制文件和文本文件

文本文件:每一位数字作为一个字符以ASCII的形式存储的,每一个数字占用一个字节的存储空间。
二进制文件:把整个多位数字作为一个二进制数来存储。

文件的打开和关闭:
FILE *fopen(const char *filename,const char *mode);
第一个参数表示文件名,包含路径和文件名两个部分。
第二参数表示打开方式

  • “r”:只读方式打开文本文件
  • “w”:只写方式,创建并打开文本文件,已存在的文件将被覆盖
  • “a”:只写方式,打开文本文件,向文件尾部添加数据。
  • “+”:与上面的字符串组合,表示以读写的方式打开文本文件
  • “b”:与上面的字符串组合,表示打开二进制文件
FILE *fp;
fp=fopen(“D:\demo.txt”,“ab+”);
fclose(fp);

文件打开后记得关闭:int fclose(FILE *fp);关闭成功,返回0值;否则返回非0值。

13.2读写文件

按字符读写文件

//从fp文件中读取一个字符,并将指针指向下一个字符。读取成功,返回该字符;否则返回EOF。
int fgetc(FILE *fp);
int fputc(int c,FILE*fp);//将字符C写入fp文件中,写入错误,返回EOF;否则返回字符c。
//写入字符到文件中
#include
#include
int main()
{FILE *fp;char ch;if((fp=fopen("demo.txt","w"))==NULL)//看是否打开成功{exit(0);}ch=getchar();while(ch!='\n')  //以回车符作为文件的结尾{fputc(ch,fp);ch=getchar();//输入字符到缓冲区,直到键入回车符才从缓冲区逐个读出并赋值给ch。}fclose(fp);//从文件中读出字符if((fp=fopen("demo.txt","rb"))==NULL){exit(0);}/*ch=fgetc(fp);while(!feof(fp)) feof()来判断是否读到文件末尾,是返回非0值{putchar(ch);ch=fgetc(fp);if(isprint(ch))  判断是否为可打印字符{printf("%c\n",ch);}}*/while((ch=fgetc(fp))!=EOF){putchar(ch);}fclose(fp);return 0;
}
//读写文件中的字符串
char *fgets(char *s,int n,FILE *fp);
//从fp中读取n-1个字符,在字符串的末尾加上'\0',存入s。读取失败,返回空指针。
int fputs(const char *s,FILE *fp);
//fgets与gets不同,会将换行符也读入;fputs与puts不同,不会在写入文件的结尾加上换行符。#include
#include
#define N 80
int main()
{FILE *fp;char str[N];if((fp=fopen("demo.txt","a"))==NULL){exit(0);}gets(str);fputs(str,fp);fclose(fp);

按格式读写文件

int fscanf(FILE *fp,const char *format,…);
第一个参数是文件指针,第二个参数为格式控制参数,第三个参数为地址参数表列,后两个参数与scanf()相同.从文件读数据。
int fprintf(FILE *fp,const char *format,…);

//向文件写入数据
#include
#include
#define N 30
typedef struct date
{int year;int month;int day;
}DATE;
typedef struct student
{long studentID;char studentName[10];char studentSex;DATE birthday;int score[4];float aver;
}STUDENT;
void InputScore(STUDENT stu[],int n,int m)
{int i,j;for(i=0;i

按数据块读写文件
unsigned int fread(void *buffer,unsigned int size,unsigned int count,FILE *fp);
//从fp中读取数据块到buffer指向的内存中,size是每个数据块的大小,count最多允许数据块读取的个数
unsigned int fwrite(const void *buffer,unsigned int size,unsigned int count,FILE *fp);
//将buffer指向内存中的数据块写入fp指向的文件中。函数的返回值也就是实际写入的数据块个数
 

void WritetoFile(STUDENT stu[],int n,int m)
{FILE *fp;int i,j;if((fp=fopen(“score.txt”,“w”))==NULL){exit(0);}fwrite(stu,sizeof(STUDENT),n,fp);fclose(fp);
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部