一天從C到C 高階篇

2021-10-10 18:44:50 字數 4034 閱讀 2540

目錄

1.檔案和流

2.異常處理

3.動態記憶體分配

4.命名空間

5.模板

6.預處理器

7.訊號處理

在標頭檔案中

開啟檔案: void open(const char *filename, ios::openmode mode); 其中開啟模式如下:

模式標誌

描述追加模式。所有寫入都追加到檔案末尾。

ios::ate

檔案開啟後定位到檔案末尾。

ios::in

開啟檔案用於讀取。

ios::out

開啟檔案用於寫入。

ios::trunc

如果該檔案已經存在,其內容將在開啟檔案之前被截斷,即把檔案長度設為 0。

關閉檔案:  void close();

寫入檔案 :  <<

讀取檔案:   >>

#include #include using namespace std;

int main ()

檔案位置指標:

// 定位到 fileobject 的第 n 個位元組(假設是 ios::beg)

fileobject.seekg( n );

// 把檔案的讀指標從 fileobject 當前位置向後移 n 個位元組

fileobject.seekg( n, ios::cur );

// 把檔案的讀指標從 fileobject 末尾往回移 n 個位元組

fileobject.seekg( n, ios::end );

// 定位到 fileobject 的末尾

fileobject.seekg( 0, ios::end );

如果try塊在不同的情境下會丟擲不同的異常,這個時候可以嘗試羅列多個catch語句,用於捕獲不同型別的異常。

try

catch( exceptionname e1 )

catch( exceptionname e2 )

catch( exceptionname en )

c++標準異常:

記憶體的申請和釋放分別為new和delete。

需要注意陣列的記憶體的申請方式:

一維陣列:

// 動態分配,陣列長度為 m

int *array=new int [m];

//釋放記憶體

delete array;

二維陣列:

int **array

// 假定陣列第一維長度為 m, 第二維長度為 n

// 動態分配空間

array = new int *[m];

for( int i=0; i三維陣列的話就再套一層!

物件的記憶體分配

#include using namespace std;

class box

命名空間可以不連續,如果命名空間中的某個組成部分需要請求定義在另乙個檔案中的名稱,則仍然需要宣告該名稱。也就是說只要命名空間的名字相同就是在同乙個命名空間,多次宣告就相當於在之前的中新增。比如上面這個命名空間定義可以是定義乙個新的命名空間,也可以是為已有的命名空間增加新的元素。

此外,命名空間可以巢狀;

namespace namespace_name1 

}

也可以這樣巢狀:

// 訪問 namespace_name2 中的成員

using namespace namespace_name1::namespace_name2;

// 訪問 namespace:name1 中的成員

using namespace namespace_name1;

巢狀之後,宣告外部的命名空間的時候,也就自然包含了內部的命名空間。

模板是一種對型別進行引數化的工具;通常有兩種形式:函式模板和類模板;

函式模板 針對僅引數型別不同的函式;類模板 針對僅資料成員和成員函式型別不同的類。

使用模板的目的就是能夠讓程式設計師編寫與型別無關的**。

預處理以井號(#)開頭,比如 #include、#define、#if、#else、#line 等,是指編譯器在實際編譯之前所需完成的預處理。

需要知道條件編譯

#ifdef   #ifndef  #endif 等等

此外,#可以當做運算子使用

# 字串化的意思,出現在巨集定義中的#是把跟在後面的引數轉換成乙個字串。

## 連線符號,把引數連在一起。將多個 token 連線成乙個 token。

#include using namespace std;

#define mkstr( x ) #x

#define concat(a, b) a ## b

int main()

c++中還有一些預定義巨集(c裡也有),這些預定義巨集在除錯的時候很有用。因為他們列印出**比較詳細的資訊,常用來列印log。

__line__

這會在程式編譯時包含當前行號。

__file__

這會在程式編譯時包含當前檔名。

__date__

這會包含乙個形式為 month/day/year 的字串,它表示把原始檔轉換為目標**的日期。

__time__

這會包含乙個形式為 hour:minute:second 的字串,它表示程式被編譯的時間。

#include using namespace std;

int main()

訊號是一種軟體中斷,一種向程序傳遞有關其他程序,作業系統和硬體狀態的資訊的方法。訊號是一種中斷,因為它可以改變程式的流程。當訊號傳遞給程序時,程序將停止其執行的操作,處理或忽略訊號,或者在某些情況下終止,取決於訊號。

如果學過微控制器,就很容易理解這裡說的訊號,其實就是和中斷請求類似。無論要捕獲什麼訊號,都必須使用signal函式來註冊訊號,並將其與訊號處理程式相關聯。語法如下:

void (*signal (int sig, void (*func)(int)))(int);
包含兩個引數,乙個是訊號編號(有巨集定義的,下邊),另乙個是訊號處理函式的指標(訊號處理函式的名字就行)。

常見訊號(編號)巨集定義如下:

訊號描述

sigabrt

程式的異常終止,如呼叫abort

sigfpe

錯誤的算術運算,比如除以零或導致溢位的操作。

sigill

檢測非法指令。

sigint

程式終止(interrupt)訊號。

sigse**

非法訪問記憶體。

sigterm

傳送到程式的終止請求。

可以使用函式raise()生成訊號,該函式帶有乙個整數訊號編號作為引數。下面的**用來捕獲sigint訊號,並在三次迴圈之後生成乙個sigint訊號來讓其捕獲。也可以不用raise來生成訊號,手動ctrl+c也可以生成sigint訊號。

#include #include #include using namespace std;

void signalhandler(int signum)

int main()

sleep(1);

}return 0;

}

學習平台:菜鳥教程

從C語言到C (一)

1.輸入輸出流 using std cout 標準輸出流 using std endl 換行 cout em1.t a cout endl 2.結構體的宣告 在c 裡,不需要加struct 3.類的定義 類名稱前面加c,類成員前面加m 如果不加關鍵字public和 預設為 private 即如果你在...

C 修煉篇 01 從C到C 的公升級

引言 本文意在完成一場從c到c 世界的平滑過渡,因此要求讀者應具備一定的c語言基礎功底。文章嚮導 一 c與c 的關係c與c 的關係並不能簡單地概括為僅多了兩個 號而已,兩者實際上既有區別又有聯絡,且並無所謂的何者好壞之說。簡單說來,c 其實是一種更好的c語言,只不過兩者適用場景並不相同。由上圖可知,...

C 伴每一天

2015 11 5 今天葉子木學到的東東是關於引用家族的,不多說,直奔主題,go。1 函式呼叫語句 string result string input result version input 2 函式定義 string version const string s1,const string s...