openFOAM學習筆記(一)—— C++基礎

一、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=01&&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)
);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章