print变参

笔记 同时被 2 个专栏收录
17 篇文章 0 订阅
42 篇文章 0 订阅


本文是基于韦东山视频的学习笔记

pintf格式

参考printf函数
int printf(const char *format,…)

  • “*format”为固定参数
  • “…”为可变参数

在这里插入图片描述

可变参数

固定参数便是传入的字符串,而重点在于怎么传递可变参数

我们知道,在x86平台,函数调用时参数传递是使用堆栈来实现的,上图。

比如如下代码

struct Stu {
	char* name;
	int num1;
	char c;
	int num2
}
void MyPrintf(char* format, ...)
{
	...
}
int main()
{
	...
	MyPrintf("abcd", 123, Stu, 'c', 10.12);
}

其中,main函数中的format是定参,后面的123是可变参数1,Stu是可变参数2,c是可变参数3,10.12是可变参数4,在堆栈中如下分布。

这里是引用

可变参数的取值

参数指针从format开始传入,如果想指向可变参数1,就指针+4即可,如此类推,有以下代码辅助实现:

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )	//这一句实现取参、指针移向下一个变参
#define va_end(ap)      ( ap = (va_list)0 )	

字节对齐

值得注意的是,在这个gcc 编译都是4字节对齐,包括结构体的字符类型。如果想取消对齐,用__attribute__ ((packed)) 修饰即可,如:

struct  person{
	char *name;
	int  age;
	char score;
	int  id;
}__attribute__ ((packed));

还可以指定对齐,如下

struct  person{
	char *name;
	int  age;
	char score;
	int  id;
}__attribute((aligned (4)));

/usr/include/features.h:367:25: fatal error: sys/cdefs.h: No such file or directory
解决Ubuntu编译error:fatal error: sys/cdefs.h: No such file or directory–InWho
Some packages could not be authenticated
E: Some packages could not be authenticated–Simon_CB_Zhao

vc6.0 中的 stdarg.h
#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )	//4字节对齐
//#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_arg(ap,t)    ( *(t *)( ap=ap + _INTSIZEOF(t), ap- _INTSIZEOF(t)) )	//移动指针 & 取值
#define va_end(ap)      ( ap = (va_list)0 )	//ap = (char *)(0)
  • 0
    点赞
  • 1
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值