C语言的函数与文件操作

时间:2021-06-17 09:57:01

一 函数

1 函数基础知识

  c语言中使用函数对语句进行分组。所有的c语言程序都是由一个或多个的的函数构成的。所有c语言程序中必须有一个叫做main的函数,这个函数叫做主函数。

  函数之间通过互相调用建立联系,在函数调用过程中主动发起的一方叫调用函数,被动接受的一方叫被调用函数。

  返回值是一个特殊的变量,函数中使用return语句对返回值变量赋值。调用函数中可以把函数调用语句当数字使用,这个数字就来自于函数的返回值变量,返回值变量用来从被调用函数向调用函数传递数据。
  return关键字不单可以给返回值变量赋值,还可以立刻结束函数的执行。标准函数exit(0)可以立即结束整个程序,参数0表示正常结束,使用时需要包含头文件stdlib.h。

  声明在小括号内的变量叫形式参数,形式参数的个数和类型可以任意指定,形式参数用来从调用函数传递数据给被调用函数。
  函数调用语句中提供的数据叫实际参数,实际参数用来对形式参数赋值,形式参数的变化不会影响实际参数,函数调用过程中数据的传递类似传真机,传递完成后同样的数据存在两份。

  数组做形参,函数调用时数组中的变量不会被复制,数组做形参可以在调用函数和被调用函数之间双向传递数据,这种形参叫做输入输出参数。
  数组做形参,需要另外一个形参表示数组中变量的个数。

  gcc在编译时如果先遇到函数调用语句则会对函数格式做出猜测,这叫做函数的隐式声明,隐式声明不可靠,在文件开头把所有函数的声明列出可以避免隐式声明。

2 递归函数

  在执行过程中会重复调用自己的函数叫做递归函数。使用递归函数解决问题的思路叫递归,使用循环解决同样问题的思路叫递推。
  递归函数的编写规则:
    1、必须使用形参编写分支;
    2、必须有一个分支不会递归调用自己;
    3、必须保证上一条中的分支有机会执行。

#include <stdio.h>

int sum(int num) {
if (num == 1) {
return 1;
}
else {
return num + sum(num - 1);
}
}

int main() {
printf("sum(10)是%d\n", sum(10));
return 0;
}
/*
最大公约数
*/

#include <stdio.h>

int yue(int num, int num1) {
if (!(num1 % num)) {
return num;
}
else {
return yue(num1 % num, num);
}
}

int main() {
int num = 0, num1 = 0;
printf("请输入两个数字:");
scanf("%d %d", &num, &num1);
printf("最大公约数是%d\n", yue(num, num1));
return 0;
}

二 C语言文件操作

文件操作函数:
  1、fopen用于打开文件
  2、fclose用于关闭文件
  3、fread/fwrite函数用于对文件进行读写操作

打开模式:
  “r”:只读模式,从文件头开始
  “r+”:读写模式,从文件头开始
  “w”:只写模式,如果文件事先存在,则会删除
  “w+”:读写模式,如果文件存在则删除
  “a”:只写模式,如果文件存在,则追加在末尾
  “b”表示二进制模式,“b”可以和上面的任何模式混用

fopen函数的返回值内容可以当做逻辑表达式使用,如果为true表示打开成功,否则打开失败。
所有文件在程序结束之前都必须使用fclose关闭。

fread/fwrite的参数:
  1、表示一个数组
  2、表示单个数据的大小
  3、表示数据的个数
  4、表示要操作的文件
返回值表示实际要操作的变量个数。

/*
拷贝功能
*/


#include <stdio.h>

int main() {
FILE *p_file = fopen("b.out", "rb");
FILE *p_file1 = NULL;
char buf[20] = {};
int size = 0;
if (p_file) {
p_file1 = fopen("c.out", "wb");
if (p_file1) {
size = fread(buf, sizeof(char), 20, p_file);
while (size) {
fwrite(buf, sizeof(char), size, p_file1);
size = fread(buf, sizeof(char), 20, p_file);
}
fclose(p_file1);
p_file1 = NULL;
}
fclose(p_file);
p_file = NULL;
}
return 0;
}

位置指针表示文件下次操作的位置,可使用一组标准函数对它进行修改。
ftell()函数可以获得当前位置指针相对于文件头的距离。
rewind()函数可以把位置指针移动到文件开头。
fseek()函数可以任意挪动位置指针
  SEEK_SET 1 表示以文件头为基准
  SEEK_CUR 2 表示以当前位置为基准
  SEEK_ END 3 表示以文件尾为基准

#include <stdio.h>

int main() {
int num[] = {1, 2, 3, 4, 5};
int val = 0;
FILE *p_file1 = fopen("a.bin", "wb");
if (p_file1) {
fwrite(num, sizeof(int), 5, p_file1);
printf("距离是%ld\n", ftell(p_file1));
fclose(p_file1);
}

FILE *p_file = fopen("a.bin", "rb");
if (p_file) {
//rewind(p_file);
fread(&val, sizeof(int), 1, p_file);
printf("val是%d\n", val);//1

fseek(p_file, 12, SEEK_SET);
fread(&val, sizeof(int), 1, p_file);
printf("val是%d\n", val);

fseek(p_file, -12, SEEK_CUR);
fread(&val, sizeof(int), 1, p_file);
printf("val是%d\n", val);

fseek(p_file, -8, SEEK_END);
fread(&val, sizeof(int), 1, p_file);
printf("val是%d\n", val);

fclose(p_file);
p_file = NULL;
}
return 0;
}
#include <stdio.h>
#include <stdbool.h>

bool search_id(int id) {
int old_id = 0;
char name[20] = {};
float salary = 0.0f;
bool ret = false;
FILE *p_file = fopen("a.bin", "rb");
if (p_file) {
while (fread(&old_id, sizeof(int), 1, p_file)) {
if (old_id == id) {
fread(name, sizeof(char), 20, p_file);
fread(&salary, sizeof(float), 1, p_file);
printf("id:%d\n", old_id);
printf("name:%s\n", name);
printf("salary:%g\n", salary);
ret = true;
break;
}
fseek(p_file, 24, SEEK_CUR);
}
fclose(p_file);
p_file = NULL;
}
return ret;
}

int main() {
int id = 0;
printf("请输入一个id:");
scanf("%d", &id);
printf(search_id(id) ? "找到了\n" : "没有找到\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>

typedef struct {
int id;
char name[20];
float salary;
} person;

int main() {
FILE *p_file = fopen("a.bin", "rb");
person *p_person = NULL;
int size = 0, pos = 0;
if (!p_file) {
printf("文件打开失败\n");
return 0;
}
//获得文件大小
fseek(p_file, 0, SEEK_END);
size = ftell(p_file);
//从堆中分配变量
p_person = (person *)malloc(size);
if (!p_person) {
printf("内存分配失败\n");
fclose(p_file);
p_file = NULL;
return 0;
}
//读文件内容
fseek(p_file, 0, SEEK_SET);
fread(p_person, sizeof(person), size / sizeof(person), p_file);
//显示人员信息
for (pos = 0;pos <= size / sizeof(person) - 1;pos++) {
printf("id:%d\n", (p_person + pos)->id);
printf("name:%s", (p_person + pos)->name);
printf("salary:%g\n\n", (p_person + pos)->salary);
}
//释放堆中内存
free(p_person);
p_person = NULL;
//关闭文件
fclose(p_file);
p_file = NULL;
return 0;
}