我可以在printf中传递一个预期整数的字符吗?

时间:2012-07-11 11:51:24

标签: c++ c variadic-functions

以下代码是否正确?

char mychar = 200;
printf("%x", mychar);

根据http://www.cplusplus.com/reference/clibrary/cstdio/printf/ %x需要一个整数(我的编译器为4个字节),我只传递1个字节。由于printf使用了varargs,我担心这只会因为堆栈上的字节对齐而起作用(即,当在堆栈上按下时,char总是使用4个字节)。

我认为最好写一下:

char mychar = 200;
printf("%x", static_cast<int>(mychar));

你认为第一个代码是否安全?如果不是,如果我切换到bigendian架构,你认为我能得到不同的输出吗?

4 个答案:

答案 0 :(得分:25)

在您的示例中,参数实际上是int类型。由于默认参数促销mychar被提升为int

  

(C99,6.5.2.2p6)“如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并将具有float类型的参数提升为double。 这些被称为默认参数促销。

和(强调我的):

  

(C99,6.5.2.2p7)“如果表示被调用函数的表达式具有包含原型的类型,则将参数隐式转换为类型,就像通过赋值一样相应参数的类型,将每个参数的类型作为其声明类型的非限定版本。函数原型声明符中的省略号表示法导致参数类型转换在最后声明的参数之后停止。默认参数   促销是在尾随参数上进行的。“

请注意,从技术上讲,x转换说明符需要unsigned int个参数,但intunsigned int类型保证具有相同的表示形式。

答案 1 :(得分:3)

这仅适用于您,因为您的平台能够将int(促销char)解释为unsigned,这是%x所期望的。为了确保这始终有效,您应该使用适当的格式说明符,即%d

由于您似乎希望使用char作为数字数量,因此最好使用两种替代类型signed charunsigned char来明确您的意图。 char可以是您平台功能的签名或未签名类型。 unsigned char的正确说明符为%hhx

答案 2 :(得分:0)

如果您正在使用C ++,那么您可能希望改用流。

您需要将字符转换为整数,否则它们将打印为字形。此外,签名字符将在演员表期间进行符号扩展,因此最好使用unsigned char。例如,一个持有0xFF的字符将打印为0xFFFFFFFF,除非先将其转换为unsigned char。

#include <iostream>
#include <iomanip>

int main(void){

    char c = 0xFF;
    std::cout << std::hex << std::setw(2) << std::setfill('0');
    std::cout << static_cast<int>(static_cast<unsigned char>(c)) << std::endl;

    return 0;
}

答案 3 :(得分:0)

只需使用printf("%hhx", mychar)即可。请不要使用cplusplus.com作为参考。这个问题只证明了它包含许多错误并遗漏了大量信息的声誉。