一、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)
);