C语言入门基础之输入和输出

标准输入函数

在stdio.h中scanf声明如下:

/* Read formatted input from stdin.This function is a possible cancellation point and therefore notmarked with __THROW. */
extern int scanf (const char *__restrict __format, ...) __wur;

使用Mac或Linux的同学,在终端上输入man scanf回车即可学习scanf函数的用法。我们可以看到注释上说明,scanf从标准输入stdin输入读取数据,在glibc中stdin的定义如下:

/*stdio.c*/
FILE *stdin = (FILE *) &_IO_2_1_stdin_;
/*libio.h*/
extern struct _IO_FILE_plus _IO_2_1_stdin_;
/*libioP.h*/
struct _IO_FILE_plus
{FILE file;const struct _IO_jump_t *vtable;
};

从以上代码我们可以知道,最终stdin是一个FILE文件流指针,我能继续追踪FILE类型为何物。

/** stdio state variables.** The following always hold:** if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),* _lbfsize is -_bf._size, else _lbfsize is 0* if _flags&__SRD, _w is 0* if _flags&__SWR, _r is 0** This ensures that the getc and putc macros (or inline functions) never* try to write or read from a file that is in `read' or `write' mode.* (Moreover, they can, and do, automatically switch from read mode to* write mode, and back, on "r+" and "w+" files.)** _lbfsize is used only to make the inline line-buffered output stream* code as compact as possible.** _ub, _up, and _ur are used when ungetc() pushes back more characters* than fit in the current _bf, or when ungetc() pushes back a character* that does not match the previous one in _bf. When this happens,* _ub._base becomes non-nil (i.e., a stream has ungetc() data iff* _ub._base!=NULL) and _up and _ur save the current values of _p and _r.** NB: see WARNING above before changing the layout of this structure!*/
typedef  struct __sFILE {unsigned char *_p; /* current position in (some) buffer */int  _r; /* read space left for getc() */int  _w; /* write space left for putc() */short  _flags; /* flags, below; this FILE is free if 0 */short  _file; /* fileno, if Unix descriptor, else -1 */struct  __sbuf _bf;  /* the buffer (at least 1 byte, if !NULL) */int  _lbfsize; /* 0 or -_bf._size, for inline putc *//* operations */void  *_cookie; /* cookie passed to io functions */int  (* _Nullable _close)(void *);int  (* _Nullable _read) (void *, char *, int);fpos_t  (* _Nullable _seek) (void *, fpos_t, int);int  (* _Nullable _write)(void *, const char *, int);/* separate buffer for long sequences of ungetc() */struct  __sbuf _ub;  /* ungetc buffer */struct __sFILEX *_extra; /* additions to FILE to not break ABI */int  _ur; /* saved _r when _r is counting ungetc data *//* tricks to meet minimum requirements even when malloc() fails */unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */unsigned char _nbuf[1]; /* guarantee a getc() buffer *//* separate buffer for fgetln() when line crosses buffer boundary */struct  __sbuf _lb;  /* buffer for fgetln() *//* Unix stdio files get aligned to block boundaries on fseek() */int  _blksize; /* stat.st_blksize (may be != _bf._size) */fpos_t  _offset; /* current lseek offset (see WARNING) */
} FILE;

看到这个结构体内部一大堆成员变量不要慌,我们重点关注里面的close、read、seek和write函数指针。我们在调用scanf函数时正是通过这几个函数指针间接调用系统函数close、read、seek和write实现标准输入关闭、读取、偏移和写功能。

int  (* _Nullable _close)(void *);
int  (* _Nullable _read) (void *, char *, int);
fpos_t  (* _Nullable _seek) (void *, fpos_t, int);
int  (* _Nullable _write)(void *, const char *, int);

从函数声明我们知道scanf返回一个int型返回值,在调用时scanf,返回正整数表示从标准输入读取到的有效数据数量,返回0表示没有输入或者输入不正确,返回负数表示发生了从标准输入读取数据发生了错误。下面我们使用scanf从标准输入读取数据的代码。

int num = 0;
float f_num = 0;int count = scanf("%d", &num);
scanf("%f", &f_num);scanf_s("%d", &num);

在scanf中输入数据并将数据保存在变量num和f_num中,调用scanf输入数据必须要用%,%d表示输入一个整数,%f表示输入一个单精度浮点数,count保存scanf输入数据的有效数。

在C语言里函数传参方式有2种,一种是传值另外一种是传指针。通过传值方式形参拷贝实参,得到一个实参副本对实参副本进行修改不会影响实参,而传指针方式,将会得到实参的地址,通过指针解引用可以间接修改实参的值。那么回到scanf函数那里,我们通过对变量进行取址,scanf函数内部有一个指针,将变量地址值赋给内部指针,再将标准输入的值赋值给实参,实参变量因此获得标准输入的值。

标准输出函数

在stdio.h中printf函数声明如下:

/* Write formatted output to stdout.This function is a possible cancellation point and therefore notmarked with __THROW. */
extern int printf (const char *__restrict __format, ...);

看到这里是不是很熟悉?printf函数的返回值也是int型,调用printf函数将会返回输出字符个数,出错则返回一个负数。同样在Linux/Mac平台的终端上输入man printf函数可以查看函数的详细使用方法(任何C标准函数都可以在Linux/Mac平台上输入man+函数名的方式查看函数使用方法)。下面是我们使用printf函数在标准输出中输出数据的代码。

int output_count = printf("num = %d\n", num);
printf("output_count = %d\n", output_count);output_count = printf("f_num = %f\n", f_num);
printf("output_count = %d\n", output_count);

在代码片段里我们看到一个\n字符,在C语言里这是一个换行符。看到这里是不是又有疑问了,为什么printf函数输出变量值时不需要对变量取地址?这就回到前面我们说过的问题了,在C语言里传值,形参是实参的副本,形参修改了不会影响到实参。而printf函数只是在标准输出中输出信息,不会修改实参的值,因此使用传值方式。

那么标准输出是什么呢?从print函数声明代码注释上看,标准输出正是stdou,我们继续在glibc中继续追踪stdout到底是什么?在stdout.c中我们看到stdout和stderr定义如下:

FILE *stdout = (FILE *) &_IO_2_1_stdout_;
FILE *stderr = (FILE *) &_IO_2_1_stderr_;

我们发现stdout、stderr和stdin的定义一模一样都是一个FILE类型指针,那么使用方式就和stdin一样了,区别则在于stdin和文件描述符0绑定,stdout和文件描述符1绑定,stderr和文件描述符2绑定。

声明:

本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

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

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

相关文章

camel java_与Java EE和Camel的轻量级集成

camel javaEnterprise Java具有不同的风格和观点。 从简单的平台技术(众所周知的Java EE)开始,到不同的框架和集成方面,最后是涉及以数据为中心的用户界面或特定可视化效果的用例。 Java EE本身无法解决的最突出的问题是“集成”。…

c语言 伪随机数程序,C语言的伪随机数

一直想好好的系统的学习一下C语言的伪随机数,今天终于逮到机会了伪随机数C语言中有可以产生随机数据的函数,需要添加stdlib.h和time.h头文件。首先在main函数开头加上srand(unsigned)time(NULL))。先来介绍一下srand头文件:定义函数&#xff…

最大隶属度原则_模糊数学笔记:六、模糊模型识别-I(最大隶属度原则)

1、模型识别的问题提出模型识别,通俗地理解即是对一个类别未知的对象进行归类(或者叫分类)。这里与聚类不同的是,聚类实际上是要区分出已有的样本哪些属于同一类,但并没有参考标准。而识别则事先有参考的标准&#xff…

C语言经典题

C 库函数 - tanh()描述C 库函数 double tanh(double x) 返回 x 的双曲正切。声明下面是 tanh() 函数的声明。double tanh(double x)参数x -- 浮点值。返回值该函数返回 x 的双曲正切。实例下面的实例演示了 tanh() 函数的用法。#include#include int main (){ double x, ret;…

用c语言产生大素数,C语言实现寻找大素数

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼找到一亿内所有素数并写入文件用时 35秒.#include "math.h"#include "stdio.h" #include "stdlib.h" #include "time.h"int isP(int num,int *p) { int i; int lenp[0]; int flag1; p;for…

java ee自动生成编码_EE Servlet 3:在Servlet中生成HTML输出

java ee自动生成编码如果您只需要在EE Web模块中处理少量请求URI,那么在Servlet代码中生成自己HTML响应可能比使用完整的模板库更容易。 作为示例的一部分,我尝试了一个非常简单的Java DSL,该Java DSL在编写自己的Serlvet时生成html输出。 代…

jq 控制td只显示一行_CSS让表格里的内容强制显示一行,超出长度显示省略号

在写html页面的时候,会经常用到表格,而且很多时候一个tr里边需要包含好几个td,这样就会导致tr的高度不一致,被撑开了这时候,如果能让td里的内容强制显示在一行,并让超出边界范围的内容显示点点,…

C++11的模板改进

C11关于模板有一些细节的改进:模板的右尖括号模板的别名函数模板的默认模板参数模板的右尖括号C11之前是不允许两个右尖括号出现的,会被认为是右移操作符,所以需要中间加个空格进行分割,避免发生编译错误。int main() {std::vecto…

java面试题2014_Java生态系统– 2014年我的5大亮点

java面试题20141月1日-RedMonk Analyst公司宣布Java比以往任何时候都更加流行和多样化! 2014年,随着FOSDEM的Free Java会议室的年会,Java生态系统开始轰轰烈烈地响起。 除了关于OpenJDK和相关主题的许多精深的技术讲座外,Steve OG…

android 第三方圆弧进度条,android 可配置的圆弧进度条

Arc ProgressBar Configurable 圆弧环形进度条DEMOAttributesnameformatdescriptionborderWidthinteger圆弧边框的宽度progressStyletick/arc进度条类型,tick 为带刻度的radiusinteger半径arcbgColorcolor圆弧的边框背景degreeinteger弧度,设置为 0 即为…

三分钟让孩子的数学开窍

周末给孩子灌了一个世界观和方法论:用笛卡尔坐标系描述世界。 我强调,学习笛卡尔坐标系不是做题,它是工具,它是帮你解题的,而不是为难你的。 任何数学题放在笛卡尔坐标系都可以通过机械的方法硬算,计算过程…

oracle大对象实例_超大型Oracle数据库设计实例

超大型系统的特点为: 1.处理的用户数一般都超过百万,有的还超过千万,数据库的数据量一般超过1TB; 2.系统必须提供实时响应功能,系统需不停机运行,要求系统有很高的可用性及可扩展性。 这篇是笔者针对以上特…

C++定时器的实现之格式修订版

个人认为一个完备的定时器需要有如下功能:在某一时间点执行某一任务在某段时间后执行某一任务重复执行某一任务N次,任务间隔时间T那么如何实现定时器呢?下面是我自己实现的定时器逻辑,源码链接最后会附上。定时器中主要的数据结构…

java 性能调优_Java性能调优调查结果(第四部分)

java 性能调优这是本系列中的最后一篇文章,我们将分析我们在2014年10月进行的Java Performance Tuning Survey的结果。如果您尚未阅读第一篇文章,建议您首先阅读以下内容: 性能问题的频率和严重性 最受欢迎的监控解决方案 查找根本原因的工…

Android接入热敏打印机,Android 关于佳博和汉印蓝牙热敏打印机开发

接上篇文章Android之BLE(低功耗)蓝牙开发,本篇文章针对上篇博文中提出的两款打印机的开发流程进行记录。首先不管时佳博打印机还是汉印打印机,都是先对他们各自的lib进行导入,如图:导入lib之后,一定要记得进行sync pro…

C 桥接模式 - 开关和电器

桥接模式(Bridge Pattern)是将抽象部分与它的实现部分分离,使它们都可以独立地变化。1模式结构UML 结构图:Abstraction(抽象类):用于定义抽象类的接口,并且维护一个指向 Implementor…

centos8配置本地光盘yum源_CentOS8 配置本地yum源的详细教程

centos8发行版通过 baseos 和应用流 (appstream) 仓库发布,appstream 是对传统 rpm 格式的全新扩展,为一个组件同时提供多个主要版本centos8 自带封装了nginx,这篇文章给大家介绍centos8 配置本地yum源,具体内容如下所示&#xff…

javafx显示image_如何摆脱JavaFX中的重点突出显示

javafx显示image今天,有人问我是否知道摆脱JavaFX控件(分别是按钮)的焦点突出的方法: 有关此问题的大多数文章和提示建议添加: .button:focused {-fx-focus-color: transparent; }但是使用这种样式,仍然…

android aop静态方法,spring aop 不能对静态方法进行增强解决

想要通过aop的方式记录HttpUtils发出的post请求日志,但是 aop 不能对静态方法进行增强。只能对实例方法进行增强。。如果一定要增强静态方法,我们可以对目标类使用单例模式,然后通过调用实例方法去调用那个静态方法,而且对应的对象…

汉字笔画动图怎么做_隶书基本笔画教程(动态图)

隶书开创并奠定了汉字的书写形式。而隶书的美时而古朴遒劲,时而秀美温润,实在是令人神往。笔法有方有圆,方圆并用。下面文章以明朗的笔迹演示,结合相对切实的例字,给大家详尽讲解隶书的基本写法。掌握这些基本写法后&a…