1.指向指针的指针
#include<stdio.h> int main() { char *a[] = { "hello","world","my","love" }; char **p; //*p表示p为指针变量,char *表示p指向char *类型的变量 p = a; //p = &a[0] printf("%s\n", *p);//输出a[0] return 0; }
2.函数指针
int (*p)(int, int);//定义一个函数指针p,指向的函数有两个int类型的形参,函数返回值为int型。
#include<stdio.h> int main() { void(*p)(int, int); void max(int, int); void min(int, int); int n = 0; scanf_s("%d", &n); if (n == 1) p = max; else p = min; (*p)(3, 4); return 0; } void max(int x, int y) { printf("%d\n", x > y ? x : y); } void min(int x, int y) { printf("%d\n", x < y ? x : y); }
函数指针就是函数的入口地址。
3.结构体
/*方法一*/ struct Student { ... }student1,student2; /*方法二*/ struct Student { ... }; struct Student student1, student2;//struct Student是类型名 /*方法三*/ typedef struct { ... }Student; Student student1, student2; /*方法四*/ struct { ... }student1,student2;
4.文件类型指针
typedef struct { short level; //缓冲区“满”或“空”的程度 unsigned flags; //文件状态标志 char fd; //文件描述符 unsigned char hold; //如缓冲区无内容不读取字符 short bsize; //缓冲区的大小 unsigned char* buffer;//数据缓冲区的位置 unsigned char* curp; //指针当前的指向 unsigned istemp; //临时文件指示器 short token; //用于有效性检查 }FILE;
声明FILE结构体类型的信息包含在头文件“stdio.h”中。在程序中可以直接使用FILE类型名定义变量,每一个FILE类型变量对应一个文件的信息区,在其中存放该文件的有关信息。
FILE *fp;//定义一个指向文件的指针变量fp;
4.文件操作
- fopen(文件名,使用文件方式);
通常将fopen函数的返回值赋给一个指向文件的指针变量。
FILE *fp;
fp = fopen("a1","r");
这样fp就和文件a1相联系了,或者说fp指向了a1文件
//计算机从ASCII文件读入字符时,遇到回车换行符,系统把它转换为一个换行符,在输出时把换行符转换成回车和换行两个字符。在使用二进制文件时,不进行这种转换,在内存中的数据形式与输出到外部文件中的数据形式完全一致,一一对应。
fclose(文件指针);//若函数成功执行返回0,否则返回EOF(即-1)
- fclose(fp);
如果不关闭文件将会丢失数据。因为,在向文件写数据时,是先将数据输出到缓冲区,待缓冲区满后才正式输出给文件。如果当数据未充满缓冲区而程序结束运行,就有可能使缓冲区中的数据丢失。用fclose函数关闭文件,先把缓冲区中的数据输出到磁盘文件,然后才撤销文件信息区。有的编译系统在程序结束前会自动先将缓冲区中的数据写入到文件,从而避免了这个问题,但是应当养成在程序终止之前关闭所有文件的习惯。
- 向文件读写字符
fgetc(fp);//从fp指向的文件中读入一个字符,读成功,带回所读的字符,否则返回EOF
fputc(ch,fp);//把字符ch写到文件指针变量fp指向的文件中,输出成功,返回值就是输出的字符,输出失败,则返回EOF
#include<stdio.h> #include<stdlib.h> int main() { FILE *fp; char ch, filename[30]; printf("请输入所用的文件名:"); scanf("%s", filename); if ((fp = fopen(filename, "w")) == NULL) { printf("无法打开此文件\n"); exit(0); } ch = getchar(); //用来接收输入完文件名后的回车符 printf("请输入一个准备存储到磁盘中的字符串(以#结束):"); ch = getchar(); while (ch != ‘#‘) { fputc(ch, fp); putchar(ch); ch = getchar(); } fclose(fp); putchar(10); //向屏幕输出一个换行符 return 0; }
//将一个文件中的内容复制到另一个文件中#include<stdio.h> #include<stdlib.h> int main() { FILE *fp_in,*fp_out; char ch, filename_in[30],filename_out[30]; printf("请输入读入的文件名:"); scanf("%s", filename_in); if ((fp_in = fopen(filename_in, "r")) == NULL) { printf("无法打开此文件\n"); exit(0); } printf("请输入写出的文件名:"); scanf("%s", filename_out); if ((fp_out = fopen(filename_out, "w")) == NULL) { printf("无法打开此文件\n"); exit(0); } while (!feof(fp_in)) //feof函数的作用是检查是否到文件末尾 { ch = fgetc(fp_in); fputc(ch, fp_out); putchar(ch); } putchar(10); fclose(fp_in); fclose(fp_out); return 0; }
注意:C系统已把fputc和fgetc函数定义为宏名putc和getc
#define putc(ch,fp) fputc(ch,fp)
这是在stdio.h中定义的
- 向文件读写字符串
char* fgets(char* str,int n,FILE* fp);
从fp指向的文件中读取n - 1个字符,在字符串后加‘\0‘,把它们放到字符数组str中。如果在读完n - 1个字符之前遇到换行符‘\n‘或文件结束符EOF,读入即结束,但将所遇到的换行符‘\n‘也作为一个字符读入。若执行fgets函数成功,则返回值为str数组首元素的地址,如果一开始就遇到文件尾或读数据出错,则返回NULL。
int puts(char* str, FILE* fp);
将str所指向的字符串输出到fp指向的文件中。字符串末尾的‘\0‘不输出。若输出成功,函数值为0,失败时,函数值为EOF。
- 用二进制方式向文件读写一组数据
C语言允许用fread函数从文件中读一个数据块,用fwrite函数向文件写一个数据块。在读写时是以二进制形式进行的。在向磁盘写数据时,直接将内存中的一组数据原封不动、不加转换地复制到磁盘文件上,在读入时也是将磁盘文件中若干字节的内容一批读入内存。一般调用形式为:
fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
其中:
buffer:是一个地址。对fread来说,它是用来存放从文件读入的数据的存储区地址。对fwrite来说,是要把此地址开始的存储区中的数据向文件输出(以上指的是起始地址)。
size:要读写的字节数
count:要读写多少个数据项(每个数据项长度为size)
fp:FILE类型文件指针
在打卡文件时指定用二进制文件,这样可以用fread和fwrite函数读写任何类型的信息。