回顧一下,容易忘記的c++的一些需要注意,而往往會忽視的點。
標識符
C++ 標識符內不允許出現標點字符,比如 @、$ 和 %。C++ 是區分大小寫的編程語言。
標識符以字母 A-Z 或 a-z 或下劃線 _ 開始,後跟零個或多個字母、下劃線和數字(0-9)。
下面代碼會輸出電腦上各種數據類型的大小。
#include <iostream>
using namespace std;
int main()
{
cout << "Size of char : " << sizeof(char) << endl;
cout << "Size of int : " << sizeof(int) << endl;
cout << "Size of short int : " << sizeof(short int) << endl;
cout << "Size of long int : " << sizeof(long int) << endl;
cout << "Size of float : " << sizeof(float) << endl;
cout << "Size of double : " << sizeof(double) << endl;
cout << "Size of wchar_t : " << sizeof(wchar_t) << endl;
return 0;
}
我的計算機上面輸出的結果如下,不同計算機結果可能不同。
Size of char : 1
Size of int : 4
Size of short int : 2
Size of long int : 8
Size of float : 4
Size of double : 8
Size of wchar_t : 4
枚舉類型
枚舉類型(enumeration)是C++中的一種派生數據類型,它是由用戶定義的若干枚舉常量的集合。
如果一個變量只有幾種可能的值,可以定義爲枚舉(enumeration)類型。所謂”枚舉”是指將變量的值一一列舉出來,變量的值只能在列舉出來的值的範圍內。
例如,下面的代碼定義了一個顏色枚舉,變量 c 的類型爲 color。最後,c 被賦值爲 “blue”。
enum color { red, green=5, blue } c;
c = blue;
默認情況下,第一個名稱的值爲 0,第二個名稱的值爲 1,第三個名稱的值爲 2,以此類推。也可以給名稱賦予一個特殊的值,只需要添加一個初始值即可,如上面blue=6,默認情況下,每個名稱都會比它前面一個名稱大 1。
變量
在程序中,局部變量和全局變量的名稱可以相同,但是在函數內,局部變量的值會覆蓋全局變量的值。
當局部變量被定義時,系統不會對其初始化,須自行對其初始化。定義全局變量時,系統會自動初始化。
常量
- 如果常量以 L(僅當大寫時)開頭,則表示它是一個寬字符常量(例如 L’x’),此時它必須存儲在 wchar_t
類型的變量中。否則,它就是一個窄字符常量(例如 ‘x’),此時它可以存儲在 char 類型的簡單變量中。 - 定義成 const 後的常量,程序對其中只能讀不能修改。
C++ 允許使用速記符號來聲明無符號短整數或無符號長整數。可以不寫 int,只寫單詞 unsigned、short 或 unsigned、long,int 是隱含的。
存儲類定義
1. auto :從 C++ 11 開始,auto 關鍵字不再是 C++ 存儲類說明符,且 register 關鍵字被棄用。 自 C++ 11 以來,auto 關鍵字用於兩種情況:聲明變量時根據初始化表達式自動推斷該變量的類型、聲明函數時函數返回值的佔位符。
2. register 存儲類用於定義存儲在寄存器中而不是 RAM 中的局部變量。這意味着變量的最大尺寸等於寄存器的大小(通常是一個詞),且不能對它應用一元的 ‘&’ 運算符(因爲它沒有內存位置)。寄存器只用於需要快速訪問的變量,比如計數器。還應注意的是,定義 ‘register’ 並不意味着變量將被存儲在寄存器中,它意味着變量可能存儲在寄存器中,這取決於硬件和實現的限制。
3. static 存儲類指示編譯器在程序的生命週期內保持局部變量的存在,(局部->函數內,全局->文件內)
4. extern 是用來在另一個文件中聲明一個全局變量或函數
5. mutable 說明符僅適用於類的對象,允許對象的成員替代常量。也就是說,mutable 成員可以通過 const 成員函數修改
6. thread_local 說明符聲明的變量僅可在它在其上創建的線程上訪問,可以與 static 或 extern 合併。 thread_local 僅應用於數據聲明和定義,thread_local 不能用於函數聲明或定義。
#include< iostream.h> 和 #include< iostream>的區別
#include< iostream.h> 中不存在類 std,但是他有 cin,out 的相關函數,不需要使用命名空間了。
而第二種標準 #include< iostream>,它包含了一個類,在類的使用之前要預處理一下,using namespace std; 然後你就可以使用 cin,cout 這兩個成員函數了,假設你不使用預處理 using namespace std;,就要加上 std::cin 或者 std::cout再去使用它的成員函數(頭文件中存在這個類)
運算符
在函數聲明中,參數的名稱並不重要,只有參數的類型是必需的。
數學中的常用函數
C++ 隨機數
在許多情況下,需要生成隨機數。關於隨機數生成器,有兩個相關的函數。一個是 rand(),該函數只返回一個僞隨機數。生成隨機數之前必須先調用 srand() 函數。
下面是一個關於生成隨機數的簡單實例。實例中使用了 time() 函數來獲取系統時間的秒數,通過調用 rand() 函數來生成隨機數:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main ()
{
int i,j;
// 設置種子
srand( (unsigned)time( NULL ) );
/* 生成 10 個隨機數 */
for( i = 0; i < 10; i++ )
{
// 生成實際的隨機數
j= rand();
cout <<"隨機數: " << j << endl;
}
return 0;
}
思考:rand()生成的隨機數,大小和位數能不設定?
數組
#include <iostream>
using namespace std;
#include <iomanip>
using std::setw;
int main ()
{
int n[ 10 ]; // n 是一個包含 10 個整數的數組
// 初始化數組元素
for ( int i = 0; i < 10; i++ )
{
n[ i ] = i + 100; // 設置元素 i 爲 i + 100
}
cout << "Element" << setw( 13 ) << "Value" << endl; //setw() 函數來格式化輸出
// 輸出數組中每個元素的值
for ( int j = 0; j < 10; j++ )
{
cout << setw( 7 )<< j << setw( 13 ) << n[ j ] << endl;
}
return 0;
}
結果:
Element Value
0 100
1 101
2 102
3 103
4 104
5 105
6 106
7 107
8 108
9 109
Array 是固定大小的,不能額外增加元素.當我們想定義不固定大小的字符時,可以使用 vector(向量) 標準庫。
#include <iostream>
#include <vector>
using namespace std;
int main() {
// 創建向量用於存儲整型數據
vector<int> vec;
int i;
// 顯示 vec 初始大小
cout << "vector size = " << vec.size() << endl;
// 向向量 vec 追加 5 個整數值
for(i = 0; i < 5; i++){
vec.push_back(i);
}
// 顯示追加後 vec 的大小
cout << "extended vector size = " << vec.size() << endl;
return 0;
}
vec的大小隨着 for 循環的輸入而增大。
執行以上代碼,輸出結果:
vector size = 0
extended vector size = 5
C++ 中有大量的字符串函數:(這些字符串是以 null 結尾的)
C++ 標準庫也提供了 string 類類型(面向對象),可以不用char str[]來初始化,而是用 string str。如下所示:
#include <iostream>
#include <cstring>
using namespace std;
int main ()
{
char str1[11] = "Hello";
char str2[11] = "World";
char str3[11];
int len ;
// 複製 str1 到 str3
strcpy( str3, str1);
cout << "strcpy( str3, str1) : " << str3 << endl;
// 連接 str1 和 str2
strcat( str1, str2);
cout << "strcat( str1, str2): " << str1 << endl;
// 連接後,str1 的總長度
len = strlen(str1);
cout << "strlen(str1) : " << len << endl;
return 0;
}
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str1 = "Hello";
string str2 = "World";
string str3;
int len ;
// 複製 str1 到 str3
str3 = str1;
cout << "str3 : " << str3 << endl;
// 連接 str1 和 str2
str3 = str1 + str2;
cout << "str1 + str2 : " << str3 << endl;
// 連接後,str3 的總長度
len = str3.size();
cout << "str3.size() : " << len << endl;
return 0;
}
c++輸入輸出流
除了cin和cout,我們來認識一下cerr和clog.
- 預定義的對象 cerr 是 ostream 類的一個實例。cerr 對象附屬到標準錯誤設備,通常也是顯示屏,但是 cerr
對象是非緩衝的,且每個流插入到 cerr 都會立即輸出。cerr 也是與流插入運算符 << 結合使用的,如下所示:
#include <iostream>
using namespace std;
int main( )
{
char str[] = "Unable to read....";
cerr << "Error message : " << str << endl;
}
當上面的代碼被編譯和執行時,它會產生下列結果:
Error message : Unable to read....
2.預定義的對象 clog 是 ostream 類的一個實例。clog 對象附屬到標準錯誤設備,通常也是顯示屏,但是 clog 對象是緩衝的。這意味着每個流插入到 clog 都會先存儲在緩衝區,直到緩衝填滿或者緩衝區刷新時纔會輸出。
clog 也是與流插入運算符 << 結合使用的,如下所示:
#include <iostream>
using namespace std;
int main( )
{
char str[] = "Unable to read....";
clog << "Error message : " << str << endl;
}
當上面的代碼被編譯和執行時,它會產生下列結果:
Error message : Unable to read....
訪問結構成員,我們使用成員訪問運算符(.),如:
cout << "第一本書標題 : " << Book1.title <<endl;
指針—指向結構的指針
定義指向結構的指針,方式與定義指向其他類型變量的指針相似,如下所示:
struct Books *struct_pointer;
現在,可以在上述定義的指針變量中存儲結構變量的地址。爲了查找結構變量的地址,請把 & 運算符放在結構名稱的前面,如下所示:
struct_pointer = &Book1;
爲了使用指向該結構的指針訪問結構的成員,您必須使用 -> 運算符,如下所示:
struct_pointer->title;
如下結構體和指向結構體的指針兩個實例所示:
#include <iostream>
#include <cstring>
using namespace std;
void printBook( struct Books book );
// 聲明一個結構體類型 Books
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定義結構體類型 Books 的變量 Book1
Books Book2; // 定義結構體類型 Books 的變量 Book2
// Book1 詳述
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "ABC");
strcpy( Book1.subject, "編程語言");
Book1.book_id = 12345;
// Book2 詳述
strcpy( Book2.title, "C 教程");
strcpy( Book2.author, "ABC");
strcpy( Book2.subject, "後臺語言");
Book2.book_id = 12346;
// 輸出 Book1 信息
printBook( Book1 );
// 輸出 Book2 信息
printBook( Book2 );
return 0;
}
void printBook( struct Books book )
{
cout << "書標題 : " << book.title <<endl;
cout << "書作者 : " << book.author <<endl;
cout << "書類目 : " << book.subject <<endl;
cout << "書 ID : " << book.book_id <<endl;
}
#include <iostream>
#include <cstring>
using namespace std;
void printBook( struct Books *book );
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定義結構體類型 Books 的變量 Book1
Books Book2; // 定義結構體類型 Books 的變量 Book2
// Book1 詳述
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "ABC");
strcpy( Book1.subject, "編程語言");
Book1.book_id = 12345;
// Book2 詳述
strcpy( Book2.title, "C 教程");
strcpy( Book2.author, "ABC");
strcpy( Book2.subject, "後臺語言");
Book2.book_id = 12346;
// 通過傳 Book1 的地址來輸出 Book1 信息
printBook( &Book1 );
// 通過傳 Book2 的地址來輸出 Book2 信息
printBook( &Book2 );
return 0;
}
// 該函數以結構指針作爲參數
void printBook( struct Books *book )
{
cout << "書標題 : " << book->title <<endl;
cout << "書作者 : " << book->author <<endl;
cout << "書類目 : " << book->subject <<endl;
cout << "書 ID : " << book->book_id <<endl;
}