一、C++基础
很久不用C++,学习openFOAM之前复习一下C和C++相关的基础知识
1.1常用操作符
++,–
整型变量的自加自减,用法很多。最简单的有i++,i–。运算速度会比i=i+1更快。
此外还有 j = i++ 和 j = ++ i ,前者表示先赋值后自加,后者表示先自加后赋值。
类似的用法还有 i += 1 ,实际等价于i=i+1。A+=B等价于A = A+B
!
取反符号,没什么好说的。matlab中对应符号~
!true = false
!1 = 0
!0 = 1
12!=1 = 1
%
取模运算符,即整除后的余数A%B
等价于fortran中的mod(A,B)
& | 和 && ||
后者是逻辑运算与和或,对应fortran中的.and.
和.or.
,有0&&1=0
和1&&1=1
。
而&
是按位与,例如15
的二进制为00001111
以及127
的二进制为11111111
。那么按位与结果为15&127=0x00001111&0x11111111=0x00001111=15
(这么奇怪的运算谁会用啊。。。)
同样|
表示按位或,即15&127=0x00001111&0x11111111=0x11111111=127
使用逻辑运算时要避免使用前者发生未知错误
三元运算符?:
直接给例子说明
a=2>1?3:4
此时2>1
,所以执行左侧,即赋值a=3
1.2 openFOAM中的运算符
cin cout Info
cin>>a
cout<<b
这是C++自带的输入输出流,可对很多不同类型的变量输入输出,而openFOAM中一般使用并行运算,为了方便输出特殊定义了Info
外积、内积、双重积、差积
. *
外积、&
内积、&&
双重积、^
差积
1.3 条件,循环
if条件,注意大括号外没有逗号
if(condition) {...} else {...}
while循环
while(condition){...}
for循环,注意括号中为分号,(初始化;测试;更新)
for(i=1;i<10;i++){...}
switch选择
switch(expression)
{case1:...;
case2: ...;
default:...;}
跳出循环有三个指令, break
跳出当前循环层;continue
直接进行下一次循环,return
退出当前函数
1.4 标识符可见范围
即using namespace std
的使用,参考该链接(https://blog.csdn.net/quyafeng2011/article/details/68921750)。简单的说,C++中的函数库并非在整个代码段中都是默认可见可以任意调用的,如果没有这样声明,就需要用类似这样的方式调用
std::cout << std::hex<< 3.4<< std::endl;
声明之后,可以直接写成
cout << hex<< 3.4<< endl;
1.5 数组
基础用法如下
double a[4];
double b[]={1,2,3} ;
C++中的数组模板
#include<vector>
using namespace std;
vector<double> a(5); // 大小为 大小为55的数组,初始化为0
vector<double>b (5,1.0); //大小为5的数组,初始化为1.0
vector<double> c(b); //创建c为b一个副本
openFOAM编写的时候,C++的标准库还没有形成,所以openFOAM自行给定了一个库,和当前C++的标准库有区别。C++中的vector
类似OpenFOAM中的list
,而openFOAM中的vector
是只有三个分量的向量
1.6 子函数相关
首先给一个代码段方便说明
void swap(int &a, int &b)
{
int c = a;
a = b;
b = c;
}
int main()
{
int a = 1, b = 2;
swap(a,b);
cout<<"a="<<a<<",b="<<b<<endl;
}
几个问题,
- 首先函数名前面的返回值类型可以不写,默认为空类型
void
。 - 不同的函数可以有相同的名字,根据他们的输入值进行区分,这种技巧成为重载。
- 输入的值可以设定为默认
F(scalar a, scalar b=0);
,但默认的输入值必须在最后。
传参时,可以为swap(int a, int b)
,这是传值,swap(int &a, int &b)
为传地址,后者更好。
子函数内的值的作用域仅限当前子函数,如果子函数内想要调用全局的变量,需要使用::a
1.7 指针
给一个简单的例子
#include <iostream>
using namespace std;
int main ()
{
int var = 20; // 实际变量的声明
int *ip; // 指针变量的声明
int b
ip = &var; // 在指针变量中存储 var 的地址
b = *ip //把ip存储的地址的值取出赋给b
return 0;
}
用new
初始化的指针需要用delete
删除,而openFOAM中另外有autoPtr
创建指针,可以自动删除
1.8 类型别名的定义
在openFOAM中大量使用,这里简单提到
typedef vector<double> doubleVector;
typypedef GeometricField<scalar, fvPatchField, volMesh> volScalarField;
typedef GeometricField<vector, fvPatchField, volMesh> volVectorField;
1.9 面向对象
类的定义与使用直接给一个简单的例子
#include <iostream>
using namespace std;
class Box
{
public:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};
int main( )
{
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
double volume = 0.0; // 用于存储体积
// box 1 详述
Box1.height = 5.0;
Box1.length = 6.0;
Box1.breadth = 7.0;
// box 2 详述
Box2.height = 10.0;
Box2.length = 12.0;
Box2.breadth = 13.0;
// box 1 的体积
volume = Box1.height * Box1.length * Box1.breadth;
cout << "Box1 的体积:" << volume <<endl;
// box 2 的体积
volume = Box2.height * Box2.length * Box2.breadth;
cout << "Box2 的体积:" << volume <<endl;
return 0;
}
class
声明了类box
,用对象声明对象Box1
,直接调用方式为Box1.height
。- 对象的指针也可以类似的声明
box *Box2
,而此时调用方式为Box2->height
。 - 类内变量分
public
对类内和类外均可见protected
仅对类内的和子类可见private
仅对类内可见。
类会有一些内置函数,构造函数和析构函数比较常用,下面简单罗列
class Empty {
public:
Empty(); Empty(); // // 缺省构造函数
Empty( const Empty& ); // 复制构造函数
~Empty(); // 析构函数
Empty & operator=( const Empty& ); // 赋值运算符
Empty* operator&(); // 取址运算符
const Empty* operator&() const; // 取址运算符 const
};
- 构造函数和析构函数都是没有输入值的
这部分内容可能还需要扩充
1.10 关键字
const
表示常量,初始化方式const int a=10;
。表示变量赋初值后就不能再修改。
static
通常在函数名前表示静态函数。静态函数可以使用类名直接调用,无需构造对象。用在类内变量上表示所有对象共享。用在函数中表示函数调用者共享,即函数调用完,该变量不会释放,而是保存当前值,知道整个程序结束。静态函数的调用方式如下
aut PtoPtr<incompressible::turbulenceModel> turbulence
(
incompressible::turbulenceModel::New(U, phi, laminarTransport)
);
暂无评论内容