0%

主要介绍:

什么是“流”,“流”的基本概念,“流”对于内存和外部设备着什么样的作用,C语言默认打开的三个“流”:stdin、stdout、stderr👀。

通过《C语言》文件这一章的学习,我们学会了如何向文件进行读写操作,也就是如何让数据从内存中保存到硬盘上,或是如何从硬盘上读取数据放到内存中。硬盘其实是一个外部设备,那有人就要问了:我们能否对其他外部设进行读写操作呢?例如:屏幕、键盘、鼠标、U盘、光盘、网络…… ,答案当然是肯定的。

但值得注意

的是,每一种外部设备的读写方式是有所差异的,就比如:写硬盘和写屏幕,读键盘和读网络。那大家想一下,如果一个程序员写代码的时候,必须要把每种外部设备的读和写的方式都理解透彻,是不是太麻烦了!

  所以,为了能够让程序员更加方便的对外部设备进行读写操作,我们会在外部设备前抽象出来一层东西,称为:“流”的概念。这样程序员在写文件的时候就不需要关注外部设备了,只需要将数据写到“流”里面去,然后由C语言底层的封装来进行相应的操作,把“流”里面的数据分发到不同的外部设备当中去。反之亦是如此。 如下图所示。抽象的来说“流”就相当于一个中转站,能够将数据更具不同的外部设备读写的方式来进行相应的操作。 如此这些外部设备的细节就不需要用户来关注,用户只需要关注“流”就可以了(这里的“流”指的是向哪个外部设备进行的操作)。至于“流”是如何做到向不同外部设备读写的,这是在C语言底层就已经实现好的,不需要我们关心。
  所以,为了能够让程序员更加方便的对外部设备进行读写操作,我们会在外部设备前抽象出来一层东西,称为:“”的概念。这样程序员在写文件的时候就不需要关注外部设备了,只需要将数据写到“流”里面去,然后由C语言底层的封装来进行相应的操作,把“流”里面的数据分发到不同的外部设备当中去。反之亦是如此。 如下图所示。抽象的来说“流”就相当于一个中转站,能够将数据更具不同的外部设备读写的方式来进行相应的操作。 如此这些外部设备的细节就不需要用户来关注,用户只需要关注“流”就可以了(这里的“流”指的是向哪个外部设备进行的操作)。至于“流”是如何做到向不同外部设备读写的,这是在C语言底层就已经实现好的,不需要我们关心。
  “流”是一个比较抽象的概念,数据就像水管里的水流,可以从内存中流向外部设备,也可以从外部设备流向内存,但只能单方向的流。由此可见“流”是有明确的方向性的,所以可以将“流”分为两种:以内存为第一人称,数据从内存向外流的称为输出流,数据由外向内存流的称为输入流

  还值得补充的一点是,不知道大家有没有发现,我们在对一个文件操作前必须先打开它,获得与之关联的文件指针,这个指针就可以称为“文件流”,因为这个指针指向了数据的目的地 / 源头。但我们在对屏幕写出数据时或从键盘上读入数据时,并没有对这些外部设备进行打开操作获得所对应的“流”啊,而且在scanf和printf操作的时候也没有要求你给出数据的流向,最后却还能实现,这是为什么呢?
因为任意一个C程序只要运行起来,就会默认打开3个“流”:

stdin —— 标准输入流(键盘)

stdout —— 标准输出流(屏幕)

stderr —— 标准错误流(屏幕)

  所以printf()会默认将数据发送到stdout这个“流”上,scanf()会默从stdin这个“流”上读取数据,不需要我们手动打开和关闭“流”。但对于文件来说,我们就必须先打开这个文件从而获得这个“流”,然后才能从这个“流”里面读取数据或向这个“流”里面写数据,最后还得关闭“流”。
 那有同学就要问了:能不能用格式化输出函数fprintf()来向屏幕上输出一段内容?答案当然是可以的.

clock

C语言中的函数clock( ),它可以捕捉从程序开始运行到clock( )被调用时所耗费的时间。它计时所用的单位是clock tick,翻译成中文就是“时钟打点”。

与之配套的还有一个常数CLK_TCK,实际上就是“clock tick”的缩写。它给出的是机器时钟每秒所走的时钟打点数。这个数在不同机器中可能不一样,可以通过写程序得到一台机器的CLK_TCK。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include<math.h>
#include<time.h>

int main( )
{
printf("%d\n", CLK_TCK);
return 0;
}


将clock( )函数和常数CLK_TCK两个配合在一起,就可以计算出来一个函数到底跑了多少秒钟。

以下是一个常用的模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<studio.h>
#include<time.h>
/*要用clock( )函数必须要包含time.h*/
clock_t start,stop;/*clock_t是clock( )函数返回的变量类型*/
double duration;/*记录被测函数运行时间,以秒为单位*/
int main( )
{ /*不在测试范围内的准备工作写在clock( )调用之前*/
start=clock();/*开始计时*/
MyFunction();/*把被测函数加在这里*/
stop=clock();/*停止计时*/
duration=((double)(stop-start))/CLK_TCK;/*计算运行时间*/
/*其他不在测试范围的处理写在后面,例如输出duration的值*/
return 0;
}

下面是一个具体的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<stdio.h>
#include<math.h>
#include<time.h>
clock_t start, stop;
double duration;
#define MAXN 10
double f(int n, double a[], double x);

int main()
{
int i;
double a[MAXN];
for (i = 0; i < MAXN; i++) a[i] = (double)i;

start = clock();
f(MAXN - 1, a, 1.1);
stop = clock();
duration = ((double)(stop - start)) / CLK_TCK;

printf("ticks=%f\n", (double)(stop - start));
printf("duration=%6.2e\n", duration);
return 0;

}
double f(int n, double a[], double x)
{
int i;
double p = a[0];
for (i = 1; i <= n; i++)
p += (a[i] * pow(x,i));
return p;
}

计算结果都是0,是因为这个函数跑的实在是太快了,它的运行时间不到一个tick,所以clock函数铺捉不到它。解决方法就是让被测函数重复运行充分多次,使得测出的总的时钟打点间隔充分长,最后计算被测函数平均每次运行的时间即可。

调整后的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<stdio.h>
#include<math.h>
#include<time.h>
clock_t start, stop;
double duration;
#define MAXN 10
#define MAXK 1e7/*被测函数最大重复调用次数*/
double f(int n, double a[], double x);

int main()
{
int i;
double a[MAXN];
for (i = 0; i < MAXN; i++) a[i] = (double)i;

start = clock();
for(i=0;i<=MAXK;i++)/*重复调用函数已获得充分多的时钟打点数*/
f(MAXN - 1, a, 1.1);
stop = clock();
duration = ((double)(stop - start)) / CLK_TCK/MAXK;/*计算函数单次运行的时间*/

printf("ticks=%f\n", (double)(stop - start));
printf("duration=%6.2e\n", duration);
return 0;

}
double f(int n, double a[], double x)
{
int i;
double p = a[0];
for (i = 1; i <= n; i++)
p += (a[i] * pow(x,i));
return p;
}

这个数据在不同的电脑上运行出来的结果不同,因为不同机器的CLK_TCK不一定相同

1677666755946

链接:CMD命令大全
CMD命令:开始->运行->键入cmd或command(在命令行里可以看到系统版本、文件系统版本)
chcp 修改默认字符集
chcp 936默认中文
chcp 65001

  1. appwiz.cpl:程序和功能
  2. calc:启动计算器
  3. chkdsk.exe:Chkdsk磁盘检查(管理员身份运行命令提示符)
  4. cleanmgr: 打开磁盘清理工具
  5. cmd.exe:CMD命令提示符
  6. 自动关机命令
      Shutdown -s -t 600:表示600秒后自动关机
      shutdown -a :可取消定时关机
      Shutdown -r -t 600:表示600秒后自动重启
  7. CompMgmtLauncher:计算机管理
  8. compmgmt.msc:计算机管理
  9. credwiz:备份或还原储存的用户名和密码
  10. control:控制面版
  11. dcomcnfg:打开系统组件服务
  12. devmgmt.msc:设备管理器
  13. desk.cpl:屏幕分辨率
  14. dfrgui:优化驱动器 Windows 7→dfrg.msc:磁盘碎片整理程序
  15. dialer:电话拨号程序
  16. diskmgmt.msc:磁盘管理
  17. dvdplay:DVD播放器
  18. dxdiag:检查DirectX信息
  19. eudcedit:造字程序
  20. eventvwr:事件查看器
  21. explorer:打开资源管理器
  22. Firewall.cpl:Windows防火墙
  23. fsmgmt.msc:共享文件夹管理器
  24. gpedit.msc:组策略
  25. hdwwiz.cpl:设备管理器
  26. inetcpl.cpl:Internet属性
  27. intl.cpl:区域
  28. iexpress:木马捆绑工具,系统自带
  29. joy.cpl:游戏控制器
  30. logoff:注销命令
  31. lusrmgr.msc:本地用户和组
  32. lpksetup:语言包安装/删除向导,安装向导会提示下载语言包
  33. lusrmgr.msc:本机用户和组
  34. main.cpl:鼠标属性
  35. mmsys.cpl:声音
  36. mem.exe:显示内存使用情况(如果直接运行无效,可以先管理员身份运行命令提示符,在命令提示符里输入mem.exe>d:a.txt 即可打开d盘查看a.txt,里面的就是内存使用情况了。当然什么盘什么文件名可自己决定。)
  37. mmc:打开控制台
  38. mobsync:同步命令
  39. Msconfig.exe:系统配置实用程序
  40. msdt:微软支持诊断工具
  41. msinfo32:系统信息
  42. mspaint:画图
  43. Msra:Windows远程协助
  44. mstsc:远程桌面连接
  45. NAPCLCFG.MSC:客户端配置
  46. ncpa.cpl:网络连接
  47. narrator:屏幕“讲述人”
  48. Netplwiz:高级用户帐户控制面板,设置登陆安全相关的选项
  49. netstat : an(TC)命令检查接口
  50. notepad:打开记事本
  51. Nslookup:IP地址侦测器
  52. odbcad32:ODBC数据源管理器
  53. OptionalFeatures:打开“打开或关闭Windows功能”对话框
  54. osk:打开屏幕键盘
  55. perfmon.msc:计算机性能监测器
  56. perfmon:计算机性能监测器
  57. PowerShell:提供强大远程处理能力
  58. printmanagement.msc:打印管理
  59. powercfg.cpl:电源选项
  60. psr:问题步骤记录器
  61. Rasphone:网络连接
  62. Recdisc:创建系统修复光盘
  63. Resmon:资源监视器
  64. Rstrui:系统还原
  65. regedit.exe:注册表
  66. regedt32:注册表编辑器
  67. rsop.msc:组策略结果集
  68. sdclt:备份状态与配置,就是查看系统是否已备份
  69. secpol.msc:本地安全策略
  70. services.msc:本地服务设置
  71. sfc /scannow:扫描错误并复原/windows文件保护
  72. sfc.exe:系统文件检查器
  73. shrpubw:创建共享文件夹
  74. sigverif:文件签名验证程序
  75. slui:Windows激活,查看系统激活信息
  76. slmgr.vbs -dlv :显示详细的许可证信息
      slmgr.vbs -dli :显示许可证信息
      slmgr.vbs -xpr :当前许可证截止日期
      slmgr.vbs -dti :显示安装ID 以进行脱机激
      slmgr.vbs -ipk :(Product Key)安装产品密钥
      slmgr.vbs -ato :激活Windows
      slmgr.vbs -cpky :从注册表中清除产品密钥(防止泄露引起的攻击)
      slmgr.vbs -ilc :(License file)安装许可证
      slmgr.vbs -upk :卸载产品密钥
      slmgr.vbs -skms :(name[ort] )批量授权
  77. snippingtool:截图工具,支持无规则截图
  78. soundrecorder:录音机,没有录音时间的限制
  79. StikyNot:便笺
  80. sysdm.cpl:系统属性
  81. sysedit:系统配置编辑器
  82. syskey:系统加密,一旦加密就不能解开,保护系统的双重密码
  83. taskmgr:任务管理器(旧版)
  84. TM任务管理器(新版)
  85. taskschd.msc:任务计划程序
  86. timedate.cpl:日期和时间
  87. UserAccountControlSettings用户账户控制设置
  88. utilman:辅助工具管理器
  89. wf.msc:高级安全Windows防火墙
  90. WFS:Windows传真和扫描
  91. wiaacmgr:扫描仪和照相机向导
  92. winver:关于Windows
  93. wmimgmt.msc:打开windows管理体系结构(WMI)
  94. write:写字板
  95. wscui.cpl:操作中心
  96. wscript:windows脚本宿主设置
  97. wuapp:Windows更新
阅读全文 »

路线

《Pointers On C》(Kenneth Reek) 【US】

第一章 快速上手

1.1 简介

1.1.1 空白和注释

注释并不能真正将代码从源文件中删除(/**/)

逻辑上删除C代码——#if指令

1
2
3
#if 0   
statements
#endif

在#if和#endif之间的程序段可以去除

1.1.2 预处理指令

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define ABC 20``

预处理器解释的:预处理器读入源代码,根据预处理指令对其进行修改,然后将修改过的代码递交给编译器。

eg:<stdio.h>->#include

1.1.3 main函数

每个C程序都必须有一个main函数–>程序执行的起点
main函数内容:花括号之间({})

关键字:int 表示函数返回一个整型值

&emsp;&emsp;&emsp;void表示函数不返回任何值

传递方式
数组参数: 引用^引用
标量和常量: 值

C函数的参数传递规则如下:所有传递给函数的参数都是按值传递的

字符串:一串以[^NUL]NUL字节结尾的字符。
字符串常量:“&emsp; ”中间的

1.1.4 read_column_numbers函数

1.1.5 rearrange函数

1.2 补充说明

1.3 编译

1.4 总结

格式化输入与输出 非格式化输入与输出
printf putchar
scanf getchar

1.5 警告的总结

1.在scanf函数的^标量参数前未加 & .

阅读全文 »

头文件math.h

实数绝对值函数

➢指数函数

double fabs(double x);

double exp(double x);

求实数x的绝对值|x|

求e的实数x次幂ex

例: fabs(3.5)的值为3.5

例: exp(1.0)的值约为2.71828

fabs(-3.5)的值为3.5

exp(2. 5)的值约为12.1825

平方根函数

double sqrt(double x);

➢对数函数

double log(double x);

求实数x的平方根vx

求以e为底正实数x的对数Inx

例: sqrt(100.0)的值约为10.0

double log10(doublex);

sqrt(12.96)的值约为3.6

求以10为底正实数x的对数lgx

➢幂函数

例: log(2.718283)的值约为1.0

double pow(double x, doubley); .

log(45.7)的值约为3.822098

求实数x的实数y次幂x

log10(1000.0)的值约为3.0

例: pow(2.0, 10.0)的值约为1024.0

log10(6.022e23)的值约为23.7797

pow(4.3, 2.9)的值约为68.7161

注: C只提供以e和10为底数的对数函数。当计算

以其它实数为底数的对数时,可利用换底公式。

➢双曲函数

ex-e-x
shx或sinhx
double sinh(double x);
sinh x=
2
chx或cosh xdouble cosh(double x);
thx或tanhx
double tanh(double x);
e*+ e-x
例: sinh(1.0)的值约为1.175201
coshx= -
2
cosh(1.0)的值约为1.543081
tanh(1.0)的值约为0.7615942
ex- e-x

➢取整函数

tanh x =ex+ e-x
[x1 double ceil(double x);
. lx」
double floor(double x);
例: ceil(1.1)的值约为2.0, ceil(-1.1)的值约为-1.0
floor(1.1)的值约为1.0, floor(-1.1)的值约为-2.0
ceil(1.0)和floor(1.0)的值都约为1.0, ceil(-1.0)和floor(-1.0)的值都约为-1.0

➢取模函数

xmody
double fmod(double x, double y);
例: fmod(14.0, 3.0)的值约为2.0, fmod(-14.0, -3.0)的值约为-2.0
fmod(-6.5, -3.2)的值约为-0.1, fmod(6.5, -3.2)的值约为0.1

欢迎使用 Cmd Markdown 编辑阅读器


我们理解您需要更便捷更高效的工具记录思想,整理笔记、知识,并将其中承载的价值传播给他人,Cmd Markdown 是我们给出的答案 —— 我们为记录思想和分享知识提供更专业的工具。 您可以使用 Cmd Markdown:

> * 整理知识,学习笔记
> * 发布日记,杂文,所见所想
> * 撰写发布技术文稿(代码支持)
> * 撰写发布学术论文(LaTeX 公式支持)
阅读全文 »