printk 打印的参数异常问题

本贴最后更新于 1585 天前,其中的信息可能已经时移俗易

如下一句简单的打印函数, 发现打印 b 的结果很奇怪, 不符合预期, 那可能是什么原因呢?

printk("A=%d, B=%d", a, b);

printk 属于变参函数, 那我们就从 C 语言的变参函数入手.

变参函数范例

如下一个简单的任意多个加数的求和函数函数

int sum(int num, ...) // 这里的num不是自动的, 需要调用者手动传入.
{  
    va_list argptr;  

    va_start(argptr, num); // 注释1
    for(i=1; i<num; i++) // 注释2
    {  
         arg = va_arg(argptr, int);  //注释3
         total += arg;  
    }
    va_end(argptr); //无实际意义, 只是从逻辑上表示后续不在使用argptr
    return(total);  
}
  • 注释 1:
    函数参数存储于栈中, 通过最后一个参数 num 在栈中的偏移量, 是可以找到可变参数中的第 1 个参数的位置.
  • 注释 2:
    可变参数的个数是需要手动传入的, 无法自动获得
  • 注释 3
    获取参数的值需要特别指定参数类型, 有 2 个作用
    • 获取正确的值
    • 获取下一个参数的偏移量

printk 变参实现

printk("A=%d, B=%d", a, b);
  • 通过第 1 个参数"A=%d, B=%d", printk 函数可以计算函数参数的个数(2 个 %d, 表示 2 个参数)
  • 通过 %d 的内容, 就可以知道参数的类型

这里你就可以注意到一个问题, 如果 %d 指定的类型不符合, 是否会导致错误呢? 答案是一定的, 不仅仅是影响本参数, 而且还会影响下一个的参数, 因为参数的偏移量会计算错误.

结论

错误的原因可能有二, 具体参考如下图

  1. a 的类型指定错误
  2. b 的类型指定错误

image.png

另注: printk 可用的格式字符

If variable is of Type,		use printk format specifier:
---------------------------------------------------------
		int			%d or %x
		unsigned int		%u or %x
		long			%ld or %lx
		unsigned long		%lu or %lx
		long long		%lld or %llx
		unsigned long long	%llu or %llx
		size_t			%zu or %zx
		ssize_t			%zd or %zx
		s32			%d or %x
		u32			%u or %x
		s64			%lld or %llx
		u64			%llu or %llx
  • C

    C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

    83 引用 • 165 回帖 • 61 关注
  • 变参函数
    1 引用 • 1 回帖
  • printk
    1 引用 • 1 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • someone

    很受益,记住格式输出表格,避免输出错误