为什么我们需要在C ++ printf函数中指定格式说明符中的类型?

时间:2011-09-14 05:38:20

标签: c printf string-formatting

我已经做了一些PHP,当你声明变量时,你不需要声明类型(例如.string或int)。

但是我必须调整一个非常简单的C文件,为了使打印功能正常工作,我必须为每个变量的输出包含一个类型说明符。

为什么不从变量本身自动推断出这种类型?

3 个答案:

答案 0 :(得分:2)

因为printf是C ++的C兼容性部分的一部分,其中类型检测不是那么热: - )

格式字符串中的说明符与用于该说明符的数据项之间存在脱节,例如:

printf ("String at memory %p is '%s'\n", mystr, mystr);
printf ("That character is '%c', ASCII code %d, hex %02x\n", mych, mych, mych);

如果您使用C ++流作为输出,这不是一个问题。

答案 1 :(得分:2)

C是一种非常简单的语言,我的意思是它提供了对裸机的极小抽象。基本类型附带 no 类型信息,甚至struct仅获取提供的类型信息。

因此在典型的实现中,当编译器看到

int x, y;
float z;
int x = foo(y,z);

xyz可能是一个机器字,被解释为x和`y的2s-补码整数,并且作为IEEE- z的754浮点值,没有别的

编译器执行类似

的操作
  • 使堆栈指针前进以允许返回值的空间
  • push yz进入堆栈(它的执行顺序依赖于实现)
  • push当前stack pointer+two instructions作为返回地址
  • branchfoo的入口点。

(体面的筹码提供了一些支持,让这更容易,但仍然......)

然后foo

  • 从相对于当前堆栈值的位置读取yz
  • 做任何事情
  • 将返回写入x(再次通过偏离堆栈指针找到)
  • branch返回调用例程push编辑的返回地址。

如果没有指示foo传递的参数具有什么类型(如在printf之类的变量例程中),它将不知道堆栈上的每个参数有多大(实际上是c强制每个variadac参数的大小,包含一组修正此问题的上转换规则),以及如何解释它。

另一方面,PHP在裸机上提供了复杂的抽象,并且可以(实际上必须做它所做的事情)携带一些识别信息来处理它所使用的每个值。

答案 2 :(得分:-1)

最常见的说明符是:

%d /%i是整数
%c代表字母 %s用于字符串
%f用于浮动/双重

例如:

int i = 1;
char hi[6] = "Hello"
printf("%d %s", i, hi);

会打印

1 Hello

如上所述,您可以参考http://www.cplusplus.com/reference/clibrary/cstdio/printf/