【问题标题】:C - how does passing space-separated strings to a single parameter work? [duplicate]C - 将空格分隔的字符串传递给单个参数如何工作? [复制]
【发布时间】:2019-03-09 19:31:23
【问题描述】:

这可能是 C 编程中一个非常简单且核心的组件,但很难找到

内核中的printk 可以采用许多日志级别的常量,并且函数本身使用可变参数,但是我不知道它为什么起作用。这是给不熟悉的人的示例调用

printk(KERN_DEBUG "this is my message which can be %s as normal", "formatted");

源代码如下,它使用可变参数,但是什么机制允许将多个以空格分隔的字符串传递给一个参数?

asmlinkage __visible int printk(const char *fmt, ...)
{
        va_list args;
        int r;

        va_start(args, fmt);
        r = vprintk_func(fmt, args);
        va_end(args);

        return r;
}

这不是 printk 特有的,我在创建设备时看到它在内核的驱动程序中使用

device_create(drv_class, 
                      NULL,    
                      dev, 
                      NULL,      
                      MY_DEVICE_NAME "%d", i); 

谁能告诉我是什么允许这样做?它是特定于编译器的还是语言的核心部分?

【问题讨论】:

    标签: c char


    【解决方案1】:
    printf("hello World\n");
    // or equivalent
    printf("h" "e" "l" "l" "o" " " "W" "o" "r" "l" "d" "\n");
    // or equivalent
    #define char_h "h"
    printf(char_h "ello World\n");
    

    字符串文字被连接在一起。这意味着,"ab""a" "b" 是相同的。空终止字符仅添加在末尾。

    预处理器只替换。所以#define KERN_DEBUG "<7>" 只是让预处理器用KERN_DEBUG 替换"<7>"

    然后在预处理器之后连接两个字符串文字。例如,printf(KERN_DEBUG "..."); 变为 printf("<7>" "...");,然后将字符串文字连接成 printf("<7>...");

    【讨论】:

      【解决方案2】:

      这只是在编译时连接字符串文字的 C 语言功能。 "foo" "bar" 等价于 "foobar"。将长字符串放入代码中非常方便,但也可以与宏扩展一起使用。考虑:

      #define FOO "foo"
      int i;
      printf(FOO "%d", i);
      

      这只是将"FOO" "%d" 传递给printf,由于宏扩展和字符串常量的C 语言规则,这相当于"FOO%d"

      【讨论】:

      • 我是否遗漏了第一个示例中的某些内容,或者您​​是否遗漏了 KERN_DEBUG?我认为它们是完全相同的机制。我只是表明它可以使用带有 % 的可变参数在每个 printf 中工作
      • 哦,我错过了!谢谢,这让我的回答非常更简单。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-25
      • 1970-01-01
      • 2017-09-04
      • 1970-01-01
      • 2023-03-12
      • 2015-01-28
      • 2018-09-02
      相关资源
      最近更新 更多