C //练习 8-2 用字段代替显式的按位操作,重写fopen和_fillbuf函数。比较相应代码的长度和执行速度。

C程序设计语言 (第二版) 练习 8-2

练习 8-2 用字段代替显式的按位操作,重写fopen和_fillbuf函数。比较相应代码的长度和执行速度。

注意:代码在win32控制台运行,在不同的IDE环境下,有部分可能需要变更。
IDE工具:Visual Studio 2010

 

代码块:
#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>#ifdef NULL
#undef NULL
#endif#define NULL 0
#define EOF (-1)
#define BUFSIZ 1024
#define OPEN_MAX 20
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2typedef struct _iobuf{int cnt; char *ptr; char *base; int flag; int fd;
}FILE;extern FILE _iob[OPEN_MAX];#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])enum _flags {_READ = 01, _WRITE = 02, _UNBUF = 03,_EOF = 010, _ERR = 020,
};int _fillbuf(FILE *);
int _flushbuf(int, FILE *);#define feof(p)     (((p)->flag & _EOF) != 0)
#define ferror(p)   (((p)->flag & _ERR) != 0)
#define fileno(p)   ((p)->fd)#define getc(p) (--(p)->cnt >= 0 ? (unsigned char) *(p)->ptr++ : _fillbuf(p))#define putc(x, p) (--(p)->cnt >= 0 ? *(p)->ptr++ = (x) : _flushbuf((x), p))#define getchar()   getc(stdin)
#define putchar(x)  putc((x), stdout)#define PERMS 0666FILE *fopen(char *name, char *mode) {int fd;FILE *fp;if (*mode != 'r' && *mode != 'w' && *mode != 'a')return NULL;for (fp = _iob; fp < _iob + OPEN_MAX; fp++)if ((fp->flag & (_READ | _WRITE)) == 0)break; if (fp >= _iob + OPEN_MAX)return NULL;if (*mode == 'w')fd = creat(name, PERMS);else if (*mode == 'a') {if ((fd = open(name, O_WRONLY, 0)) == -1)fd = creat(name, PERMS);lseek(fd, 0L, 2);} elsefd = open(name, O_RDONLY, 0);if (fd == -1)return NULL;fp->fd = fd;fp->cnt = 0;fp->base = NULL;fp->flag = (*mode == 'r') ? _READ : _WRITE;return fp;
}int _fillbuf(FILE *fp) {int bufsize;if ((fp->flag & (_READ | _EOF | _ERR)) != _READ)return EOF;bufsize = (fp->flag & _UNBUF) ? 1: BUFSIZ;if  (fp->base == NULL) if ((fp->base = (char *) malloc(bufsize)) == NULL)return EOF; fp->ptr = fp->base;fp->cnt = read(fp->fd, fp->ptr, bufsize);if (--fp->cnt < 0) {if (fp->cnt == -1)fp->flag |= _EOF;elsefp->flag |= _ERR;fp->cnt = 0;return EOF;}return (unsigned char) *fp->ptr++;
}int _flushbuf(int c, FILE *f) {int num_written, bufsize;unsigned char uc = c;if ((f->flag & (_WRITE | _EOF | _ERR)) != _WRITE) {return EOF;}if (f->base == NULL && ((f->flag & _UNBUF) == 0)) {if ((f->base = (char*)malloc(BUFSIZ)) == NULL)f->flag |= _UNBUF;else {f->ptr = f->base;f->cnt = BUFSIZ - 1;}}if(f->flag & _UNBUF){f->ptr = f->base = NULL;f->cnt = 0;if (c == EOF) {return EOF;}num_written = write(f->fd, &uc, 1);bufsize = 1;}else{bufsize = (int)(f->ptr - f->base);num_written = write(f->fd, f->base, bufsize);f->ptr = f->base;f->cnt = BUFSIZ - 1;}if (num_written == bufsize)return c;else {f->flag |= _ERR;return EOF;}
}FILE _iob[OPEN_MAX] = {{ 0, (char *) 0, (char *) 0, _READ, 0 },{ 0, (char *) 0, (char *) 0, _WRITE, 1 },{ 0, (char *) 0, (char *) 0, _WRITE | _UNBUF, 2 }
};int flushbuf(int c, FILE *f) {int num_written, bufsize;unsigned char uc = c;if ((f->flag & (_WRITE|_EOF|_ERR)) != _WRITE)return EOF;if (f->base == NULL && ((f->flag & _UNBUF) == 0)) {if ((f->base = (char*)malloc(BUFSIZ)) == NULL)f->flag |= _UNBUF;else {f->ptr = f->base;f->cnt = BUFSIZ - 1;}}if (f->flag & _UNBUF) {f->ptr = f->base = NULL;f->cnt = 0;if (c == EOF)return EOF;num_written = write(f->fd, &uc, 1);bufsize = 1;}else{if (c != EOF)*f->ptr++ = uc;bufsize = (int)(f->ptr - f->base);num_written = write(f->fd, f->base, bufsize);f->ptr = f->base;f->cnt = BUFSIZ - 1;}if(num_written == bufsize)return c;else{f->flag |= _ERR;return EOF;}
}int fflush(FILE *f) {int retval;int i;retval = 0;if (f == NULL) {for (i = 0; i < OPEN_MAX; i++) {if ((_iob[i].flag & _WRITE) && (fflush(&_iob[i]) == -1))retval = -1;}} else {if ((f->flag & _WRITE) == 0)return -1;_flushbuf(EOF, f);if (f->flag & _ERR)retval = -1;}return retval;
}int fclose(FILE *f) {int fd;if (f == NULL)return -1;fd = f->fd;fflush(f);f->cnt = 0;f->ptr = NULL;if (f->base != NULL)free(f->base);f->base = NULL;f->flag = 0;f->fd = -1;return close(fd);
}int fseek(FILE *f, long offset, int whence) {int result;if ((f->flag & _UNBUF) == 0 && f->base != NULL) {if (f->flag & _WRITE) {if (fflush(f))return EOF;} else if (f->flag & _READ) {if (whence == SEEK_CUR) {if (offset >= 0 && offset <= f->cnt) {f->cnt -= offset;f->ptr += offset;f->flag &= ~_EOF;return 0;} elseoffset -= f->cnt;}f->cnt = 0;f->ptr = f->base;}}result = (lseek(f->fd, offset, whence) < 0);if (result == 0)f->flag &= ~_EOF;return result;
}int main(){int c;while((c = getchar()) != 'x'){putchar(c);}system("pause");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/632495.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

easydarwin 下面easywasmplayer和easyplayer

拷贝大佬们&#xff0c;起码验证能用再写文章&#xff0c;找到的各种坑 easydarwin/easywasmplayer - npm 区别 easyplayer&#xff1a;在与vue2结合的时候没有问题&#xff0c;但是用在vue3中&#xff0c;就是提示各种缺东西&#xff0c;你就是将所有文件引入到index.html都…

github clone Failed to connect to github.com port 443 after xxx ms

最近克隆github项目时老是报超时&#xff0c;可以尝试以下解决方法 如果本地开启了代理还是clone超时&#xff0c;可以尝试最后一种方式解决 1、把 https 换成 http&#xff0c;如&#xff1a; git clone http:xxx2、更新本地hosts配置&#xff0c;可以参考这篇文章获取最新的…

vue基于spring boot框架的发艺美发店理发店管理系统的设计q9xpe

店铺信息、美发信息是发艺美发店管理系统的重要组成部分&#xff0c;信息清晰、详细、准确&#xff0c;能够有效地促进发艺美发店管理系统的运行[5]。基础设定函数是对整个系统的总体布局进行合理安排&#xff0c;包括&#xff1a;店铺活动、物品信息、领用信息等。通过对各类资…

【C++】vector模拟实现过程中值得注意的点

Hello大家好&#xff01;我是咕噜的铁蛋&#xff01;C中的vector是一种动态数组&#xff0c;它能够根据需要自动增长和缩小。虽然C标准库已经为我们提供了vector的实现&#xff0c;但在某些情况下&#xff0c;我们可能需要自己模拟实现一个类似于vector的数据结构。今天铁蛋将给…

CPU密集型计算、IO密集型计算、多进程、多线程

参考链接&#xff1a; 使用多进程multiprocessing模块加速程序的运行_哔哩哔哩_bilibili 什么是CPU密集型计算、IO密集型计算&#xff1a; CPU密集型&#xff1a; CPU密集型也叫计算密集型&#xff0c;是指I/O在很短的时间就可以完成&#xff0c;CPU需要大量的计算和处理&a…

javaweb学习day01(HTML)

一、B/S 软件开发架构简述 1 Java Web 技术体系图 2 B/S 软件开发架构简述 B/S架构 前端 后端 数据库 二、HTML 1 官方文档 地址: https://www.w3school.com.cn/html/index.asp 离线文档: W3School 离线手册(2017.03.11 版).chm 2 网页 3 HTML 介绍 3.1 HTML 是什么…

oop面向对象编程python

1.定义一个圆类&#xff08;Circle&#xff09;,求圆的面积和周长 import mathclass Circle():def __init__(self, R ,name):self.radius Rself.name namedef girth(self):return 2 * self.radius * math.pidef area(self):return self.radius ** 2 * math.pic1 Circle(10,&q…

python 常用功能积累

sql查询 import pymysql import pandas as pduser #用户名 password #密码 dbName #库名 dbHost #ip dbPort 8888 con pymysql.connect(hostdbHost,portdbPort,useruser,passwordpassword,databasedbName,charsetutf8) cursor con.cursor() head ["Id"…

React16源码: React中调度之requestWork的源码实现

requestWork 1 &#xff09;概述 在 scheduleWork 中&#xff0c;找到了创建更新的fiber对应的root节点然后对它进行了一些操作之后&#xff0c;调用了 requestWork&#xff0c;开始请求工作在 requestWork 里面它会做哪些东西呢&#xff1f; 首先我们要把这个root节点加入到调…

Qt所有容器之间的区别,以及如何简单使用?

Qt中常用的容器有 QList、QVector、QMap、QHash、QSet 等,它们都具有不同的特性和适用场景。 1. QList:动态数组,可以动态增加和删除元素,支持随机访问和迭代,适用于不需要频繁插入或删除元素的场景。 ```cpp QList<int> list; list.append(1); list.append(2); fo…

Docker之nacos集群部署

前言 Nacos 是一个开源的注册中心和配置中心&#xff0c;用于实现微服务架构中的服务发现、服务治理和动态配置管理。在 Docker 中使用 Nacos&#xff0c;你可以通过拉取官方提供的 Docker 镜像并运行容器的方式来快速部署 一.Nacos镜像拉取及独立模式 镜像拉取命令详解&…

【自动化测试】看完这篇文章,让你了解到你和大厂的差距到底在哪儿

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

基于STM32F103的病房监控系统的设计

论文题目&#xff1a;基于STM32F103的病房监控系统的设计 摘要&#xff1a; 病房是患者恢复期间的重要环境&#xff0c;对于病房内的环境和设备状态进行监测和管理具有重要意义。本文提出了一种基于STM32F103的病房监控系统的设计方案。该方案利用嵌入式系统和物联网技术&…

sc.pl.umap 画feature plot

今天有时间尝试测试了这个scanpy的feature plot,其实很简单&#xff0c;就是使用 sc.pl.umap(adata,color"gene name"), 但是这个地方就有一个问题&#xff0c;这个画出来的值是原始的基因值还是scale之后的&#xff0c;这个我得搞清楚 首先看使用例子&#xff0c;参…

企业为什么需要选择软件测试外包公司?有哪些查找途径?

软件测试外包公司是专门为软件企业提供软件测试服务的机构。这些公司拥有一支经验丰富、专业化的软件测试团队&#xff0c;能够帮助企业进行软件产品的测试、评估和质量保证。 一、企业为什么需要选择软件测试外包公司?   1.专业的测试团队&#xff1a;外包公司拥有经验丰富…

赤藓糖醇行业研究:预计2029年将达到3.5亿美元

赤藓糖醇是一种四碳糖醇&#xff0c;存在于多种食物中&#xff0c;如葡萄、梨、西瓜等&#xff0c;可由微生物发酵法和化学合成法两种方法制备&#xff0c;目前商业化生产中均采用微生物发酵法。赤藓糖醇由葡萄糖发酵制作而成&#xff0c;上游原料主要包括葡萄糖、玉米淀粉糖和…

C++(13)——string

上篇文章中介绍了中部分函数的用法&#xff0c;本篇文章将继续对其他的函数进行介绍&#xff1a; 1. substr: string substr (size_t pos 0, size_t len npos) const; 函数的两个参数如上述代码所示&#xff0c;此函数的主要作用是根据一个已有的的对象的起始坐标开始&a…

STM32---基本定时器(含源码)小白可入

写在前面&#xff1a;定时器是STM32中一个十分重要的外设&#xff0c;并且在STM32中具有多个定时器。定时器的包括基本定时器、通用定时器以及高级控制定时器&#xff0c;这些定时器相关独立&#xff0c;不共享任何资源。当然&#xff0c;其难易程度也是逐渐增加的&#xff0c;…

如何实现固定公网地址远程访问本地部署的Termux MySQL数据库

文章目录 前言1.安装MariaDB2.安装cpolar内网穿透工具3. 创建安全隧道映射mysql4. 公网远程连接5. 固定远程连接地址 前言 Android作为移动设备&#xff0c;尽管最初并非设计为服务器&#xff0c;但是随着技术的进步我们可以将Android配置为生产力工具&#xff0c;变成一个随身…

conda 虚拟环境相关命令

创建虚拟环境 conda create -n 虚拟环境名 python版本号查看所有的conda虚拟环境 conda env list进入虚拟环境 conda activate 虚拟环境名退出当前虚拟环境&#xff0c;回到base source deactivate删除某个整个conda虚拟环境 conda remove -n 虚拟环境名 --all在conda虚拟…