C复数和printf

54
如何使用printf打印复数?例如,如果我有以下代码:
#include <stdio.h>
#include <complex.h>
int main(void)
{
    double complex dc1 = 3 + 2*I;
    double complex dc2 = 4 + 5*I;
    double complex result;

    result = dc1 + dc2;
    printf(" ??? \n", result);

    return 0;
}

我应该使用什么转换说明符(或其他内容)来替代“???”?

4个回答

62
printf("%f + i%f\n", creal(result), cimag(result));

我不相信C99复数类型有特定的格式说明符。


我可能错了,但是由于creal()和cimag()都返回双精度浮点数,所以格式说明符不应该只是'%f',而应该是'%lf'。 - Jon Doe
5
附加改进 - 宏响应虚部符号: #define printfc(c) printf("%f%c%fi",creal(c),(cimag(c)>=0.0f)? '+':'\0',cimag(c)) - Agnius Vasiliauskas
2
@JonDoe 没关系。printf不是scanf,f和lf都可以用于double类型。参见https://dev59.com/hXVC5IYBdhLWcg3wsTbv - ntysdd
@AgniusVasiliauskas 你知道 %c 也会输出 \0 吗?最好使用带有 ? "+" : ""%s - 12431234123412341234123

20

%+f为您选择适当的符号以表示虚部:

printf("%f%+fi\n", crealf(I), cimagf(I));

输出:

0.000000+1.000000i

注意i在末尾。


0

由于复数在内存中是作为两个实数依次存储的,所以进行

printf("%g + i%g\n", result);

虽然可以工作,但使用gcc会生成编译器警告,因为参数的类型和数量与格式不匹配。在调试时可以这样做,但在生产代码中不要这样做。


2
我认为在调试时依赖未定义的行为是一个坏主意。未定义的行为经常会导致其他微妙的错误,加剧问题。此外,一次性的调试代码很容易最终进入生产环境。 - David Brown
3
只有在平台的调用约定指定复数与两个实数以相同方式传递时,此方法才能奏效。但这并不被保证。 - Stephen Canon
2
然而,这只是用于调试的一个不错的技巧。感谢您提供的想法。 - Rhys Ulerich
目前只是使用了带有复数_Complex的编译器。为了更安全地使用连续内存,可以这样写:printf("%f%+fi\n", (double)D, *((double*)&D+1)); - dargaud

-3
使用GNU C,这个可以工作:
printf("%f %f\n", complexnum);

或者,如果您想在虚部后面打印一个“i”的后缀:
printf("%f %fi\n", complexnum);

我不认为那是真的:https://wandbox.org/permlink/h7O5hbDp0FzxKtXc 看看其他答案就会明白为什么它可能起作用。 - Bob__
2
未定义行为是未定义的。 - Antti Haapala -- Слава Україні

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接