使用%d或%i进行类型转换后打印会产生意外的输出

时间:2015-07-31 23:00:25

标签: c arrays string casting printf

我将一些值四舍五入然后打印出来。当我使用%f选项时,它们被正确打印,但是使用%d或%i选项(即使将舍入值转换为int)也会产生奇怪的输出,我无法弄清楚它的原因。

非常感谢任何帮助!

当我使用%f:

i = 0;

while(i < n_shapes)
{
    ll_x[i] = (int)round((ll_x[i] - min_x)/pitch_x);
    ll_y[i] = (int)round((ll_y[i] - min_y)/pitch_y);
    ur_x[i] = (int)round((ur_x[i] - min_x)/pitch_x);
    ur_y[i] = (int)round((ur_y[i] - min_y)/pitch_y);
    printf("%f,%f,%f,%f\n", ll_x[i], ll_y[i], ur_x[i], ur_y[i]);
    i++;
}

输出:

115.000000,94.000000,115.000000,101.000000
116.000000,51.000000,117.000000,58.000000
116.000000,60.000000,117.000000,67.000000
116.000000,69.000000,117.000000,75.000000
116.000000,77.000000,117.000000,84.000000
116.000000,86.000000,117.000000,93.000000
116.000000,94.000000,117.000000,101.000000

现在,使用%d(或%i):

i = 0;

while(i < n_shapes)
{
    ll_x[i] = (int)round((ll_x[i] - min_x)/pitch_x);
    ll_y[i] = (int)round((ll_y[i] - min_y)/pitch_y);
    ur_x[i] = (int)round((ur_x[i] - min_x)/pitch_x);
    ur_y[i] = (int)round((ur_y[i] - min_y)/pitch_y);
    printf("%d,%d,%d,%d\n", ll_x[i], ll_y[i], ur_x[i], ur_y[i]);
    i++;
}

输出:

1079590912,0,6,-1
1078788096,0,5,-1
1079033856,0,6,-1
1079164928,0,6,-1
1079312384,0,6,-1
1079459840,0,6,-1
1079590912,0,6,-1

谢谢!

编辑:是的,我意识到在printf中使用(int)给了我正确的输出。我很好奇我没有这样做的价值观。当我使用%d而不在printf中进行转换时,我的输出是什么意思?

2 个答案:

答案 0 :(得分:3)

这是未定义的行为。您需要使用正确的类型说明符。

printf无法验证传递给它以进行打印的参数类型是否与其对应的格式说明符匹配。编译器在传递这些参数之前执行特定于类型的转换,因此printf期望每个%f如果找到doublefloat转换为double同样)并且对于每个%d,它会找到int。您的代码为double说明符传递%d转换后的值,这会导致未定义的行为。

请注意,在分配给floatdouble变量之前,将intfloat表达式转换为double并不会更改数字的表示形式。它所做的就是截断小数部分。表示保持不变。换句话说,如果你这样做

double x = 12.345;
double y = (int)x;

相同
double x = 12.345;
double y = (double)((int)x);

因为在这种情况下编译器知道变量y的类型,并为您插入缺失的强制转换。

答案 1 :(得分:0)

要了解gcc的第一件事是您需要明确地启用警告并使用-Wall -Wextra -Werror使其出错。如果你不完全正确的话,这些会警告你许多有用的东西。

包括格式字符串和错误的参数类型。

我想默认情况下没有启用这些警告选项的原因是,旧的完美工作的K&amp; R代码现在会产生警告并扰乱一些令人尊敬的黑客。