C语言之文件操作
C语言之文件操作
在本节我们将会讲解有关文件的读写操作;
纲要:
- 一些需要掌握的知识点
- 文件名
- 文件类型
- 数据流
- 文件缓冲区
- 文件指针
- 与文件操作相关的一些函数
- 文件的打开及关闭
- 文件的顺序读写
- 文件的随机读写
- 文件缓存区的刷新
- 一个易被误用的点
- feof()的使用
正文开始:
一.一些需要掌握的知识点
文件有千千万万,但是在我们的程序设计当中,我们谈的文件一般有两种:
1.程序文件
包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。
2.数据文件
文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
而在本节中,我们主要提到的是数据文件。
1.文件名
我们知道,名字都是用来标识和区别事物的,那么文件名也是这样,是区别各个文件的标识。
一个文件名要包含 3 个部分:文件路径+文件名主干+文件后缀
如:C:\Windows\System32\drivers\etc.txt
其中 :C:\Windows\System32\drivers\ 是文件路径,etc 是文件名主干,txt 是文件名后缀。
当然了,各个平台的文件路径并不相同,以及为了方便起见文件标识通常别称为文件名
2.文件类型
根据数据的组织形式,数据文件被称为文本文件或者二进制文件。
二进制文件:数据在内存中以二进制的形式存储,并不加转换的输出到外存。
文本文件:要求在外存上以ASCII码的形式存储,需要在存储前转换,以ASCII字符的形式存储的文件。
那么一个数据在内存中是怎样存储的呢?
字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。
如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节)
而二进制形式输出,则在磁盘上只占4个字节(VS2019测试)。
如:
我们可以测试一番:
#include <stdio.h>
int main()
{
int a = 10000;
FILE* pf = fopen("test.txt", "wb");
fwrite(&a, 4, 1, pf);//二进制的形式写到文件中
fclose(pf);
pf = NULL;
return 0;
}
我们打开的时候要注意以二进制编辑器来打开,你会发现出现了如下图显示的一串数字,其中它们是以十六进制现实的,转换一下,刚好是上图显示的那串二进制数字(注意VS采用的是小端储存模式)
3.数据流
数据流:
指程序于数据的交互是以流的形式进行的,包括输入流与输出流;
输入流:
程序从输入流读取数据源。数据源包括键盘,文件,网络等,即:将数据源读入到程序的外界通道。
输出流:
程序向输出流写入数据。将程序中的数据输出到外界(显示器,打印机,文件,网络,等)的通信通道。
采用数据流的目的:使得输入输出独立于设备,不关心数据源来自何方,也不管输出的目的地是何种设备。
4.文件缓冲区
缓冲区:
指在程序运行时,所提供的额外内存,可用来暂时存放做准备执行的数据。它可在创建、访问、删除静态数据上,大大提高运行速度(速度的提高程度有时甚至可高达几十倍),
为我们提供了极大的便捷,节省了大量的时间与精力
文件缓冲区:
ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。
从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),
然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。
如:
无论是输入输出,都先在缓冲区里存着,然后在进行输入输出。
5.文件指针
缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。
这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE。
我们可以来看在VS 2019中FILE的声明:
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// Stream I/O Declarations Required by this Header
//
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#ifndef _FILE_DEFINED
#define _FILE_DEFINED
typedef struct _iobuf
{
void* _Placeholder;
} FILE;
#endif
不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。
如下:我们便创建了一个文件指针
FILE* pf;//文件指针变量
定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。
通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。
比如:
到此,我们的基本概念就结束了,下面进入到函数部分:
二.与文件操作相关的一些函数
1.文件的打开及关闭
文件在使用前,我们肯定要打开文件;在使用结束后,我们需要关闭文件。
1.fopen() --- 文件打开函数
声明:文档
FILE* fopen(const char* filename, const char* mode);
参数:
const char* filename ---- 文件名
const char* mode ---- 文件打开方式
文件打开方式:
那,接下来看一个实例:
/* fopen example */
#include <stdio.h>
int main()
{
FILE* pFile;
pFile = fopen("myfile.txt", "w");//打开一个文件(没有就创建),以写的方式打开
if (pFile != NULL)//如果打开成功
{
fputs("fopen example", pFile);//就往文件里写入 fopen example
fclose(pFile);//关闭文件
}
return 0;
}
2.fclose() --- 文件关闭函数
声明:文档
int fclose(FILE* stream);
参数为要关闭文件的文件指针
示例:
int main()
{
//相对路径
//.. 表示上一级目录
//. 当前目录
//FILE* pf = fopen("../data.txt", "r");//在上一级文件中打开data.txt,如果没有就报错
//绝对路径 C:\Windows\System32\drivers\etc.txt
//./hehe/test.txt
//../../
FILE* pf = fopen("../../data.txt", "r");
if (pf == NULL)
{
printf("打开文件失败\n");
printf("%s\n", strerror(errno));//注意头文件的包含 stding.h errno.h
return 1;//失败返回
}
//打开文件成功
printf("打开文件成功\n");
//读写文件
//... //关闭文件
fclose(pf);
pf = NULL;//及时置NULL return 0;
}
注:
其他的文件打开模式,将在函数讲解的时候一并讲解:
2.文件的顺序读写
1. 字符输入输出函数
fput --- 向指定输出流输出一个字符 声明
int fputc ( int character, FILE * stream );
参数:
int character --- 所输入的字符
FILE * stream --- 指定输出流
fgetc --- 向指定输入流输入一个字符 声明
int fgetc ( FILE * stream );
参数:
FILE * stream --- 指定输入流
示例 1:
//在文件里写入a-z26个字母
int main()
{
//fopen函数如果是以写的形式打开
//如果文件不错在,会创建这个文件
//如果文件存在,会清空文件的内容
//fopen函数如果是以读的形式打开
//文件不存在打开失败 FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return 1;//失败返回
}
//写文件
int i = 0;
for (i = 'a'; i <= 'z'; i++)
{
fputc(i, pf);//在文件里写 --- pf 我们自己定义的文件指针
fputc(i, stdout);//显示在屏幕上 --- stdout --- 标准输出流
} // 从键盘输入 --- stdin --- 标准输入流 //关闭文件
fclose(pf);
pf = NULL; return 0;
}
这里需要注意的就是所指定的输出流:
在C语言所写的程序运行起来时,会默认打开三个流:
1.stdin - 标准输入流 (键盘)
2.stdout - 标准输出流 (屏幕)
3.stderr - 标准错误流(屏幕)
示例 2:
//从刚才写的文件,再把内容读出来
int main()
{
FILE* pf = fopen("data.txt", "r");// r 是以读的形式打开文件,如果没有该文件就报错
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
//打开文件成功,读文件
//int ch = fgetc(pf);
//printf("%c\n", ch);//a
//ch = fgetc(pf);
//printf("%c\n", ch);//b
//ch = fgetc(pf);
//printf("%c\n", ch);//c
//ch = fgetc(pf);
//printf("%c\n", ch);//d
int ch = 0;
while ((ch = fgetc(pf)) != EOF)// pf --- 所指定的输入流
{
printf("%c ", ch);
} //关闭文件
fclose(pf);
pf = NULL;
return 0;
}
这里需要注意一点:
fgetc() 的返回值:我们在这就只说出现错误的信息:
If the position indicator was at the end-of-file, the function returns EOF and sets the eof indicator (feof) of stream.
If some other reading error happens, the function also returns EOF, but sets its error indicator (ferror) instead.
翻译过来就是:
如果文件指针处于文件末端,则函数返回EOF,并设置流的eof指示器(feof)
如果发生其他读数错误,函数也会返回EOF,但会设置错误指示器(ferror)
这里的feof和ferror我们专门会放到最后讲
2.文本行输入输出函数
fputs --- 文本行输出行数声明
int fputs ( const char * str, FILE * stream );
参数:
const char * str --- 将被写入输出流的字符指针
FILE * stream --- 输出流
fgets --- 文本行输入函数 声明
char * fgets ( char * str, int num, FILE * stream );
参数:
char * str --- 所输入信息的存放位置
int num --- 要读内容的大小
FILE * stream --- 输入流
示例 1:
int main()
{
FILE* pf = fopen("data.txt", "a");// a --- 如果没有就该文件就创建,有就在该文件后方继续追加内容
if (pf == NULL) // 而 w 如果存在该文件会覆盖重写
{
printf("%s\n", strerror(errno));
return 1;
}
//写一行数据
fputs("hello\n", pf);//输出到文件中
fputs("hello\n", stdout);//在屏幕上显示
fputs("hello world\n", pf);//输出到文件中
fputs("hello world\n",stdout);//在屏幕上显示 fclose(pf);
pf = NULL;
return 0;
}
示例 2:
int main()
{
char arr[100] = {0};//存放写入的信息
FILE* pf = fopen("data.txt", "r");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
//读一行数据
//fgets(arr, 100, pf);
//printf("%s\n", arr); while (fgets(arr, 10, pf) != NULL)//输出---一次读十个
{
printf("%s", arr);
} //fgets从标准输入流中读取
fgets(arr, 100, stdin);
printf("%s\n", arr); fclose(pf);
pf = NULL;
return 0;
}
注意:
1.在fgets中num的大小数包含 \0 ,在内的,如果所输入的内容大小大于指定的大小,fgets会强行截断加 \0.
2.返回值的处理:
If the end-of-file is encountered while attempting to read a character, the eof indicator is set (feof). If this happens before any characters could be read, the pointer returned is a null pointer
(and the contents of str remain unchanged).
If a read error occurs, the error indicator (ferror) is set and a null pointer is also returned (but the contents pointed by str may have changed).
简单点说:遇到错误和文件结尾都会返回NULL,但会设置不同的指示器(feof,ferror)(后面会说)
3.格式化输入输出函数
fprintf --- 格式化输出函数 声明
int fprintf ( FILE * stream, const char * format, ... );
fscanf --- 格式化输入函数 声明
int fscanf ( FILE * stream, const char * format, ... );
别看他们俩长得花里胡哨的,但是使用却和我们的printf,scanf大致相同,只是多出了一个 流 的填写
我们来看看 printf 和 scanf的声明:
int scanf ( const char * format, ... );
int printf ( const char * format, ... );
所以我们来看一个示例:
示例 1:
struct Stu
{
char name[20];
int age;
float score;
}; int main()
{
struct Stu s = {"zhangsan", 20, 66.5f}; FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return 1;
} //格式化的写入
fprintf(pf,"%s %d %f", s.name, s.age, s.score); //printf("%s %d %f", s.name, s.age, s.score);//对比一下只是差了一个 流 的指定
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
int main()
{
struct Stu s = {0}; FILE* pf = fopen("data.txt", "r");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return 1;
} //格式化的读取
fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));//从文件中读取
fprintf(stdout, "%s %d %f\n", s.name, s.age, s.score);//输出到屏幕上 //scanf("%s %d %f", s.name, &(s.age), &(s.score));
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
注意:
读取错误或结束时,fscanf 的返回值也是EOF,判断同 fgetc
这里其实还有一组与它俩相似的函数 --- sprintf以及sscanf (点击函数名看文档)
它俩是干什么的呢,一个是把结构化的数据转换为字符串,一个是把字符串转化为结构化的数据
同样,我们来看看声明:
int sprintf ( char * str, const char * format, ... );
char * str --- 我们要把格式化生成的字符串所存放的地址
int sscanf ( const char * s, const char * format, ...);
const char * s --- 我们所要读取的字符串
示例:
struct Stu
{
char name[20];
int age;
float score;
}; int main()
{
struct Stu s = {"zhangsan", 20, 66.5f};
char buf[200] = { 0 }; //sprintf可以把结构化的数据转换为一个字符串
sprintf(buf, "%s %d %f", s.name, s.age, s.score); printf("按照字符串的形式:%s\n", buf); struct Stu tmp = { 0 }; //sscanf可以把一个字符串转换为一个结构化的数据
sscanf(buf, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score));
printf("按照格式化的形式:%s %d %f\n", tmp.name, tmp.age, tmp.score); return 0;
}
4.二进制输入输出函数
fwrite --- 二进制写 文档
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
这个函数解释一下就是: 将来自 ptr 指向的数据,一次写size个字节,共写 count 次,输出到 stream 指定的流中
fread --- 二进制读 文档
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
这个函数解释一下就是: 将 stream 指定的流中 读 count 次,一次读 size 个字节,存到 ptr 所指向的内容中
示例:
// data.txt 内容 zhangsan 20 66.500000
int main()
{
struct Stu s = {0};
FILE* pf = fopen("data.txt", "rb");//binary --- 二进制
if (pf == NULL) // rb --- 二进制读
{
printf("%s\n", strerror(errno));
return 1;
}
//读文件-二进制
fread(&s, sizeof(struct Stu), 1, pf);
printf("%s %d %f\n", s.name, s.age, s.score); fclose(pf);
pf = NULL;
return 0;
}
注:
若读取时发现读取的内容的个数比指定的最大个数小时,就结束,然后判断是读到文件末尾,还是读取失败
示例 2:
int main()
{
int a = 10000;
FILE*pf = fopen("bin.dat", "wb");//二进制写
if (pf == NULL)
{
return 1;
} fwrite(&a, sizeof(int), 1, pf);
fclose(pf);
pf = NULL; return 0;
}
3.文件的随机读写
1.seek --- 根据文件指针的位置和偏移量来定位文件指针。
int fseek ( FILE * stream, long int offset, int origin );
FILE * stream --- 流
long int offset --- 偏移量
int origin --- 从哪里开始,有三个选择
1.SEEK_SET --- 从文件头开始
2.SEEK_CUR --- 从当前位置开始
3.SEEk_END --- 从文件末尾开始
示例:
//此时文件内容为:123456789
int main()
{
FILE* fp = fopen("data.txt", "r");
if (fp == NULL)
{
perror("\n");
exit(1);
} char a = fgetc(fp);
printf("%c ", a);//此时结果为 1,现在指针指向 2 a = fgetc(fp);//此时读取2,指针指向 3
printf("%c ", a); fseek(fp, -1, SEEK_END);//将文件指针置于文章末尾 a = fgetc(fp);//此时读取9,指针再次指向末尾
printf("%c ", a); fseek(fp, 1, SEEK_SET);//将文件指针置于文章头 a = fgetc(fp);//此时读取1,指针再次指向2
printf("%c ", a); fclose(fp);
fp = NULL;
return 0;
}
2.ftell --- 返回文件指针相对于起始位置的偏移量
long int ftell ( FILE * stream );
3.rewind --- 让文件指针的位置回到文件的起始位置
void rewind ( FILE * stream );
示例:
int main()
{
FILE*pf = fopen("data.txt", "r");
if (pf == NULL)
{
return 1;
}
//读取
int ch = fgetc(pf);
printf("%c\n", ch); ch = fgetc(pf);
printf("%c\n", ch); //定位文件指针到文件的起始位置
//fseek(pf, -2,SEEK_CUR);
//fseek(pf, 0, SEEK_SET);
//printf("%d\n", ftell(pf)); rewind(pf); ch = fgetc(pf);//要在这里读取'a'
printf("%c\n", ch); fclose(pf);
pf = NULL;
return 0;
}
4.文件缓存区的刷新
我们曾在上文提到文件缓冲区的概念:
缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。
从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。
如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。
缓冲区的大小根据C编译系统决定的。
所以,当我们在程序中命令计算机往文件中写一些东西的时候,如果我们想在输出语句已结束,文件就有内容(即需要写的内容从文件缓冲区写到了文件中),
此时,我们不妨 fflush 一下
fflush --- 刷新文件缓存区
int fflush ( FILE * stream );
参数就是我们所定义的文件指针。
示例:
#include <stdio.h>
#include <windows.h>
//VS2019 WIN10环境测试
int main()
{
FILE* pf = fopen("test.txt", "w");
fputs("abcdef", pf);//先将代码放在输出缓冲区
printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
Sleep(10000);
printf("刷新缓冲区\n");
fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
//注:fflush 在一些编译器上并不能使用
printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
Sleep(10000);
fclose(pf);
//注:fclose在关闭文件的时候,也会刷新缓冲区
pf = NULL; return 0;
}
三.一个易被误用的点
feof的错误使用
在刚才的讲解中,我们已经都说过了各输入函数遇到错误时的返回值,所以我们在写文件循环读取的循环条件时,一定要注意各函数的返回值的区别 !
在不满足循环条件后 判断是发生错误跳出,还是读到文本末尾结束(这就是前面所说到的指示器 feof --- 文本结束, ferror --- 遇到错误)
如图:
示例:
int main()
{
FILE*pf = fopen("data.txt", "r");
if (pf == NULL)
{
return 1;
}
//读取
int ch = 0;
while ((ch = fgetc(pf)) != EOF)
{
printf("%c ", ch);
}
//找结束的原因
if (ferror(pf))
{
printf("读取是发生错误,失败,而结束\n");
}
else if (feof(pf))
{
printf("遇到文件末尾,而结束的\n");
} fclose(pf);
pf = NULL;
return 0;
}
所以,我们在日常使用的时候要注意这个点!
|------------------------------------------------------------------
到此,对于文件管理的讲解便结束了!
因笔者水平有限,若有错误,还望指正!
C语言之文件操作的更多相关文章
- C语言程序设计--文件操作
前言 这里尝试与Python对别的方法来学习C语言的文件操作,毕竟我是Pythoner. 文件打开与关闭 Python #因为是和C语言比对,所以不使用with filename = "/e ...
- C语言之文件操作08——总结
C程序的文件操作共涵盖7个例题,包括格式打印,文件读取,条件查找,矩阵的文件操作,数据格式输入及调用计算等内容. 文件操作使得程序有更强的拓展性,使其能够单独保存数据.这为程序的调试和优化打下了坚实的 ...
- c语言_文件操作_FILE结构体解释_涉及对操作系统文件FCB操作的解释_
1. 文件和流的关系 C将每个文件简单地作为顺序字节流(如下图).每个文件用文件结束符结束,或者在特定字节数的地方结束,这个特定的字节数可以存储在系统维护的管理数据结构中.当打开文件时,就建立了和文件 ...
- c语言,文件操作总结
C语言文件操作 一.标准文件的读写 1.文件的打开 fopen() 文件的打开操作表示将给用户指定的文件在内存分配一个FILE结构区,并将该结构的指针返回给用户程序,以后用户程序就可用此FILE指针来 ...
- C语言的文件操作
在操作系统中,为了统一对各种硬件的操作,简化接口,不同的硬件设备也被看成一个文件.对于这些文件的操作,等于是对普通文件的操作.例如,通常把显示器称为标准输出文件,printf就是想这个文件输出,把键盘 ...
- C#语言-07.文件操作
a. 文件操作:适用于相对简单的数据保存 i. 读写文件的步骤: . 创建文件流 . 创建读写器 . 读写文件 . 关闭读写器 . 关闭文件流 ii. FileStream(文件流),它主要用于读写文 ...
- Linux下C语言的文件操作
代码: #include <stdio.h> #include <string.h> #include <fcntl.h> /*************基本的函数A ...
- 超赞的 Go 语言 INI 文件操作
灵活的数据源 不光光可以从文件读取配置,还支持 []byte 类型的纯数据读取和基于 io.ReadCloser 的流式读取. 多种格式兼容 各种文件种类的广泛支持,包括但不限于 my.cnf..gi ...
- C语言中文件操作
用两个指针变量来操作字符串. 多维数组在做函数参数的时候,会退化成为一个指针变量,变成一个指向一维数组的数组指针,注意,是一个指针变量. 一维数组在当作函数参数传递的时候,会退化成为一个对应类型的指针 ...
随机推荐
- Self-XSS All In One
Self-XSS All In One Self-XSS(自跨站脚本)攻击 警告! 使用此控制台可能会给攻击者可乘之机,让其利用 Self-XSS(自跨站脚本)攻击来冒充您并窃取您的信息.请勿输入或粘 ...
- Principle for iOS App Animation Design
Principle for iOS App Animation Design Animate Your Ideas, Design Better Apps https://principleforma ...
- how to install MySQL on macOS
how to install MySQL on macOS MySQL Community Server 8.0.21 # version $ mysqladmin --version # 8.0.2 ...
- Vue & mobile UI components
Vue & mobile UI components https://github.com/vuejs/awesome-vue https://awesome-vue.js.org/ http ...
- Vue SSR in Action
Vue SSR in Action https://ssr.vuejs.org/ https://ssr.vuejs.org/api/ https://ssr.vuejs.org/guide/data ...
- Flutter:发布包
[package] 生成包含模块化Dart代码的可共享Flutter项目 [plugin] 生成一个可共享的Flutter项目, 在Dart代码中包含带有API的API, 针对Android的平台特定 ...
- C++算法代码——质因数分解[NOIP2012普及组]
题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=1102 题目描述 已知正整数 n 是两个不同的质数的乘积,试求出较大的那个质数. 输入 ...
- eclipse从接口快速跳转到实现类
1.只跳转到实现类上 按住Ctrl键,把鼠标的光标放在要跳转的接口上面,选择第二个 2.直接跳转大实现的方法上 按住Ctrl键,把鼠标的光标放在要跳转的方法上面,选择第二个 对比可以发现,操作都是一样 ...
- Lambad表达式--Java8新特性
1.概述 Lambda是一个匿名函数,是java8的一个新特性.可以对接口进行非常简洁的实现.但它要求接口中只能有一个抽象方法,原因是lambda只能实现一个方法.另外,需要在接口上添加注解@Func ...
- Java-for循环打印九九乘法表
Java打印九九乘法表 public class forDemo04 { public static void main(String[] args) { //练习3:打印九九乘法表 /* 1*1=1 ...