将c++与c语言混编转成纯c++

因为导师最近给发了一个c语言和c++混编的程序,打开出现了很多错误,但本人对c语言的语法不太熟悉,所以在老师帮忙下(将c语言转成c++)调通后,自己又调了一遍,总结了一下改的东西

1.首先在c++中定义c语言函数的话,因为C++ 编译器会对函数名进行修饰(添加参数类型信息),而 C 编译器不会。所以需要
​使用 extern "C" 告诉 C++ 编译器:​
“此函数/变量需按 C 语言的规则生成符号,不要进行名称修饰”。具体语法如下:

#ifdef __cplusplus
extern "C" {  // 告诉 C++ 编译器以下函数按 C 规则链接
#endif

void c_print(const char* msg); // 声明 C 函数

#ifdef __cplusplus
}
#endif

因为我现在要将c语言转成c++,所以直接将带有这一部分的代码注释掉,再将里面的函数声明改成c++的形式即可。

2.c语言在使用复数类型的变量时,C++内置了std::complex模板类,而C语言在C99标准中引入了复数支持,但两者的语法和用法有所不同。在C++中是std::complex<double>,而C语言中则是double complex类型。所以需要注意以下几点

头文件和命名空间​​:

  • C++需要包含<complex>头文件,并且使用std::complex,可能需要命名空间。
  • C语言需要包含<complex.h>,并且使用double complex类型,函数名可能带有下划线,比如crealcimag

类型声明和初始化​​:

  • C++中使用std::complex<double> z(1.0, 2.0);来初始化。
  • C语言中使用double complex z = 1.0 + 2.0 * I;,其中I是虚数单位。

访问实部和虚部​​:

  • C++中使用real(z)imag(z)成员函数,或者std::real(z)std::imag(z)
  • C语言中使用creal(z)cimag(z)函数。​

数学运算和函数​​:

  • C++可以使用运算符重载,如+-*/等直接操作复数。
  • C语言需要使用复数特定的函数,如conjcexp等,这些函数可能需要包含特定头文件。

兼容性和标准差异​​:

  • C++的std::complex支持更多的运算符和运算,而C语言的复数函数较为基础。
  • C++11之后支持constexpr和更高级的特性,而C语言的复数功能较为有限。

具体语法如下

cpp

// C++
#include <complex>
std::complex<double> z(1.0, 2.0);
double real_part = std::real(z);

c

// C
#include <complex.h>
double complex z = 1.0 + 2.0 * I;
double real_part = creal(z);

3.代码中有以下两行代码

#  define Inf numeric_limits<double>::infinity()
#  define NaN numeric_limits<double>::quiet_NaN()

在后面使用到Inf时一直报错,然后将其改成就能正常运行了

const double Inf = numeric_limits<double>::infinity();

const double NaN = numeric_limits<double>::quiet_NaN();

主要原因在于:

#define 和 const 的区别

  • #define 是一个预处理指令,它会在编译之前进行宏替换。宏并不会像常规的变量那样进行类型检查或者作用域检查。也就是说,它会直接用给定的表达式替换代码中的每个 InfNaN,没有类型安全和作用域限制。它是一种简单的文本替换。

  • const 则是声明一个常量,编译器会进行类型检查,并且会在编译时为该常量分配内存地址。const 常量是类型安全的,并且具有作用域。

为什么 #define 可能会导致错误

#define Inf numeric_limits<double>::infinity() 这样做会让预处理器在代码中每次看到 Inf 时都将其替换成 numeric_limits<double>::infinity(),而这可能会导致一些问题。具体原因如下:

  • 类型不匹配或作用域问题numeric_limits<double>::infinity() 返回的是一个 double 类型的常量,但是 #define 并不关心这个常量的类型,它只是简单的做文本替换。当你在代码中使用 Inf 时,编译器无法知道它是一个 double 类型的常量,有时可能会因为上下文的不同导致类型不匹配的错误,尤其是当你在不期望的地方使用 Inf 时(比如在不需要 double 类型的地方)。

  • 代码可读性和调试问题:宏替换并不会产生变量,它不会在调试时显示出变量的名字和类型,给代码的可维护性带来困难,特别是当错误信息中没有明确的标识符时。

为什么 const double 不会报错

当你使用 const double Inf = std::numeric_limits<double>::infinity(); 时,Inf 被声明为一个具有明确类型 (double) 的常量。编译器会根据 std::numeric_limits<double>::infinity() 的返回值的类型(double)来进行类型检查,并且保证常量 Inf 在整个作用域内有效。const 常量不会引起宏替换的问题,它会保留类型信息,且具有作用域限制,这样可以避免类型冲突和其他潜在的错误。

4.因为我的代码中还包含

#  define FADDEEVA(name) Faddeeva::name
#  define FADDEEVA_RE(name) Faddeeva::name

意思是

  • 这个宏将 FADDEEVA(name) 替换为 Faddeeva::name
  • 它将 Faddeeva::name 中的 name 替换为具体的函数或变量名。Faddeeva 可能是一个命名空间或者是一个类名,name 代表具体的函数或类成员。这个宏的作用是简化代码,直接通过 FADDEEVA(name) 来访问 Faddeeva 命名空间或类中的内容。

所以在将c语言改成c++时,如果这部分函数是使用c语言进行声明的,需要将其改成c++的命名空间或者相应的类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值