成像實驗代碼
- 宣告
- C++的知識
- 開始撰寫代碼(讀入資料)
宣告
由于實驗的老師特有的查重方式以及計算成績的方法,所以請不要直接照抄本文的代碼,
這里的代碼可能會有一些BUG,請大家注意
注:我這里的使用的是C++,VS2019 ,Graph2019,可能之后的版本會不同這里說明一下,說不定等我啥時間閑了,我寫個C#版本的,(笑)
C++的知識
這里我先簡單的說一下C++的知識,如果您是大佬請自行跳過,
這里是我對C++的理解,勿噴,
我放個鏈接
https://www.runoob.com/cplusplus/cpp-tutorial.html (這個是在網上自學C++使用網站,確實不錯)
首先:我是用的是VS,如果你使用的是VScode,你加油,我至今沒配置好VScode的C++環境(哭),
這里新建一個檔案請看清楚是不是C++,還要選擇控制臺應用(就是會自動生成Hello word的),后面會讓你輸入你專案的名字,這里我寫的是實驗但是我認為寫英文或者拼音可以防止一些Bug.


你打開軟體應該是這樣的,有這個自動生成的Hello World就行了,這里我建議你先運行一下,看看自己你的環境配置有沒有啥問題,如果你不幸出現了bug,先看看是不是自己的SDK出現了問題(這里建議上網搜搜吧),
你確認可以運行之后,
把不需要的注釋洗掉,打頭檔案(就是一堆.h檔案);
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#include <graphics.h>
#include <conio.h>
#include <iostream>
#include <cstdio>
#include <fstream>
#include <istream>
#include<string>
#include<regex>
#include<sstream>
#include <cassert>
這里是我的,好像有一些沒用上不要在意這些細節(笑),注意看上面有一個graphics.h的檔案這個是需要你個人在網上下載的,
這里我放個鏈接https://blog.csdn.net/edc370/article/details/79944550 可以參考這個去下載和配置,
C++的知識
仔細觀察這個hello world的輸出方式,
std::cout << "Hello World!\n";
這里的std:: 是命名空間建議在開頭寫在頭檔案下面,
using namespace std;
這里的<<可以理解為資料流的傳遞,如果無法理解就請先記憶吧,
這里說的都是對控制臺的輸入輸出,不是檔案(害)
cout<<"someting you want to output";
cout<<"someting you want to output"<<endl;//這個是輸出之后會自動換行的
//讀入
int x;
double y;
cin>>x;//這個是從控制臺讀入資料放到x中
cin>>y;//同理這個也是一樣的
//如果你出現cin ,cout,endl;下面有紅線你看看是不是命名空間有問題,
//試試這種方式
std::cout<<"someting you want to output"<<std::endl;
std::cin>>x;
//在這些前面加一個std::
//大致意思就是使用std命名空間中的啥啥的意思,注意后面跟的是兩個英文的冒號::
類和物件
我盡量寫的通俗一些,如果你實在不會那就不用使用這個了,直接在main花括號中寫把,
如果你想讓自己查重低點就學學這個吧,如果你用的是C但是看到了這個文章我說一下:C中沒有類這個概念,直接在main 中寫把
這里的類我簡單解釋一下:用我們之前的數電實驗來舉例,類就相當于一個模塊(NE555?),但是這里注意一下,現在的類還沒有實體化相當于這個模塊還在別人工廠的電腦中做仿真,你用之前需要先實體化,相當于你從老師那里拿到了一個可以用的模塊,之后就可以開始搭電路了,
大家都知道,模塊有各種各樣的功能,類也是一樣就是一堆功能的集合,
你可以在VS上直接生成一個類,但是這樣的話就不符合老師說的要一個檔案(害),所以我這里就沒寫了,
這里我用的是我的代碼,請不要照抄
//寫class 之后寫個{} 在class后面寫你的命名
class Read//這里的Read是我類的名稱(就是NE555這個名字)
{
//記得C系列的都需要提前命名,別matlab寫太多了忘了,
int i, j, k, s, t;
double ElecThickness;//電極厚度
int ElecNumber;//電極總數
//這里的 啥啥* 是指標如果你不會就直接寫 啥啥[]開個陣列,至于大小嘛,看后面把
double* DisBetweenAdjacentEle;//相鄰電極之間的距離
double* StepBetweenAdjacentEle;//相鄰電極劃分的步長
double* ElecPotential;//電極電位
double RadiusAperture;//電極內孔徑半徑
int GridAperture;//電極內孔徑半徑等步長劃分的網格數
double RadiusBoundary;//從電極內孔沿到封閉邊界處的徑向距離
int GridBoundary;//從電極內孔沿到封閉邊界處劃分的網格數
double IterationAccuracy;//迭代精度
int NST;//輸出列印空間電位時網格點間隔數
//注:這里的等位線可能只有一個或者多個,這里處理還是很煩的,注意
double* EOE;//要求掃描搜索等電位線的電位間隔值
//這里是檔案的指標,不能改成陣列,主要是為了讀入資料
FILE* ParameterFile;
//這里我是使用結構體去進行類之間的資料傳遞,所以我寫了這個東西,
//要是看不同這里public的話就寫一個function寫一個public:
public://這里的public :是說明這個東西可以在外部呼叫,類比就是NE555的一些功能之類的
struct data {
public://這里的public 是說明這個結構體中的東西可以被外部呼叫,
double mElecThickness;//電極厚度
int mElecNumber;//電極總數
double* mDisBetweenAdjacentEle;//相鄰電極之間的距離
double* mStepBetweenAdjacentEle;//相鄰電極劃分的步長
double* mElecPotential;//電極電位
double mRadiusAperture;//電極內孔徑半徑
int mGridAperture;//電極內孔徑半徑等步長劃分的網格數
double mRadiusBoundary;//從電極內孔沿到封閉邊界處的徑向距離
int mGridBoundary;//從電極內孔沿到封閉邊界處劃分的網格數
double mIterationAccuracy;//迭代精度
int mNST;//輸出列印空間電位時網格點間隔數
double* mEOE;//要求掃描搜索等電位線的電位間隔值
double mdov;//要求掃描等位線間隔值
};
};
之后開始學習function的使用,
//這里我臨時寫了一個類
class hhh {
public ://這就是上面那個public,不會用的話就在每一個函式前寫一個public吧,
void jj() //這個是函式,jj是名稱,void表示啥都不反回,
{
cout << "Huang WeiChen";
}
double gg() //這個是回傳一個double型別的資料,這里我就隨便寫了個1,
{
cout << "I'm yellow boss" << endl;
return 1;
}
};
這里我假設你已經寫好了你自己的class,下面就是如果使用它(就是用NE555搭個電路,笑)
int main() {
/*在你的main函式中寫*/
double kk;
hhh test;//這里就是實體化,模板: 你的類名稱 你的實體化名稱
//簡單的理解就是你把你的NE555叫小花 它有個功能(函式)叫開花(不知道NE555有沒有這個功能,笑)
// 那就這樣寫: NE555 小花
//就簡單的類比一下把,感覺和結構體比較像
/*接下來就是函式的呼叫,寫: 小花.開花();*/
kk = test.gg();//kk是回傳的值,這里是1
test.jj();
}
好了這里為止就是C++大致的內容(我認為這次撰寫需要的),
好像還有一個開空間的(笑)
記得要關閉空間,不然會出bug,但是VS好像有一個機制啥的吧會自動釋放的,但是還是建議你寫,因為不知道會發生啥bug,
這個是C開空間的方式,C++也能用,但是注意它應該是沒有初始化的,記得初始化
名稱 =(型別*)calloc(大小 ,sizeof(型別));
StepBetweenAdjacentEle = (double*)calloc(ElecNumber, sizeof(double));//
free(StepBetweenAdjacentEle);
另外一種方式:
使用new
double* StepBetweenAdjacentEle = new double[ElecNumber];
型別* 名稱 =new double[大小];
delete[] StepBetweenAdjacentEle;
開始撰寫代碼(讀入資料)
老師會給一個.dat檔案,它包含了你需要的各種資訊,可能你會對此有一定的修改,但是這里還是按照我的來(笑)
這里我就直接在main中寫了,如果你用的是class就自己改改把
首先宣告一點:這個代碼我沒跑通,我也不知道是啥情況,我的正冊好像不太行所以放這里做個例子(笑)
int main() {
int i, j, k, s, t;//這個其實寫不寫都行,但是后面定義麻煩我就直接寫了,
下面這些都是老師給的資料,自己寫好命名,給個建議如果英文不好就用拼音代替,但是別寫啥a,b,c,d的這個代碼我整個寫下來1200+行,后面真的記不清不如直接在這里就把命名搞好一點至少,你要讓你30分鐘后明白,
ps:VS有個好處就是如果你在命名后面寫注釋的話(比如下面這個 ElcThickness//電極厚度)
后面你debug時候用滑鼠去靠近EleThickness時候會自動顯示注釋(電極厚度),這個VS還是很好用的,但是還是希望你寫把命名寫好,
double ElecThickness;//電極厚度
int ElecNumber;//電極總數
double* DisBetweenAdjacentEle;//相鄰電極之間的距離
double* StepBetweenAdjacentEle;//相鄰電極劃分的步長
double* ElecPotential;//電極電位
double RadiusAperture;//電極內孔徑半徑
int GridAperture;//電極內孔徑半徑等步長劃分的網格數
double RadiusBoundary;//從電極內孔沿到封閉邊界處的徑向距離
int GridBoundary;//從電極內孔沿到封閉邊界處劃分的網格數
double IterationAccuracy;//迭代精度
int NST;//輸出列印空間電位時網格點間隔數
double* EOE;//要求掃描搜索等電位線的電位間隔值
FILE* ParameterFile;
//這里我定義一個函式,后面有
double inputTest(string temp);
//注:C++中從檔案讀入有多種方式,這個你自己上網搜搜把,
fopen_s(&ParameterFile, "E:\\Learning(School)\\光電成像原理與技術", "r+");
//注:這個判斷是否打開檔案的記得寫,不然不好debug,
if (ParameterFile == NULL)//detect the file
{
printf("Open filefailure!");
exit(1);
}
/*test*/
//
//這是另外一種方式讀入
string fileName = "E:\\Learning(School)\\1120160852.dat";
ifstream in; //ifstream讀檔案(ofstream寫檔案)
in.open(fileName);
if (!in)
{
cout << "打開檔案出錯!" << endl;
//return 1;
}
string temp;
if (getline(in, temp))
{
string str;
regex e("(.*):(.*);");
smatch m;
bool found = regex_search(temp, m, e);
string num = m[2].str();
istringstream Convert(num);
Convert >> ElecNumber;
Convert.clear();
}
if (getline(in, temp))
{
string str;
regex e("(.*):(.*);");
smatch m;
bool found = regex_search(temp, m, e);
string num = m[2].str();
istringstream Convert(num);
Convert >> ElecThickness;
Convert.clear();
}
if (getline(in, temp))
{
DisBetweenAdjacentEle = (double*)calloc(ElecNumber, sizeof(double));//分配電極距離陣列大小
fscanf_s(ParameterFile, "相鄰電極之間的距離:%lf,", &DisBetweenAdjacentEle[0]);//掃描距離陣列第一個元素
for (i = 1; i < ElecNumber - 1; i++)
{
fscanf_s(ParameterFile, "%lf,", &DisBetweenAdjacentEle[i]);
}//把第二個至倒數第二個距離元素都掃描到陣列里
cout << "hhh" << endl;
}
if (getline(in, temp))
{
StepBetweenAdjacentEle = (double*)calloc(ElecNumber, sizeof(double));//給步長陣列分配記憶體空間
fscanf_s(ParameterFile, "相鄰電極劃分的步長:%lf,", &StepBetweenAdjacentEle[0]);//掃描步長陣列第一個元素
for (i = 1; i < ElecNumber - 1; i++)
{
fscanf_s(ParameterFile, "%lf,", &StepBetweenAdjacentEle[i]);
}//把從第二個至倒數第二個步長元素掃描到陣列里
fscanf_s(ParameterFile, "%lf;\n", &StepBetweenAdjacentEle[ElecNumber - 1]);//把最后一個陣列元素掃描到陣列里
}
if (getline(in, temp)) {
ElecPotential = (double*)calloc(ElecNumber, sizeof(double));//Allocates memory space to the electronic potential array.
fscanf_s(ParameterFile, "電極電位:%lf,", &ElecPotential[0]);
for (i = 1; i < ElecNumber - 1; i++)
{
fscanf_s(ParameterFile, "%lf,", &ElecPotential[i]);
}
fscanf_s(ParameterFile, "%lf;\n", &ElecPotential[ElecNumber - 1]);//Put the last element into the array
}
if (getline(in, temp)) {
RadiusAperture = inputTest(temp);
}
if (getline(in, temp)) {
GridAperture = inputTest(temp);
}
if (getline(in, temp)) {
RadiusBoundary = inputTest(temp);
}
if (getline(in, temp)) {
GridBoundary = inputTest(temp);
}
if (getline(in, temp)) {
IterationAccuracy = inputTest(temp);
}
if (getline(in, temp)) {
NST = inputTest(temp);
}
EOE = (double*)calloc(100, sizeof(double));
//dov = 0;
i = -1;
do
{
i++;
fscanf_s(ParameterFile, "%lf;", &EOE[i]);
} while (EOE[i] != 0);
in.close();
/*到這里你都將資料讀入了,之后就用前面寫的cout去輸出吧*/
cout<<啥啥;
double inputTest(string temp);
{
string str;
regex e("(.*):(.*);");
smatch m;
bool found = regex_search(temp, m, e);
string num = m[2].str();
istringstream Convert(num);
double Result;
Convert >> Result;
Convert.clear();
return Result;
}
}
到這里為止是程式中讀入資料的部分,
希望你能跑通這部分,得到5分(害,這個分也太低了),
關于bug的部分:
注意空間的初始(memset()可以用這個,或者其他方式),釋放問題,
注意;的問題,注意中英文的問題,祝大家好運,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/287486.html
標籤:其他
