函数指针可以作为形式参数使用,会作为实际参数使用的函数叫回调函数

/*
* 回调函数演示
* */
#include <stdio.h>
void print_cb(int *p_num) {
printf("%d ", *p_num);
}
void neg_cb(int *p_num) {
*p_num = 0 - *p_num;
}
void for_each(int *p_num, int size, void (*p_func)(int *)) {
int num = 0;
for (num = 0;num <= size - 1;num++) {
p_func(p_num + num);
}
}
void print(int *p_num, int size) {
int num = 0;
for (num = 0;num <= size - 1;num++) {
printf("%d ", *(p_num + num));
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
print(arr, 5);
printf("\n");
for_each(arr, 5, print_cb);
printf("\n");
for_each(arr, 5, neg_cb);
for_each(arr, 5, print_cb);
printf("\n");
return 0;
}

可以在程序运行的时候临时决定需要分配的存储区个数,这种分配存储区的方法叫动态内存分配,为了管理动态分配内存需要使用一组标准函数,为了使用这组标准函数需要包含stdlib.h头文件

malloc函数可以动态分配一组连续的字节,这个函数需要一个整数类型的参数表示希望分配的字节个数.这个函数的返回值表示分配好的第一个字节的地址,如果分配失败则返回值是NULL,函数把返回值记录在无类型指针存储区里,使用前必须首先转换成有类型指针

计算机不会主动回收动态分配存储区,程序不再使用动态分配存储区之后必须主动把这些存储区还给计算机.free函数可以用来把动态分配内存还给计算机(释放内存),一起分配的内存必须一起释放,这个函数需要第一个存储区的地址作为参数,如果用指针作为参数调用free函数则函数结束后指针成为野指针,必须恢复成空指针

调用函数可以使用被调用函数动态分配的存储区

/*
* 动态分配内存演示
* */
#include <stdio.h>
#include <stdlib.h>
int main() {
int num = 0;
int *p_num = (int *)malloc(5 * sizeof(int));
/*if (p_num) {
//使用动态分配存储区
free(p_num);
p_num = NULL;
}*/
if (!p_num) {
return 0;
}
//使用动态分配内存
for (num = 0;num <= 4;num++) {
*(p_num + num) = num;
}
for (num = 4;num >= 0;num--) {
printf("%d ", *(p_num + num));
}
printf("\n");
free(p_num);
p_num = NULL;
return 0;
}

calloc函数也可以动态分配存储区,这个函数可以把动态分配存储区的内容都设置成0,为了使用这个函数也需要包含stdlib.h头文件.这个函数需要两个参数,第一个参数表示希望分配的存储区个数,第二个参数表示单个存储区的大小.这个函数的返回值也是第一个存储区的地址,这个函数也可能失败,如果失败则返回值是NULL

realloc函数可以调整动态分配存储区的个数,尽量少使用这个函数

文件里必须采用二进制方式记录数字,如果文件里的所有二进制数字都对应字符这种文件就叫做文本文件,文本文件以外的文件都叫做二进制文件

C语言里提供了两套操作文件的方法,一套方法只能操作文本文件,另外一套方法可以操作所有文件,第一套方法叫做文本方式,第二套方法叫做二进制方式

文件操作基本步骤
  1.打开文件(fopen)
  2.操作文件(fread/fwrite)
  3.关闭文件(fclose)

fopen函数需要两个参数
  1.要打开文件的路径
  2.打开文件的方式(决定程序里可以对文件做什么操作)

打开方式有如下选择
"r" 只能察看文件内容不能修改,只能从文件头开始察看,如果文件不存在打开会失败
"r+" 比"r"多了修改文件内容的功能
"w" 只能修改文件内容不能察看,只能从文件头开始修改,如果文件还不存在就创建文件,如果文件已经存在就删除文件的所有内容,"w+" 比"w"多了察看文件内容的功能,"a" 只能修改不能察看,修改方式是在文件末尾追加新内容,如果文件不存在就创建文件,如果文件存在不会改变文件原有内容,"a+" 比"a"多了察看功能

/*
* 文件操作代码框架
* */
#include <stdio.h>
int main() {
FILE *p_file = fopen("a.txt", "w");
/*if (p_file) {
//操作文件
fclose(p_file);
p_file = NULL;
}*/
if (!p_file) {
return 0;
}
//操作文件
fclose(p_file);
p_file = NULL;
return 0;
}

"b"也是一种打开方式,这种打开方式可以和上面的任何一种方式混合使用,如果程序中希望以二进制方式操作文件就应该在打开方式里加上"b"

文件操作主要有两种方式
  1.把内存里一组连续存储区的内容拷贝到文件里(写文件操作)
  2.把文件里一组连续存储区的内容拷贝到内存里(读文件操作)

fread函数以二进制方式对文件进行读操作
fwrite函数以二进制方式对文件进行写操作

/*
* fread函数演示
* */
#include <stdio.h>
int main() {
int arr[5] = {0}, size = 0, num = 0;
FILE *p_file = fopen("a.bin", "rb");
if (p_file) {
size = fread(arr, sizeof(int), 5, p_file);
printf("size是%d\n", size);
for (num = 0;num <= 4;num++) {
printf("%d ", arr[num]);
}
printf("\n");
fclose(p_file);
p_file = NULL;
}
return 0;
}
/*
* fwrite函数演示
* */
#include <stdio.h>
int main() {
int arr[] = {1, 2, 3, 4, 5}, size = 0;
FILE *p_file = fopen("a.bin", "wb");
if (p_file) {
size = fwrite(arr, sizeof(int), 5, p_file);
printf("size是%d\n", size);
fclose(p_file);
p_file = NULL;
}
return 0;
}

这两个函数都需要四个参数
  1.内存里第一个存储区的地址
  2.内存里单个存储区的大小
  3.希望操作的存储区个数
  4.文件指针

/*
* 文件操作练习
* */
#include <stdio.h>
int main() {
int arr[5][5] = {0}, num = 0;
int row = 0, col = 0;
FILE *p_file = fopen("b.bin", "rb");
if (p_file) {
for (num = 4;num >= 0;num--) {
fread(arr[num], sizeof(int), 5, p_file);
}
fclose(p_file);
p_file = NULL;
}
for (row = 0;row <= 4;row++) {
for (col = 0;col <= 4;col++) {
printf("%d", arr[row][col]);
}
printf("\n");
}
return 0;
}

它们的返回值表示实际操作的存储区个数

以下两个函数以文本方式操作文件

fprintf函数可以把数据按照指定的格式记录到文本文件里
fprintf函数的第一个参数是一个文件指针,后面的参数就是printf函数的参数

/*
* fprintf函数演示
* */
#include <stdio.h>
int main() {
int arr[] = {4, 23, 987, 42, 18}, num = 0;
FILE *p_file = fopen("abc.txt", "w");
if (p_file) {
for (num = 0;num <= 4;num++) {
//printf("%d ", arr[num]);
fprintf(p_file, "%d ", arr[num]);
}
fclose(p_file);
p_file = NULL;
}
return 0;
}

fscanf函数可以从文本文件里获得数字并记录到存储区里,这个函数的第一个参数是文件指针,后面的参数就是scanf函数的参数

/*
* fscanf函数演示
* */
#include <stdio.h>
int main() {
int num = 0, val = 0;
FILE *p_file = fopen("abc.txt", "r");
if (p_file) {
for (num = 0;num <= 4;num++) {
//scanf("%d", &val);
fscanf(p_file, "%d", &val);
printf("%d ", val);
}
printf("\n");
fclose(p_file);
p_file = NULL;
}
return 0;
}

这两个函数执行速度比较慢,不适合用来操作大量数据

计算机里为每个文件保留了一个整数,这个整数表示下一次文件读写的开始位置,这个位置一定在两个相邻字节之间,这个整数就是文件头到这个位置之间包含的字节个数,这个整数叫做文件的位置指针,每当从文件中得到n个字节或向文件里写入n个字节后位置指针的数值都会加n

ftell函数可以获得当前位置指针的数值

rewind函数可以把位置指针的数值设置成0

/*
* 位置指针演示
* */
#include <stdio.h>
int main() {
char ch = 0;
FILE *p_file = fopen("def.txt", "rb");
if (p_file) {
//rewind(p_file);
fseek(p_file, 2, SEEK_SET);
printf("%ld\n", ftell(p_file));
fread(&ch, sizeof(char), 1, p_file);
printf("%c\n", ch);
//rewind(p_file);
fseek(p_file, 7, SEEK_CUR);
printf("%ld\n", ftell(p_file));
fread(&ch, sizeof(char), 1, p_file);
printf("%c\n", ch);
//rewind(p_file);
fseek(p_file, -3, SEEK_END);
printf("%ld\n", ftell(p_file));
fread(&ch, sizeof(char), 1, p_file);
printf("%c\n", ch);
fclose(p_file);
p_file = NULL;
}
return 0;
}

fseek函数可以把位置指针设置到文件里的任何位置
fseek函数里需要设置基准位置并且指定目标位置到基准位置之间的距离

/*
* 文件练习
* */
#include <stdio.h>
typedef struct {
int id;
float salary;
char name[10];
} person;
int main() {
int id = 0, size = 0;
FILE *p_file = fopen("person.bin", "rb");
if (p_file) {
while (1) {
size = fread(&id, sizeof(int), 1, p_file);
if (!size) {
break;
}
printf("id是%d\n", id);
fseek(p_file, sizeof(person) - sizeof(int), SEEK_CUR);
}
fclose(p_file);
p_file = NULL;
}
return 0;
}

SEEK_SET 0 把文件头作为基准位置
SEEK_CUR 1 把当前位置作为基准位置
SEEK_END 2 把文件尾作为基准位置

如果基准位置在目标位置前面则距离用正数表示,如果基准位置在目标位置后则距离用负数表示

距离的绝对值就是基准位置和目标位置之间包含的字节个数

cp命令可以实现文件拷贝功能,命令使用方法如下
cp 路径一 路径二

cp命令里使用-R选项可以实现目录的拷贝

fopen函数的返回值必须记录在文件指针里,程序里只能使用文件指针代表文件,fopen函数有可能失败,如果失败返回值是NULL

完成对文件的所有操作之后必须使用fclose函数关闭文件.使用fclose函数的时候应该把文件指针作为参数,关闭文件之后文件指针会成为野指针,必须恢复成空指针

标准C语言(13)的更多相关文章

  1. 关于标准C语言的预定义宏【转】

    标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义.下面预定义宏表,被我抄了下来. __LINE__  当 ...

  2. 【部分原创】标准C语言的优先级、结合性、求值顺序、未定义行为和非确定行为浅析

    零. 优先级    在C++ Primer一书中,对于运算符的优先级是这样描述的:     Precedence specifies how the operands are grouped. It ...

  3. 标准SQL语言的用法

    原文链接:http://www.ifyao.com/2015/05/18/%E6%A0%87%E5%87%86%E7%9A%84sql%E8%AF%AD%E8%A8%80%E4%BD%BF%E7%94 ...

  4. 关于标准C语言的预定义宏

    标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义.下面预定义宏表,被我抄了下来.__LINE__  当前 ...

  5. UML标准建模语言与应用实例

    一.基本信息 标题:UML标准建模语言与应用实例 时间:2012 出版源:科技创新导报 领域分类:UML标准建模语言 面向对象 系统分析与设计 二.研究背景 问题定义:UML建模语言用图形来表现典型的 ...

  6. UML(统一建模语言)是通用的可视化标准建模语言。由构造块、公共机制、构架三部分组成。

    UML UML(统一建模语言)是通用的可视化标准建模语言.由构造块.公共机制.构架三部分组成. 1.构造块:包括基本的UML建模元素(类.接口.用例等).关系(关联关系.依赖关系.泛化关系.实现关系) ...

  7. 标准C 语言总结

    ***************C语言****************** --day01-- Linux是一个和Windows类似的操作系统 通常通过终端软件使用Linux操作系统 终端软件里只能使用 ...

  8. 标准C语言(1)

    C语言程序的绝大部分内容应该记录在以.c作为扩展名的文件里,这种文件叫源文件,C语言里还包含以.h作为扩展名的文件,这种文件叫做头文件 C语言程序里可以直接使用数字和加减乘除四则运算符号(*代表乘法, ...

  9. 【M35】让自己习惯于标准C++语言

    1.最近一些年C++语言增加的特性有: a.RTTI,namespace,bool,关键字mutable和explicit,enums,以及const static int可以直接初始化. b.扩充了 ...

随机推荐

  1. 浅谈微信小程序生命周期

    之前在做微信小程序的时候,一直对生命周期里面的onLoad,onShow,onUnload不是很理解.比如说什么时候会触发onUnload. 经过一段时间的测试发现,普通页面的onUnload在三种情 ...

  2. 前端vscode常用插件

    Auto Rename Tag 这是一个html标签的插件,可以让你修改一边标签,另外一边自动改变. Beautify 格式化代码插件 Braket Pair Colorizer 给js文件中的每一个 ...

  3. 微信小程序省市区联动,自定义地区字典

    最近在做一个项目的时候遇到了这么一个问题,就是省市区的联动呢,我们需要自定义字典来设置,那么微信小程序自带的省市区选择就不能用了,经过三根烟的催化,终于写出来了.下面献上代码示例. 首先是在utils ...

  4. 【HANA系列】SAP HANA查看某一用户最后登录时间及无效连接次数

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA查看某一用户最后 ...

  5. @Validated和@Valid校验参数、级联属性、List

    @Validated和@Valid的区别 在Controller中校验方法参数时,使用@Valid和@Validated并无特殊差异(若不需要分组校验的话): @Valid:标准JSR-303规范的标 ...

  6. python 连接SQL SERVER 并读取其数据

    1.没什么难的操作 安装  pip install pymssql import pymssql #引入pymssql模块 import pandas as pd def conn(): connec ...

  7. 【机器学习】Learning to Rank入门小结 + 漫谈

    Learning to Rank入门小结 + 漫谈 Learning to Rank入门小结 Table of Contents 1 前言 2 LTR流程 3 训练数据的获取4 特征抽取 3.1 人工 ...

  8. 【linux杂谈】centos6和centos7中固定IP的方法

    众所周知,一大部分集合部署的应用服务器内网相互通信都是采用固定IP.在阿里云.腾讯云上申请的云服务器也是固定IP,这就意味着在云平台内部策略划拨肯定是也固定了IP(即便不是采取直接在系统内固定的方式) ...

  9. 浏览器渲染优化4(styles and layout)

    你已经学会了查找和解决问题.希望你的js能正常运行了,但这只是制作帧的一小部分.在这节课里,你将处理样式,也就是像开发工具里标记的那样,重新计算样式.学完这节课后,你将学会从样式计算过程中找到性能问题 ...

  10. 开启httpfs

    参考: https://docs.cloudera.com/documentation/enterprise/6/6.2/topics/admin_httpfs.html#xd_583c10bfdbd ...