以下代码在C中编译并运行得很好(至少根据'gcc -std = gnu99'),但它无法在C ++下编译,给出“第5行:错误:无法将'double'转换为'double初始化中的复杂'。有人知道为什么吗?
#include "/usr/include/complex.h"
#include <stdio.h>
int main(int argc, char * argv[]) {
double complex a = 3; // ERROR ON THIS LINE
printf("%lf\n", creal(a));
return 0;
}
我意识到在C ++中有另一种复杂数字的方法,但我必须在C ++中使用C复数,因为这就是我给出的遗留代码所做的事情。谢谢,如果你能帮忙的话!
答案 0 :(得分:17)
C ++编译器可以选择支持_Complex
关键字作为扩展(以及一些),但这不是可移植的。如果你想拥有一个可移植的C ++解决方案,不幸的是你需要使用C ++ std :: complex模板。
好消息是C ++ std :: complex数字保证与C复数相兼容(从某种意义上说,指向一个的指针总是可以转换为指向另一个的指针,并且会发生正确的事情) ,这意味着如果您需要与需要C复杂值的C库进行互操作,那么您将不会遇到任何麻烦。
C11:
每个复杂类型具有与包含相应实数类型的两个元素的数组类型相同的表示和对齐要求;第一个元素等于复数的实部和虚部的第二个元素。
C ++ 11:
如果
z
是cvstd::complex<T>
类型的左值表达式,那么:- 表达式
reinterpret_cast<cv T(&)[2]>(z)
应格式正确,-
reinterpret_cast<cv T(&)[2]>(z)[0]
应指定z
的实部和-
reinterpret_cast<cv T(&)[2]>(z)[1]
应指定z
的虚部。
答案 1 :(得分:9)
C ++中不支持多次添加C99或与C ++功能冲突,例如可变参数宏,复合文字,指定初始值设定项,可变长度数组和本机复数类型。 C99中定义的long long int数据类型和restrict限定符不包含在当前的C ++标准中,但是一些编译器(如GNU Compiler Collection [4])将它们作为扩展提供。可以实现可变参数宏的一些功能的长long数据类型和可变参数模板存在于新的C ++标准C ++ 11中。另一方面,C99通过结合使用诸如//注释和混合声明以及代码之类的C ++特性来减少其他一些不兼容性。
答案 2 :(得分:9)
对复杂使用C关键字:_Complex。 C ++使用complex作为(模板)类。 我不确定creal在哪里,或者我会取消注释。
#include <complex.h>
#include <cstdio>
int main(int argc, char * argv[]) {
double _Complex a = 3.0 + 0.0I; // DECLARATION WORKS NOW - NOTE ASSIGNMENT MUST HAVE IMAG PART
//printf("%lf\n", creal(a));
return 0;
}
这适用于gcc(我用g ++编译)。我收到了关于弃用的.h标题的警告。
Here是指向电子邮件路径的链接,显示与C ++和C的复杂数字的非标准兼容性。 C ++ 11要求C ++复合体与C _Complexes的布局兼容性。
我目前正在研究C ++中的creal等。我没有在标准中找到任何东西。由于似乎需要一些努力来提供C ++和C之间的某些源兼容性,然后creal,cpow等可能会为TR2提供一个很好的补充库提案。