C 及計算機基礎知識 01

2021-09-25 02:48:25 字數 4192 閱讀 9035

學習vulkan的過程中,跟著教程寫了兩千行**,都是c++的。可是工作後c++本來就沒用多少,原來的一點基礎也都忘得差不多了,所以還是要對一些基礎知識整理下,方便以後翻看。

比如vulkan中的一段**:

std::vectordevices(devicecount);

vkenumeratephysicaldevices(instance, &devicecount, devices.data());

for (const auto& device : devices)

}

auto是自動推斷變數型別的,和c#中的var差不多,這裡不多解釋。那麼加const是為什麼?因為我覺得const是定義常量用的,這裡看著device是在迴圈中要變的,為什麼加了const?

先用簡單的來替換下,把型別當成int。引出乙個問題,const int&和int const&有區別嗎?根據查到的資料,二者是寫法上的區別,使用起來沒有任何區別。且有人解釋了,引用一旦初始化了就不能改變了,相當於帶了const性質。那麼這一句解釋該如何理解呢?參考:

這篇部落格就是解釋「引用被初始化後,不能再指向其他物件」這句話的。c++中使用引用的規則:

引用被建立的同時必須初始化(指標可以任何時候初始化);

不能有null引用,引用必須與合法的儲存單元關聯(指標可以是null);

一旦引用被初始化,就不能改變引用關係,即不能再指向其他物件(指標可以隨時改變所指物件)。

看一段測試**:

int main()

執行後:

str2 = str3之後,str2的位址還是str1的位址。如果你想把這句改為&str2 = str3那麼編譯器會報錯說左邊必須是可修改的值。所以說,「引用初始化後,不能再指向其他物件」就是說str2作為str1的別名,已經對映到0x00affdfc了,不能再對映到別的位址。

這裡還沒牽扯到const呢。對於const,最簡單的理解就是它指定的值是不可變的:

const int a = 1;

a = 2;

比如這個例子,編譯會報錯的。帶了&後相當於別名,那麼:

int a = 1;

const int& b = a;

b = 2;

這裡b就是a,想要重新賦值為2也會報錯。但是呢,因為a沒用const標記,所以修改a是可以的:

int a = 1;

const int& b = a;

a = 2;

a = 3;

這裡b也會變成最後的3,實際上最開始a賦值為1的初始化也可以不用,const int& b = a;也不會報錯。這個操作相當於你單獨給引用設定了門檻,它本身不能被修改,只能被動接受原始引用者(這裡的a物件)的修改。

回到前面的vulkan**,對於之前的疑問,可以這樣解釋:

不是device這個被標記了const的引用要變,因為我們前面解釋了,引用初始化後就不能再指向其他物件了,這裡要變的只是device的內容而已。

這裡面還提到了for迴圈帶冒號進行迴圈的操作,就和python的for迴圈對列表遍歷一樣,c#中類似也有foreach。這是c++11中的新新增的語法,一般也是在裡面寫const auto& entry這樣的形式,便於迭代。

比如這段vulkan**:

vkresult createdebugutilsmessengerext(

vkinstance instance,

const vkdebugutilsmessengercreateinfoext* pcreateinfo,

const vkallocationcallbacks* pallocator,

vkdebugutilsmessengerext* pdebugmessenger) else

}vkformat findsupportedformat(const std::vector& candidates, vkimagetiling tiling,

vkformatfeatureflags features) else if (tiling == vk_image_tiling_optimal &&

(props.optimaltilingfeatures & features) == features)

}throw std::runtime_error("failed to find supported format!");

}

用到了幾種各不相同的引數傳遞方法。

先複習下c++中的三種引數傳遞方式,參考:

分別是:

按值傳遞(pass by value);

位址傳遞(pass by pointer);

引用傳遞(pass by reference);

#include #include using namespace std;

void swap(int*, int*);

int main()

void swap(int *x, int *y)

傳遞的是&a和&b,也就是a和b的位址,用的時候用*提取對應位址的值,然後交換。

如果以引用為引數,則既可以使對形參的操作能改變相應資料,又讓函式呼叫方便自然。引用傳遞在函式定義時在形參前面加上&,如下:

#include #include using namespace std;

void swap(int&, int&);

int main()

void swap(int &x, int &y)

這裡還沒牽扯到const呢。參考:

當你的引數作為輸入引數時,你總不希望你的輸入引數被修改,否則可能產生邏輯錯誤。這時可以在宣告函式時在引數前加上const關鍵字,防止在實現時意外修改函式輸入。對於使用你的**的程式設計師也可以告訴他們這個引數是輸入,而不加const關鍵字的引數也可能是輸出。例如strlen,你可以這樣宣告:

int strlen(char str);
功能上肯定沒有什麼問題,但是你想告訴使用該函式的人,引數str是乙個輸入引數,它指向的資料是不能被修改的,這也是他們期望的。他們希望有乙個保證,說該函式不會破壞你的任何資料,宣告按如下方式便可讓他們放心:

int strlen(const char str);
最後,通過另一篇部落格來總結下:

回到vulkan的**上,vkinstance instance就是按值傳遞了,const vkdebugutilsmessengercreateinfoext* pcreateinfo就是按位址傳遞了,這個就和const int& a類似,是const int* a的形式。這個就是常指標了,意思就是這個指標指向物件的內容是不能改動的,不加的話我們是可以修改這個指標指向物件的內容的。比如:

int a = 1;

int c = 2;

int* b = &a;

b = &c;

*b = 3;

這裡b可以重新指向c,還能修改它的值,這裡c也被修改為了3。但是:

int a = 1;

int c = 2;

const int* b = &a;

b = &c;

*b = 3;

這裡b是可以改為指向c的,但是不能修改*b,不過可以修改c=3從而自動讓*b的值變成了3,這點就和前面的const &類似了。

好像又回到了const的內容學習上,可以另外參考:

對const的總結很詳細,比如幾種常用方法:

常變數:const 型別說明符 變數名;

常引用:const 型別說明符 &引用名;

常物件:類名 const 物件名;

常成員函式: 類名::fun(形參) const;

常陣列: 型別說明符 const 陣列名[大小];

常指標:const 型別說明符* 指標名 ,型別說明符* const 指標名。

01 計算機基礎知識

計算機 computer 俗稱電腦,是現代一種用於高速計算的電子計算機器 特點 數值計算 邏輯計算 儲存記憶功能 總結 能夠按照程式執行 自動 高速處理資料的現代化智慧型電子 硬體 滑鼠 鍵盤 顯示器 cpu 硬碟 看的見摸的著.概念 計算機語言 computer language 指用於人與計算機...

計算機導論 計算機基礎知識01

計算機是一種能按照事先儲存的程式,自動,高速進行大量數值計算和資訊處理的現代化智慧型電子裝置 第一代 電子管計算機 第二代 電晶體計算機 第三代 中 小規模積體電路計算機 大規模和超大規模積體電路計算機 第五代 新一代計算機 1 按照計算機工作原理分類 數字計算機 模擬計算機 數字模擬計算機 2 按...

計算機基礎知識 計算機基礎知識彙總

計算機專業的那六大件 組成原理,作業系統,資料庫,編譯原理,計算機網路,資料結構,其次還得加上分布式的基礎知識,因為現在的系統都變成分布式的了。如果你是做應用層開發的,那幾門課程中的有些內容和日常工作關聯度不大,我挑那些最重要的來說一說,也算是乙個最小集合吧!1,計算機組成原理 如果你不是做作業系統...