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

C语言基础:数据类型、输入输出与垃圾字符回收详解

变量

程序运行过程中会发生变化

格式:

存储类型 数据类型 变量名

auto

存储类型:决定变量存放的位置(auto 表示默认存储在栈区,由系统自动管理)

数据类型:决定开辟的空间大小

变量名:遵循标识符命名规则

类型

含义

字节大小

取值范围(了解)

char

字符型

1

-128~127

int

整型

4

约 -21 亿 ~ 21 亿

short

短整型

2

-32768~32767

long

长整型

32位:4 64位:8

依赖平台(32/64位不同)

float

单精度浮点型

4

有效位数:6-7

double

双精度浮点型

8

有效位数:15-16

使用sizeof运算符可以查看任意类型在当前平台下占用的字节数:

printf("%ld\n", sizeof(char));

以上代码输出char类型在当前平台下的字节大小(通常为 1)。

局部变量和全局变量的区别

对比维度

局部变量

全局变量

定义位置

函数体内部

函数体外部

初值

未初始化,值为随机数

未初始化,值为0

存储位置

栈区

全局区

作用域

当前函数体内

整个程序

生命周期

随函数共存亡

随整个程序共存亡

简单记忆:局部变量在函数内部定义,函数结束即销毁;全局变量在函数外部定义,整个程序运行期间一直存在。

虚拟内存空间

32位系统:4G 虚拟地址空间;64位系统:264 虚拟地址空间

栈区:系统自动开辟、回收(存放局部变量、函数参数)

堆区:程序员手动开辟、回收(通过 malloc/free 管理)

全局区 / 静态区:存放全局变量和静态变量,进一步分为:

.bss 段:未初始化或初始化为 0 的全局/静态变量

.data 段:已初始化且初值非 0 的全局/静态变量

常量区:存放字符串常量等只读数据

常量

程序运行过程中不会发生变化

整型常量

支持四种进制表示:二进制(0b 前缀)、八进制(0 前缀)、十进制(默认)、十六进制(0x 前缀)

浮点型常量

float 和 double 类型,如 3.14(默认 double 类型),3.14f 表示 float 类型

字符常量

由单引号包裹单个元素

char a = 'a';

a 是变量

'a' 是字符常量

\ 转义字符:如 \n(换行)、\t(制表)、\\(反斜杠本身)

字符串常量

由双引号包裹,以 '\0' 为结束标志

"hello" ----> 实际存储为 "hello\0",占 6 个字节

标识常量(宏定义)

宏定义:在预处理阶段进行文本替换

格式:

#define 宏名 常量值或表达式或函数

宏名:一般用大写,为了和普通变量区分开

特点:先进行单纯的替换,最后再计算(注意运算优先级,建议加括号保护)

#include<stdio.h> #define N 3 #define M N+1 #define NUM N+M/2 int main(int argc, char const *argv[]) { printf("%d\n", NUM); return 0; }

宏示例:求两个数中的最大值

#include<stdio.h> #define MAX a>b?a:b int main(int argc, char const *argv[]) { int a = 33; int b = 56; printf("%d\n", MAX); a = 67; b = 89; printf("%d\n", MAX); return 0; }

宏函数(带参数的宏)

#include<stdio.h> #define MAX(a, b) a>b?a:b int main(int argc, char const *argv[]) { printf("%d\n", MAX(12, 35)); printf("%d\n", MAX(87, 59)); return 0; }

宏函数与普通函数的区别:宏函数在预处理阶段直接展开,没有函数调用开销,但不做类型检查,且多次参数求值可能带来副作用。

输入输出

按字符输入输出

getchar

int getchar(void);// int a;

功能:从终端(标准输入)读取一个字符

参数: void(无参数)

返回值:读取字符的 ASCII 码值(int 类型),失败返回 EOF

putchar

int putchar(int c);

功能:向终端(标准输出)输出一个字符

参数:要输出的字符的 ASCII 码值

返回值:成功输出时返回该字符的 ASCII 码值,失败返回 EOF

#include<stdio.h> int main(int argc, char const *argv[]) { // getchar(); int n = getchar(); putchar(n); putchar(10); return 0; }

利用 getchar 吸收多余的换行符:

当使用 scanf 读取字符后,缓冲区中可能残留换行符,可以在下一次 scanf 前调用 getchar() 将其吸收掉:

char a = 0; scanf("%c", &a); getchar(); printf("%d\n", a); char b = 0; scanf("%c", &b); printf("%d\n", b);

按格式输入输出

printf

int printf(const char *format, ...);

功能:按指定格式向终端输出内容

参数:第一个参数是格式字符串,后面是不定长的输出项

返回值:成功输出元素的个数

常用格式占位符:

%d:int 整型

%c:char 字符型

%f:float 单精度浮点型

%lf:double 双精度浮点型

%s:字符串

%p:指针地址

%o / %#o:八进制(加 # 显示前导 0)

%x / %#x:十六进制(加 # 显示前导 0x)

精度控制:.n 保留 n 位小数,四舍五入

%f 默认输出小数点后六位

float a = 123.456; printf("%f\n", a); // 输出 123.456000 printf("%.1f\n", a); // 输出 123.5

位宽控制:m 位宽,位宽值大于数据实际宽度时才会在左侧补空格对齐

#include<stdio.h> int main(int argc, char const *argv[]) { int a = 2; int b = 22; int c = 222; printf("%3d\n", a); // 输出 " 2" printf("%3d\n", b); // 输出 " 22" printf("%d\n", c); // 输出 "222" return 0; }

scanf

int scanf(const char *format, ...);

功能:按指定格式从终端读取输入

参数:格式字符串 + 变量地址列表(需使用 & 取地址)

返回值:成功赋值的输入项个数;第一个元素赋值失败时返回 0

#include<stdio.h> int main(int argc, char const *argv[]) { int a = 0; int b = 0; printf("please input a b:\n"); scanf("%d %d", &a, &b); printf("%d %d\n", a, b); return 0; }

需要注意:scanf 中%d%f%s会自动跳过前置空白字符(空格、换行、制表符),但%c不会自动跳过。如果想深入了解%c的特殊行为以及如何处理缓冲区中的垃圾字符,请继续阅读下一章「垃圾字符回收」。

垃圾字符回收

一、核心问题:%c会读取空白垃圾字符

1. 空白字符包含哪些

空格 、制表符\t、换行符\n,都属于空白垃圾字符,%c会原封不动读入变量。

2. 案例 1:连续两个%c无空格

char a = 0; char b = 0; scanf("%c%c", &a, &b); printf("%d %d\n", a, b);

输入场景演示

场景 1:输入x y(x + 空格 + y,回车)

  • 第一个%c读取字符x→ 存入 a
  • 第二个%c直接读取中间的空格→ 存入 b
  • 输出结果:120 32(x 的 ASCII=120,空格 ASCII=32)

场景 2:输入x按回车,再输入y

  • a =x(ASCII=120)
  • b = 换行符\n(ASCII=10)
  • 输出:120 10

结论:%c不会自动跳过空格、回车,缓冲区中残留的空白字符会被直接当成有效字符读取,产生意料之外的垃圾值。

二、空白回收方案:格式串前加空格%c

语法规则

%c转换符前面写一个空格 ,作用:自动跳过缓冲区中一个或多个连续空白字符(空格、\t\n全部清空)。

对比代码

char a = 0; scanf("%c", &a); // 无前置空格,会读回车/空格 printf("%d\n", a); char b = 0; scanf(" %c", &b); // 前置空格,自动清空前面所有空白垃圾 printf("%d\n", b);

连续双字符修正写法

如果要连续读取两个字符、忽略中间空白,给每个%c前加空格:

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

此时输入a 回车 ba 空格 ba\tb都会正常读取 a、b,空白全部被过滤。

三、易混淆知识点:%d/%f%c的区别

  1. %d%f%s默认自动跳过前置空白,不用手动加空格;
  2. %c不会自动跳过空白,缓冲区残留的回车 / 空格会直接读入,必须手动加空格过滤垃圾字符。

小结:遇到%c读字符前如果前面有输入残留,优先使用%c(前置空格)方案;如果只是想丢弃单个回车,也可以用getchar()吸收。

http://www.jsqmd.com/news/1183174/

相关文章:

  • 树上连通块信息维护
  • 7个实用KQL查询:解锁GuardDuty-Sentinel-Integration的安全分析能力
  • 2026年发票查验官方操作流程,新手入门实用指南 - 跑政通
  • 告别加班改PPT,ChatGPT自动排版+配色+演讲备注生成,职场人必备的5个隐藏指令,仅限本周内公开
  • 【宝藏工具盘点】5款开源免费的2D角色动画生成器,独立开发者的福音
  • 你的内容为什么 AI 不推荐?三个动作让它主动选中你|GEO 实操(附 SOP)
  • GPT-5.6 实测案例:性能、能力与未来展望
  • 抖店运营系统怎么按经营模式选择-对比测试与选择 - 抖大侠
  • 2026年7月最新郑州宝玑官方售后服务热线与网点地址查询 - 亨得利钟表维修中心
  • 喷码字体虚边、毛边,墨滴分裂技术层面的成因?
  • 突破苹果硬件限制:OpenCore Legacy Patcher终极完整指南
  • 2026年07月新疆旅游定制包车游与精品小团市场深度观察:五家实力服务商全景解析 - 甄选服务推荐
  • SVG 基础:在 HTML 中使用矢量图形
  • AHK-v2-script-converter社区支持与资源:获取帮助的最佳途径
  • 【计算机大数据毕业设计案例】健身打卡分享与体能测评小程序系统的设计与实现 基于 SpringBoot 的用户健身行为分析管理系统(程序+文档+讲解+定制)
  • 【Embedded Development】【LVGL】基于Windows的LVGL模拟界面开发
  • 如何线上办理委托书公证?2026 年详细操作步骤指南 - 跑政通
  • 工业焊缝场景 焊缝缺陷数据集 6400张图片 支持YOLO格式 YOLO模型如何训练焊缝缺陷检测数据集
  • 常用环境部署(十四)——Docker部署MinIO(OSS)
  • 2026最新Java程序员转行AI大模型全攻略(小白零基础可学)
  • 3分钟掌握Free Texture Packer:如何将游戏性能提升200%的终极免费方案
  • 【独家首发】DeepSeek-R1长文本微调SOP(含Prompt Engineering黄金模板+评估指标白皮书)
  • 【小程序计算机毕业设计案例】地方特色农产品推介与电商交易小程序设计与实现 农产品分类展销、评价与订单管理系统的设计与实现(程序+文档+讲解+定制)
  • Windows 11终极优化指南:使用Win11Debloat一键清理系统垃圾,提升性能与隐私保护
  • 戴尔笔记本风扇控制终极指南:DellFanManagement让你的笔记本更安静更凉爽
  • Linux操作系统 --- 进程
  • 【小程序计算机毕业设计案例】智慧便民服务共享雨伞租赁平台的设计与实现 小程序实现的共享雨伞自助租借归还系统(程序+文档+讲解+定制)
  • 液氦管路哪家质量好探秘真空绝热与焊接工艺如何决定低温传输的长期可靠性 - 品牌推荐大师
  • 室内液体泼洒检测数据集 YOLOV11室内漏液检测数据集 室内跑冒滴漏检测数据集
  • 2026年土工材料供应厂家:土工布/土工格栅/土工膜/土工格室/玻纤及钢塑土工格栅等专业生产商深度解读 - 品牌发掘