C语言程序设计(下)


八、结构

结构属于派生类型,是用其他数据类型的对象构建的。关键字struct用来引出一个结构类型定义,结构标识符用来对这个结构类型命名。

struct 结构标识符
{
	数据类型 成员1的名字;
	数据类型 成员2的名字;
	...
	数据类型 成员3的名字;
};

在此,只是声明了一种数据类型,定义了数据组织形式,并未声明结构类型的变量,不会分配内存。定义结构变量方式如下:

  1. 先声明结构类型,再定义结构变量。
struct student stu;
  1. 声明结构的同时定义结构变量。
struct student{
	char ID[16];
	char name[16];
	char sex;
	float score;
}stu;

结构变量的初始化:

struct student stu = {"202222","杰哥",‘M’,69};
#include<stdio.h>//结构是一个名字下一组相关变量的集合

struct date
{
    int year;
    int mouth;
    int day;
};
typedef struct student//为已有变量起别名
{
    char ID[16];
    char name[16];
    char sex;
    struct date birthday;//将一个结构而作为另一个结构的成员
    float score;
}STUDENT;

int main(void)
{
    STUDENT stu = {"2020260104","zhangwei",'M',{2001,9,29},98};

    printf("学号:%s\n",stu.ID);
    printf("姓名:%s\n",stu.name);
    printf("性别:%c\n",stu.sex);
    printf("生日:%d年%d月%d日\n",stu.birthday.year,stu.birthday.mouth,stu.birthday.day);//成员选择运算符
    printf("成绩:%4.1f\n",stu.score);
    
    return 0;
}

结构数组与指针

结构指针的声明方式与其他类型的指针变量相同。

#include<stdio.h>

typedef struct student
{
	char ID[16];
	char name[16];
	char sex;
	float score; 
}STUDENT;

int main(void)
{
	STUDENT stu = {"202222","杰哥",'M',69};
	STUDENT *p;//定义结构指针
	
	p = &stu;//结构指针初始化
	printf("\n%s %s %c %.lf",stu.ID,stu.name,stu.sex,stu.score); 
	printf("\n%s %s %c %.lf",(*p).ID,(*p).name,(*p).sex,(*p).score); 
	printf("\n%s %s %c %.lf",p->ID,p->name,p->sex,p->score);
	return 0; 
}

联合与枚举

C语言中允许多个不同变量共享同一内存区的功能称为联合(union)。

#include<stdio.h>//起作用的成员是最后一次被赋值的成员

union share
{
    int a;
    float b;
    double c;
}u;//按变量最长的类型为联合变量分配存储空间,所以为u分配8个字节

int main(void)
{
    u.a = 10;
    u.b = 100.5f;
    u.c = 10000.1;
    printf("a=%d,b=%f,c=%lf\n",u.a,u.b,u.c);
    printf("u size=%d,a size=%d,b size=%d,c size=%d\n",
    sizeof(u),sizeof(u.a),sizeof(u.b),sizeof(u.c));
    return 0;
}

枚举类型(enumerated type)是一种代表整数常量的数据类型。通过关键字enum,可以创建一个新“类型”并指定它的值。枚举类型的语法与结构体的语法相类似。设计枚举类型的目的在于提高程序的可读性。

#include<stdio.h>
#include<time.h>//时间函数头文件

enum weekday {Sun,Mon,Tue,Wed,Thu,Fri,Sat};

int main(void)
{
    time_t rawtime;//定义代表时间的变量;
    struct tm*timeinfo;//定义一个指向tm结构变量的指针;
    enum weekday wday;//定义一个枚举变量

    rawtime = time(NULL);//获取当前的日历时间;(返回从1970年1月1日0点到现在的秒数)
    timeinfo = localtime(&rawtime);//把日历时间值转化为日期类型
    wday = (enum weekday)timeinfo->tm_wday;//获取星期域的值

    switch (wday)
    {
    case Mon:printf("学习编程!\n");break;
    case Wed:printf("继续学习编程!\n");break;
    case Thu:printf("还是学习编程!\n");break;
    case Sat:printf("看编程视频!\n");break;
    default:printf("刷编程题\n");
    }
    return 0;
}

单链表

单链表 https://blog.csdn.net/ASHIYI66/article/details/113467748

九、文件

文件指针

每一个被使用的文件都要在内存中开辟一个区域,用来存放有关信息,包括文件名称、文件状态和文件当前位置。这些信息被保存在一个结构变量中,该结构类型被系统定义为FILE,放在头文件“stdio.h”文件中。有了FILE类型后,可以用它来定义若干个FILE类型的变量,以便存放若干个文件的信息,一般使用文件型指针变量。

FILE *fp;

定义一个文件指针fp,指向该文件对应的结构变量,即可通过文件指针访问该文件。

fp = fopen("f1.txt","w");

文件的打开和关闭

ANSI C规定了标准/输出函数库,用fopen函数来实现打开文件。fopen函数的原型定义在头文件stdio.h中。一般形式为:

FILE *fp; fp=fopen(filename,mode);

fopen函数有两个参数:
filename:一个指向字符的指针
mode:系统规定的字符串,表示文件的操作属性
mode字符串对应的操作模式:
在这里插入图片描述
三个基本模式:
“r”(read)模式总是打开一个已经存在的文件,如果文件不存在则出错。
“w”(write)模式建立一个新文件,如果文件已经存在,那么先删除存在的文件,再建立新文件。
“a”(append)打开一个存在的文件,在文件的尾部追加数据。


三个追加符:
“b”(binary)表示二进制文件。
“t”(或默认)表示文本文件。
“+”表示将模式扩展为可读、可写方式。


文件打开的目的是为了读/写,当文件使用完毕后,应当关闭文件。C语言定义了关闭文件的标准函数fclose。函数原型定义在头文件stdio.h中,其一般形式为:

fclose(文件指针);

正常关闭文件,返回值为0;无法正常关闭文件,返回值为EOF(-1)。

文件读/写操作

字符读/写函数fgetc()和fputc()


字符输出函数fputc()
用法:fputc(ch,fp);
ch:输出的字符;fp:文件指针变量
功能:把一个字符写到磁盘文件上,同时移动读写位置指针到下一个写入位置。如果调用函数成功,则返回ch的值;如果失败,则返回值EOF(系统定义的宏,值为-1);


字符输入函数fgetc()
用法:ch=fgetc(fp);
fp:文件指针变量
功能:从磁盘文件读取一个字符。如果调用成功,则返回读到的字符(赋值给ch);如果读到文件结束,则返回EOF(-1)。


/*字符读/写操作*/
#include<stdio.h>
#include<stdlib.h>

int main(void)
{
	FILE *fp;
	char ch;
	
	if((fp=fopen("f2.txt","w"))==NULL)
	{
		printf("can not open this file\n");
		exit(0);
	}
	
	for(;(ch=getchar())!='@';)
		fputc(ch,fp);
	
	fclose(fp);
	
	if((fp=fopen("f1.txt","r"))==NULL)
	{
		printf("can not open this file\n");
		exit(0);
	}
	
	for(;(ch=fgetc(fp))!=EOF;)
		putchar(ch);
		
	fclose(fp);
	return 0;
 } 

字符串读/写函数fegts()和fputs()


字符串输入函数fgets()
用法:fgets(str,n,fp);
str:字符指针或数组名;n:整型量,说明输入字符串的最大长度(包括‘\0’);fp:文件指针
功能:从文本文件中读取字符,从fp对应文件的当前位置,最多输入n-1个字符,在最后加‘\0’,之后放在str为首地址的内存中。
注意:在输入过程中,如果遇到换行符或EOF,输入即结束。函数正常调用,返回str的首地址,当出错或遇到文件结束标志时,返回NULL。


字符串输出函数fputs()
用法:fputs(str,fp);
str:函数参数str是字符指针或数组名;fp:文件指针
功能:向指定的文本文件写入一个字符串,将首地址是str的字符串输出到fp对应文件的当前位置,自动丢弃str后的‘\0’。函数调用成功后返回值是0,否则是EOF。


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
	FILE *fp;
	char string[81];
	
	
	if((fp=fopen("f2.txt","w"))==NULL)
	{
		printf("can not open this file\n");
		exit(0);
	}
	
	printf("Input a string:");
	gets(string);
	fputs(string,fp);
	fclose(fp);
	
	if((fp=fopen("f2.txt","r"))==NULL)
	{
		printf("can not open this file\n");
		exit(0);
	}
	
	fgets(string,strlen(string)+1,fp);
	printf("Output the string:");
	puts(string);
	fclose(fp);
	return 0;
 } 

文件的格式化读/写函数fscanf()和fprintf()


格式化输入函数fscanf()
用法:fscanf(fp,format,&arg1,&arg2,…,&argn);
fp:文件指针;format:格式说明字符串;&arg1…&argn:输入变量的地址列表。
功能:从fp指向的文件的当前位置,顺序读取ASCII码值,按照fomat规定的格式转化为各个变量对应的值,送入指定变量。

fscanf(fp,"%d%f",&n,&x);

格式化输出函数fprintf()
用法:fprintf(fp,format,arg1,arg2,…,argn);
fp:文件指针;format:格式说明字符串;arg1…argn:输出参数个数表
功能:按指定的格式(format)将输出列表arg1…argn的值转换成对应的ASCII码表示形式,写入fp文件的当前位置。

fprintf(fp,"%d%f",n,x);

文件的数据块读/写函数fread()和fwrite()


数据块输入函数fread()
用法:表示从文件中读入数据到内存缓冲区。形式为:fread(buf,size,count,fp);
buf:类型为void指针,表示内存中存放着数据到首地址,通常是数组名或数组指针。
size:无符号整型,表示一次读取的字节数。
count:无符号整型,表示读取的大小为size的块的次数。
fp:文件指针。
功能:从fp指向的文件的当前位置读区size个字节,共count次,读取的总字节数为size* count,存放到首地址为buf的内存中。读取成功则返回读取的项数count。


数据块输出函数fwrite()
用法:表示从内存输出数据块到文件中。其一般形式为:
fwrite(buf,size,count,fp);
buf:类型为void指针,表示内存中存放着数据到首地址,通常是数组名或数组指针。
size:无符号整型,表示一次写入的字节数。
count:无符号整型,表示写入的大小为size的块的次数。
fp:文件指针。
功能:从fp指向的地址开始,分count次,每次size个字节,向fp指向的文件的当前位置写数据,共写入count*size个字节。写入成功则返回读取的项数count。

fwrite(stuArr,sizeof(stuArr),1,fp)

文件定位函数

除了顺序读/写,C语言还允许对文件进行随机读/写,可以通过定位函数来改变读写指针的位置。

  • 位置指针定位函数fseek()
    fseek函数用来改变文件指针的当前位置。其一般形式为:
    fseek(fp,offset,from);
    offset:位移量,类型为long型,表示以from为起点移动的量相对值(字节数)。如果是正数,表示向文件尾移动,如果负数,表示向文件头移动。
    from:移动的起始位置。文件头、当前位置和文件尾部分别对应0、1、2,或常量SEEK_SET、SEEK_CUR、SEEK_END。
fseek(fp,20L,0);//将文件位置指针移动到离文件首20字节处
fseek(fp,-20L,SEEK_END);//将文件位置指针从文件尾向文件首移动20字节处
  • 位置指针复位函数rewind()
    用来置文件读/写位置于开头处。一般形式为:
    rewind(fp);
    功能:将文件的当前位置移动到文件的开始处。
  • 返回文件当前位置函数ftell()
    用来取文件当前位置。其一般形式为:
    long n;
    n=ftell(fp);
    功能:取得文件当前的读/写位置。(即从文件开始处到当前读/写位置的字节数(用长整型量表示))。函数调用正确返回文件当前读/写位置。调用错误就返回-1L。

文件检测

  • 文件结束检测函数feof()
    用法:feof(fp);
    fp:文件指针变量
    功能:判断文件是否处于文件结束位置。如果文件结束,则返回1,否则返回0。它适用于文本文件而不适用于二进制文件。
  • 检测文件操作错误函数ferror()
    用法:ferror(fp);
    fp:文件指针变量
    功能:检测文件在各种输入输出函数进行读写时是否错误,若返回值为0,表示未出错,否则表示有错。
  • 清除错误标志函数
    用法:clearerr(fp);
    fp:文件指针变量
    功能:清除出错标志和文件结束标志,把它们置为0。
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会思想的苇草i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值