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

printf函数参数与入栈顺序

01. printf()的核心功能

作用:将 格式化数据 输出到 标准输出(stdout),支持多种数据类型和格式控制。

在这里插入图片描述

int printf(const char *format, ...);
  • 参数
    • format:格式字符串,字符串或%开头格式符
    • ...:可变参数,与" "内格式一一对应
  • 返回值:成功返回输出的字符数,失败返回负数

eg:

int count = printf("Hello, %s!\n", "World");
printf("输出了 %d 个字符\n", count); // 输出:输出了 13 个字符

02. printf()格式说明符

常用格式符

格式符数据类型示例
%dintprintf(“%d”, 66);
%uunsigned intprintf(“%u”, 66);
%ffloat/doubleprintf(“%.2f”, 6.666);
%ccharprintf(“%c”, ‘A’);
%s字符串printf(“%s”, “hello world”);
%p指针地址printf(“%p”, &x);
%zusize_tprintf(“%zu”, 100);
%x十六进制整数printf(“%x”, 66);

格式控制

默认右对齐,使用-可左对齐输出。%m.ns表示向右对齐占m列,左边不足补空格,输出字符只占n位,超出n位删去。同理%m.nf亦是如此。

  • 填充与对齐

    printf("%5d", 10);    //  "   10"。从右开始输出,不足处补空格
    printf("%-5d", 10);   //  "10   "。从左开始输出,不足处补空格
    printf("%05d", 7);    //  "00007"。从右开始输出,不足处补0
    
  • 精度控制

    printf("%.3f", 3.14159); //  "3.142"。保留3位小数
    printf("%.6s", "hello world"); // 输出前6个字符 "hello "
    

03. printf() 的参数入栈顺序

C标准未规定参数求值顺序。大多数编译(GCC、Clang)默认从右往左入栈顺序,这样可以支持…可变参数。这里讨论常见情况。

注意: 不同编译器可能出现不同的结果。

示例代码

int i = 1;
printf("%d, %d, %d\n", i++, i++, i++);
//GCC 一般情况输出  3, 2, 1

验证入栈顺序:

在这里插入图片描述
Linux下:
在这里插入图片描述

&a > &b > &c 符合栈的生长方向。

  • 参数入栈顺序:从右到左(c→b→a→格式串),但 64位系统优先用寄存器(前6个参数通过 rdi, rsi, rdx, rcx, r8, r9 传递)。
  • 参数访问顺序printf 按格式字符串的 % 顺序 从左到右 从寄存器或栈中读取参数。

参数传递:

  • rdi = 格式字符串地址
  • rsi = a 的值 (10)
  • rdx = b 的值 (20)
  • rcx = c 的值 (30)

输出顺序
printf%p 顺序读取 rsi→rdx→rcx,因此输出 &a, &b, &c

在这里插入图片描述

03. printf()输出流程

程序 内存缓冲区 标准输出(stdout) printf 屏幕 调用printf("Value: %d", 42)无`\0` 格式化字符串并写入缓冲区 满足条件时刷新(如缓冲区满、遇到\n) 显示"Value: 42" 程序 内存缓冲区 标准输出(stdout) printf 屏幕

04. 缓冲区机制

  • 行缓冲:默认模式(终端输出),遇到 \n 或缓冲区满时刷新。
  • 全缓冲:文件输出,缓冲区满或调用 fflush 时刷新。
  • 无缓冲:如 stderr,立即输出。

2. 强制刷新示例

printf("Processing...");  // 无换行符,行缓冲下不会立即显示
fflush(stdout);           // 强制刷新到屏幕

http://www.lryc.cn/news/2379136.html

相关文章:

  • 仿生眼机器人(人脸跟踪版)系列之一
  • 08、底层注解-@Configuration详解
  • Go语言语法---输入控制
  • 蓝桥杯单片机按键进阶
  • CSS- 4.3 绝对定位(position: absolute)学校官网导航栏实例
  • Flink 作业提交流程
  • 拓展运算符
  • Seata源码—6.Seata AT模式的数据源代理一
  • 计算机科技笔记: 容错计算机设计05 n模冗余系统 TMR 三模冗余系统
  • Spring Boot 与 RabbitMQ 的深度集成实践(一)
  • 黑马程序员2024新版C++笔记 第2章 语句
  • HTML5中的Microdata与历史记录管理详解
  • 上位机知识篇---涂鸦智能云平台
  • 面试中的线程题
  • 济南国网数字化培训班学习笔记-第三组-2-电力通信光缆网认知
  • 前端动画库 Anime.js 的V4 版本,兼容 Vue、React
  • 用 PyTorch 从零实现简易GPT(Transformer 模型)
  • 前端JSON序列化中的隐形杀手:精度丢失全解析与实战解决方案
  • 【通用大模型】Serper API 详解:搜索引擎数据获取的核心工具
  • Spring3+Vue3项目中的知识点——JWT
  • python3GUI--智慧交通分析平台:By:PyQt5+YOLOv8(详细介绍)
  • Linux任务管理与守护进程
  • C#里与嵌入式系统W5500网络通讯(2)
  • EMQX开源版安装指南:Linux/Windows全攻略
  • 【计算机视觉】OpenCV实战项目:GraspPicture 项目深度解析:基于图像分割的抓取点检测系统
  • MySQL 数据库备份与还原
  • Kubernetes控制平面组件:Kubelet详解(四):gRPC 与 CRI gRPC实现
  • javax.servlet.Filter 介绍-笔记
  • 从40秒到11毫秒:TiDB环境下一次SQL深潜优化实战
  • Win 11开始菜单图标变成白色怎么办?