当前位置: 首页 > news >正文

C语言:20250712笔记

 

数据的输入与输出

数据的输入与输出是相对而言,其中:

  • 从计算机向外部输送数据为输出(output)。通常的输出设备:显示器、打印机。

  • 从外部向计算机输送数据为输入(input)。通常的输入设备:键盘、鼠标、扫描仪。

在C语言中,输入与输出需要使用标准的输入输出库(stdio.h)中的输入函数(scanf())、输出函数(printf())实现,houg可以扩展其他输入输出函数。我们将这种跟硬件打交道的输入输出操作称作外设IO。

库函数已经被编译成了目标文件内置于编译系统,在链接时与编译源程序得到的目标文件相链接,生成可执行程序。

注意:在使用系统库函数的时候,需要用预处理指令#include将有关的头文件包含到用户资源文件中(一般放在程序的开头位置)头文件中包含了调用函数时需要的有关信息,具体的函数实现在编译的时候再去链接对应的系统库。

输入输出缓冲机制

缓冲区的概念

  • 缓冲区(缓存)是内存空间的一部分,用于暂存输入或输出的数据。

  • 在进行输入操作时,系统从外部设备(如键盘)读取数据,先放入缓冲区,程序再从缓冲区中读取数据。

    输入时数据流向:外部设备 → 输入缓冲区 → 程序

  • 在进行输出操作时,系统先将数据放入缓冲区,然后在特定条件下(如缓冲区满、遇到特定字符、手动刷新等)再将缓冲区中的数据输出到外部设备(如屏幕)

    输出时数据流向:程序 → 输出缓冲区 → 外部设备

缓冲区的类型

C语言的缓冲区有三种类型:

  • 全缓冲:当缓冲区填满后,才进行实际的输入输出操作。例如:对磁盘文件的读写。--- window全缓冲区大小是4096字节, Linux全缓冲区大小是1024字节。

  • 行缓冲:当在输入和输出中遇到换行符(\n或者回车)时,执行实际的输入输出操作。例如:标准输入(stdin)和标准输出(stdout)。

  • 无缓冲:不进行缓冲,直接进行输入输出操作。例如:标准错误流(stderr)

缓冲区的刷新条件

缓冲区的刷新(如将缓冲区中的数据实际输出到外部设备)通常发生在以下情况:

  • 缓冲区满:当缓冲区写满时,会自动刷新。

  • 遇到特定字符:如换行符(\n)等。

  • 手动刷新:使用fflush(stdout)函数手动刷新输出缓冲区。

  • 程序关闭时:当程序结束时,缓冲区中的数据会被刷新。

缓冲区的实际应用

  • 提高效率:通过缓冲区,可以减少与外部设备的交互次数,提高数据传输的效率

  • 处理输入输出:例如:使用scanf和printf函数时,数据先被放入缓冲区,然后按照特定的规则从缓冲区读取或输出。

原理实现

简单的输入与输出

用printf函数输出数据

基础用法

语法:

 printf("格式控制",输出列表);

引用文件:

 #include <stdio.h>

举例:

 printf("i=%d,x=%d,y=%d\n",i,34,i+1);

注意:格式控制中的格式化符号(%d)要和输出的数据一一对应。

参数:

  • 格式控制:用一对英文双引号括起来,包括两种信息:

  • 格式说明:由%特定字符组成,如:%d,%f,%c等,这是格式说明符,用于说明输出项目所采用的格式。
    • 普通字符:作为说明性文字、符号等,按照输入原样输出。

  • 输出列表:输出列表中的各项目指出了所要输出的内容。可以是常量(字面量、符号常量、const修饰的变量)、变量、表达式。输出列表的个数,由格式控制中的格式化符号来决定。

基本的格式化符

%d 按有符号十进制整型(int)数据的实际长度输出。(十进制(0)、八进制(00)、十六进制(0x00))%u 按无符号十进制整型(int)数据的实际长度输出。%c 仅输出一个字符(char)%s 输出结果是字符串,举例:printf("%s\n","CHINA");,输出结果:CHINA%f 以小数形式输出float类型实数;%lf 以小数形式输出double类型(双精度)实数%e 也可以写作%E,以指数形式输出一个实数(涵单双精度)。小数点前1位非0数字,并输出6位小数。%hd 短整型(short int/short)%hhd 字符型的ASCII码,char数据对应的ASCII码的值,举例:char a = 'A';printf("%hhd\n",a);,输出结果:65%ld 长整型(long int/long)%lld 长长整型(long long int/long long)%x 十六进制,但是十六进制的前缀0x不会打印出来,举例:printf("%x\n",198);,输出结果:c6%#x 十六进制,并且十六进制的前缀0x也会打印出来,举例:printf("%#x\n",198);,输出结果:0xc6%o 八进制,前缀0不会打印出来,举例:5%#o 八进制,并且八进制的前缀0也会打印出来,举例:05%p 打印内存的地址%% 输出%本身

案例:

 /*************************************************************************> File Name:    demo01.c> Author:       阮> Description:  > Created Time: 2025年07月11日 星期五 08时40分56秒************************************************************************/​#include <stdio.h>​int main(int argc,char *argv[]){printf("%x,%#x\n",255,255);//输出16进制整数printf("%o,%#o\n",255,255);//输出8进制printf("%d,%u,%c\n",5,5,'%');//正常输出printf("%%\n");//输出%printf("%f,%lf,%e\n",99.12345,99.12345,99.12345);return 0;}

用scanf函数输入数据

基础用法

语法:

 scanf("格式控制",地址列表);

注意:地址列表不能传变量、常量、表达式。只能传与之对应的内存地址(首地址),如果是普通的变量,通过&+b变量名获取变量地址。

举例:

 int a = 10; // 定义了一个变量ascanf("%d",&a);// &在这里称作 取地址符,&a的意思是获取变量a对应的内存地址(首地址)

作用:

将从键盘输入的数据存入内存中所占的存储单元里,存储单元有地址标识。

参数:

  • 格式控制:含义等同于printf函数的格式控制,说明输入的数据应该使用的格式。

  • 地址列表:是由若干个地址组成,可以是变量的地址或者字符串的地址。&是取地址符号,用于取出变量的地址。与格式化输出一样,在格式控制中,用于说明数据格式的格式说明符以%开头,后面紧跟具体的格式。

案例:

  • 需求:从键盘输入整数给变量a,b,c赋值

  • 代码:

 /*************************************************************************> File Name:    demo02.c> Author:       阮> Description:  > Created Time: 2025年07月11日 星期五 15时41分21秒************************************************************************/​#include <stdio.h>​int main(int argc,char *argv[]){//定义三个变量int a,b,c;//因为需要控制台输入赋值,所以无需初始化​//每次使用键盘前加信息printf("请输入3个整数:\n");scanf("%d%d%d",&a,&b,&c);printf("a=%d,b=%d,c=%d\n",a,b,c);return 0;}

总结:输入多个数据的时候可以用空格、Tab键、回车键中的任意一种。

说明:

  • scanf函数中的“格式控制”后面应当是变量的地址,由取地址符&和变量名共同组成,举例:

      scanf("%f%d", &a, &b);

     

  • 如果“格式控制”中除了格式说明以外还有其他字符,则在输入数据时必须在对应位置输入与之相同的字符,举例:

      scanf("%d,%d",&a, &b);

    从键盘录入数据的时候,使用格式控制中的逗号分隔:3,4

      scanf("%d-%d-%d",&year, &month, &day);

    从键盘录入数据的时候,使用格式控制中的短横线分隔:2025-7-11

     scanf("%d年%d月%d日",&year, &month, &day);

    从键盘录入数据的时候,使用格式控制中的年月日分隔:2025年7月11日

  • %c格式输入字符时,转义符(如:\n,\t等)都作为有效字符输入,应注意:

     scanf("%c%c%c", &a, &b, &c);

    注意:其实Tab键、空格键、回车键的响应都是当做字符处理。

  • 在输入数值型数据(整型+浮点型)时,遇到空格、回车、Tab键或遇到非法输入(A,?..),则认为该输入结束;

      scanf("%d%d%d",&a, &b, &c);
  • 对于unsigned型变量所需的数据,建议用%u格式输入;若用%dsigned int),需确保输入值在int范围内(否则可能溢出)

复杂的输入与输出

按指定格式输出数据的宽度、小数位数、上下行数据按小数点对齐、用八进制、十六进制输出等。

输出数据格式控制

整型格式说明符

  • 十进制形式(0~9)

    说明符说明数据类型
    %d和%md用于基本整型int
    %ld和%mld用于长整型long
    %u和%mu用于无符号基本整型unsigned int
    %lu和%mlu用于无符号长整型unsigned long
  • 八进制形式(0~7)

    说明符说明数据类型
    %o和%mo用于基本整型int
    %lo和%mlo用于长整型long
  • 十六进制形式(0~F)

    说明符说明数据类型
    %x和%mx用于基本整型int
    %lx和%mlx用于长整型long

说明:

m表示输出整型数据所占的总宽度(列数,1个字符占1列),其中:

① 当实际数据的位数不到m位时,数据前面将用空格填满, 举例:原数据("12"),列宽为m(4)的数据(" 12"

② 若实际数据的位数大于等于m位时,则以数据的实际位数为标准进行输出,列宽无效,举例:

原数据("12345"),列宽m(4)的数据("12345"

总结:

如果实际 数据列宽 < m,使用空格补齐m。

如果实际 数据列宽 >=m,输出实际数据,m失效。

一个int型整数也可以用%u输出,反之一个unsigned型整数也可以用%d、%o、%x格式输出。按相互赋值的规则处理。

举例:

/*************************************************************************> File Name:    demo03.c> Author:       阮> Description:  > Created Time: 2025年07月11日 星期五 16时47分15秒************************************************************************/​#include <stdio.h>​int main(int argc,char *argv[]){printf("%d\n",12); //"12"     实际列宽为2printf("%6d\n",12); //"    12" 实际列宽为6,右对齐,左边空格填充printf("%-6d\n",12); //"12    " 右边空格填充printf("%6d\n",1234567); //"1234567"printf("%06d\n",12); //"000012" 输出后补全对齐,实际列宽6,右对齐,左边对其printf("%+d,%+d",12,-12); //"+12,-12"输出后显示正负号printf("%#06x,%#06o\n",12,12); //"0x000c,000014" 实际列宽为6return 0;}

字符型格式说明符

  • 字符型

    说明符说明举例
    %c或者%mc输出的字符占m列printf("%3c\n",'a');

用法和整型的用法一致。

  • 字符串型

    在C语言中,支持字符串常量,不支持字符串变量。

    说明符说明
    %ms输出的字符串占m列。若串长>=m,全部输出;反之在串前补空格(m为正往前补空格) 举例:
    printf("%6s\n","hello"); " hello"

     

    %-ms输出的字符串占m列。若串长>=m,全部输出;反之在串后补空格(m为负往后补空格) 举例:
    printf("%-6s\n","hello"); "hello "
    %m.ns输出的字符串占m列,取字符串前 n 个字符,再按 m 列补空格。 举例:
    printf("%6.2s\n","hello"); " he"(先截取,在补全)
    %-m.ns

    输出的字符串占m列。只取字符串前n个字符,不足部分串后补空格。 举例:

    printf("%-6.2s\n","hello"); "he "

案例:

  • 需求:字符串输出

  • 代码:

/*************************************************************************> File Name:    demo04.c> Author:       阮> Description:  > Created Time: 2025年07月11日 星期五 17时09分26秒************************************************************************/​#include <stdio.h>​int main(int argc,char *argv[]){printf("%3s\n%7.2s\n%-5.3s\n%.4s\n","CHINA","CHINA","CHINA","CHINA");// %3s:       "CHINA"        超出指定列宽,按实际列宽输出// %7.2s:     "     CH"      截取CH,实际列宽补足到7,右对齐// %-5.3s:    "CHI  "        截取CHI,实际列宽补足到5,左对齐// %.4s:      "CHIN"         截取CHIN,实际列宽就是默认列宽4return 0;}

浮点型格式说明符

浮点型格式分为三种形式:

序号名称说明
1十进制形式%m.nf或者%-m.nf,m是列宽,n是保留的小数位
2指数形式%m.ne或者%-m.ne,m是列宽,n是保留的尾数位
3%g或者%G形式根据数值的大小,自动选择%f或者%e中宽度较短的一种格式,不输出无意义的0

解释:

在输出浮点型数据时,格式说明符中的m表示整个数据所占的列宽,n表示小数点后面所占的位数(保留的小数位)

如果在小数点后取n位后,所规定的数据宽度m不够输出数据前面的整数部分(包括小数点),则按实际的位数进行输出。

案例:

  • 需求:输出浮点型数时,指定小数位。

  • 案例:

/*************************************************************************> File Name:    demo05.c> Author:       阮> Description:  > Created Time: 2025年07月11日 星期五 17时22分42秒************************************************************************/​
#include <stdio.h>int main(int argc,char *argv[])
{float f = 123.456f; // f是标识,不计入列宽的,实际列宽是7printf("%8.2f\n%-8.2f\n%8.6f\n%9.2e\n%g\n%G\n",f,f,f,f,f,f);// %8.2f:     "  123.46" 小数位保存采取“四舍五入” 小数保留2位,实际列宽补足到8,右对齐// %-8.2f:    "123.46  " 左对齐// %8.6f:     "123.456001" 实际列宽超过指定列宽,以实际列宽为准// %9.2e:     " 1.23e+02"  首先,小数转换为指数;接着,处理尾数,这里的.2是尾数位;最后补足列宽。return 0;
}

注意:这里的小数位的保留采用四舍五入

 

http://www.dtcms.com/a/276000.html

相关文章:

  • SpringBoot集合Swagger2构建可视化API文档
  • P2619 [国家集训队] Tree I
  • 【Datawhale AI夏令营】Task2 笔记:MCP Server开发的重难点
  • 【LeetCode 热题 100】98. 验证二叉搜索树——(解法一)前序遍历
  • Python 三大高频标准库实战指南——json · datetime · random 深度解析
  • 【Java入门到精通】(二)Java基础语法(上)
  • 27. 移除元素
  • 【android bluetooth 协议分析 07】【SDP详解 1】【SDP 介绍】
  • 19th Day| 530.二叉搜索树的最小绝对差,501.二叉搜索树中的众数, 236.二叉树的最近公共祖先
  • springboot3X 整合高版本mybatisplus
  • pyqt5绘制矩形和线条
  • 【从零开始编写数据库:基于Python语言实现数据库ToyDB的ACID特性】
  • C语言<数据结构-单链表>(收尾)
  • Windows 开启和关闭 Administrator 用户的方法
  • 软考高级系系统分师和架构师常考知识点总结三
  • Typecho博客系统与WebSocket实时通信整合指南
  • 网络安全初级--搭建
  • GPU编程入门:CUDA与OpenCL全面解析
  • 聊下easyexcel导出
  • 岛屿数量问题
  • [爬虫实战] 多进程/多线程/协程-异步爬取豆瓣Top250
  • 小架构step系列12:单元测试
  • 【LeetCode】算法详解#8 ---螺旋矩阵
  • Linux->基础IO
  • 佩戴头盔数据集,5498张图片,平均识别率95.3% 其中戴头盔的图有2348张,支持yolo,coco json, pasical voc xml格式的标注
  • Ansible 入门指南:自动化配置管理核心技术与实战 SELinux 配置
  • day051-ansible循环、判断与jinja2模板
  • Frida绕过SSL Pinning (证书绑定)抓包;Frida注入;app无法抓包问题解决。
  • Spring之【写一个简单的IOC容器EasySpring】
  • 2025年亚太杯(中文赛项)数学建模B题【疾病的预测与大数据分析】原创论文分享