当我使用带有%s和%c的printf时,为什么打印的char会改变?

时间:2015-03-16 12:17:08

标签: c printf format-specifiers

这是我的代码:

int main(){
    char *p = "koraytugay";
    printf("%s%i byte(s).\n",   "Size of variable p:"       ,sizeof(p));
    printf("%s%i byte(s).\n\n", "Size of what p points to:" ,sizeof(*p));

    char t[] = "koraytugay";
    printf("%s%i byte(s).\n",   "Size of variable t:"       ,sizeof(t));
    printf("%s%i byte(s).\n\n", "Size of what t points to:" ,sizeof(*t));

    printf("%s%c\n",    "Printing p[3]: ",  p[3]);
    printf("%s%c\n",    "Printing t[3]: ",  t[3]);

    printf("%s",*(&p));

}

我得到的输出是:

Size of variable p:8 byte(s).
Size of what p points to:1 byte(s).

Size of variable t:11 byte(s).
Size of what t points to:1 byte(s).

Printing p[3]: a
Printing t[3]: a
koraytugay

当我将最后一个语句更改为:

printf("%c",*(&p));

打印的最后一行是:

6

而不是

koraytugay

但为什么呢?我期待它会打印

k

2 个答案:

答案 0 :(得分:9)

%c格式说明符需要类型为char的argumnet。

在您的代码中,*(&p)的类型为char *。使用%c进行打印会导致undefined behaviour

参考:从第7.21.6.1章,C11标准,第9段,

  

如果转换规范无效,则行为未定义。如果任何参数不是相应转换规范的正确类型,则行为未定义。

答案 1 :(得分:5)

它没有打印k因为它期待char并且您通过char *所以可能

printf("%c", **(&p));

将打印k

&p的类型为char **,因为它会创建一个地址为p的指针,因此*(&p)p完全相同,因此要打印*(&p),您需要"%s"说明符。

如果您将"%c"说明符与*(&p)一起使用,则将其评估为整数,这样您就无法预测要打印的内容,因为它取决于什么是值存储在指针中。