C++編程--語音特性(1)

1、基本類型

1.內置類型

C++基本內置類型有bool(1個字節)、char(1個字節)、wchar_t(2個字節)、short(2個字節)、int(4個字節)、long(4個字節)、float(4個字節)、double(8個字節)、long double(8個字節)。基本內置類型的存儲空間依機器而定。c++標準規定了每一個算術類型的最小存儲空間。ios

2.變量名

變量名,即變量的標識符,由字母、數字和下劃線組成變量名必順以字母或下劃線開頭,而且區分大小寫字母:C++的c++

的標識符都是大小寫敏感的。程序員

3.初始化

默認的全局變量有默認值,局部變量則被賦予任意值,爲安全起見,不管全局或者局部變量都要初始化。數組

4.const

const int MaxSize = 100; //定義一個常量
MaxSize = 59;//試圖修改MaxSize常量,這一句在編譯的時候就要出錯

const對象在文件默認爲局部變量,也就是說,若是你想在其它文件裏使用這個const變量,你必需在定義的時候前面加安全

//file1.cpp
extern const int MAX_COUNT = 20; //定義和初始化並聲明爲extern
//file2.cpp
extern const int MAX_COUNT; //使用MAX_COUNT常量從file1.cpp文件中

 :非const變量默認是全局變量(在頭文件中)。所以不須要在變量前面添加extern符號函數

5.引用

引用(reference)就是對象的另外一個名字。在實際程序中,引用主要用做函數的形式參數。引用必需用與該引用同類型的對象初始化,如:url

int ival = 1024;//ok
int &refval = ival;//ok
int &refVal2; //錯誤,引用必需初始化。
Int &refVal3 = 10; //錯誤,初始化必需是一個對象

前面說過,引用其實就是對象的別名,所以在對一個引用操做時,實質是在對引用的那個變量進行操做。spa

2、變量

typedef

typedef能夠用來定義類型的同義詞,如:操作系統

typedef double WAGES;
WAGES hourly;

枚舉

默認狀況下,枚舉的第一個成員賦值爲0,後面的每一個枚舉成員賦的值比前面的值大1。指針

enum Week{ Sun,Mon=5,Tue,Wed};

在Week枚舉中,Sun默認爲0,Mon = 5,Tue=6,Wed=7。

3、數組

1.數組定義和初始化

定義

int a[10];
char ch[10];
double dArray[3];

  任何數組,不管是靜態聲明的仍是動態建立的,其全部元素在內存中都是連續字節存放的,也就是說保存在一大塊連續的內存區中。

初始化

int a[4]={8,9,5,3};
int b[]={7,9,2};

  或者

int elem[3];
for(int i=0; i<3; i++)
{
  elem[i]=i+1;
}

  數組不容許直接賦值變量,所以在數組copy時要for循環數組重的每個元素。如:

int b[]=a;//這裏是不容許的

4、指針

初始化

指針進行初始化或賦值只能使用如下四種類型的值:
1)0常量表達式(請用NULL值初始化)
2)類型匹配的對象的地址
3)另外一個對象以後的下一地址
4)同類型的另外一個有效指針

int *p = 0; //把p指針初始化爲0 
int ival=2;
p = &ival;//把p初始化爲類型匹配的對象的地址
int* p2 = p; //把p2初始化爲同類型的另外一個有效指針

注意:避免使用未初始化的指針,不少運行時錯誤都源於使用了未初始化的指針。

 void*指針

C++提供了一種特殊的指針類型void*,它能夠保存任何類型對象的地址,如:

double obj = 3.24;
double *pd = &obj;
void *pv = &obj;
pv = pd;

void*指針只支持幾種有限的操做:與另外一個指針進行比較;向函數傳遞void*指針或從函數返回void*指針;給另外一個void*指針賦值。不容許使用void*指針操縱它所指向的對象。

指針和引用的比較

 使用引用(reference)和指針均可間接訪問另外一個值,但它們之間有兩個重要區別。
1)引用老是指向某個對象:定義引用時沒有初始化是錯誤的。
2)賦值行爲的差別:給引用賦值修改的是該引用所關聯的對象的值,而並非使引用與另外一個對象關聯。引用一經初始引用一經初始化,就始終指向同一個特定對象

指針的算術運算

#include <string>
#include <iostream>

using namespace std;

//main函數
void main()
{
	int a[6] = {36, 15, 345, 63, 43, 344};
	int *pStart = a;
	int *pEnd = pStart + 6;//指向該數組末端的下一單元

	//計算元素的個數
	int n = pEnd - pStart;
	//打印數組
	for(int i=0; i<n; i++)
	{
		cout << *pStart++ <<" ";
	}
	cout << endl;
}

指針和const限定符

1)指向const對象的指針

#include <string>
#include <iostream>

using namespace std;

//main函數
void main()
{
    double pi = 3.14;
    const double *cptr = &pi;
    //*cptr = 5;//指針不能改變其對象的值,所以是錯誤的
}

2)const指針

#include <string>
#include <iostream>

using namespace std;

//main函數
void main()
{
    double val = 1.4;
    double *const cptrVal = &val;
    double val2 = 2.5;

    //cptrVal = &val2;//const指針不能修改
}

5、建立動態數組

在有些狀況,編譯沒法知道數組的大小;好比:讀一個文件,這個時候咱們開多大的buf來裝數據呢?答案是不知道的。
所以咱們須要在知道一個文件的大小後,在分配一個數組來裝數據,建立動態數組就能解決這種狀況。
咱們能夠像這樣去定義,如:
int *pBuf = new int[1024];
建立動態數組,不是沒有代價的,你new了一個新的數組,卻沒有delete掉數組,那麼你就有內存泄漏的風險,所以在
不須要的時候要調用delete[] 刪除數組,如:
if(pBuf)
{
   delete[] pBuf
   pBuf = NULL;
}

6、多維數組

嚴格地說,C++中沒有多維數組,一般所指的多維數組其實就是數組的數組。
先來看看二維數組的定義和初始化,咱們來看一段代碼
int a[2][3];//數組的定義
int b[2][3] = {{0,1,2},{4,5,6}}; //數組的初始化
int c[2][3] = {0,1,2,3,4,5};//數組的初始化
上面的代碼演示了二維數組的定義和初始化
注意,咱們在使用二維數組的時候要按照「先行後列」的方式來訪問,而不是先列後行。這是由於咱們假設一個內存頁爲4096字節,而且定義一個數組b[128][1024],其
列數爲1024(即每一行的元素剛好佔用一頁),當你用「先行後列」方式時,外層循環走過每一行,正好走完一頁,沒
有發生頁面調度。當循環進入下一行時操做系統從外存調入下一頁,所以,咱們能夠知道,遍歷完後次數最多爲128次。可是你用「先列後行」方式來遍歷的話,可能在遍歷完後頁面調度交數變成了1024*128。這將大大下降效率

7、new和delete表達式

注意:
1)對分配的數組進行delete[]刪除,不能誤用成delete刪除,若是用的是delete,那麼只會刪除數組的第1個元素內存,
後面的內存就丟失了,容易形成內存泄漏。                
2)讀寫已刪除的對象。若是刪除指針後,沒有把指針置爲0,那麼就會形成野指針。
3)對同一個內存空間使用兩個delete表達式。 當第一次刪除時,對象的內存空間返還給自由存儲區,當第二次刪除時,此時自由存儲區可能會被破壞。

8、強制類型轉換

在編寫程序中,不免會遇到類型轉換,在C語言中用()括號來轉換,C++繼承了這種用法,可是它有一個明顯的一個缺陷
,就是不會進行類型檢測,不能保證知足轉換。在C++裏還提供了四種類型轉換:static_cast、const_cast、
dynamic_cast以及reinterpret_cast。咱們應該避免使用強制類型轉換,但若是必定要用的話,推薦使用C++裏的那四
種類型轉換,由於它們會執行類型檢測。

static_cast

可使用static_cast顯式地執行C++語言直接支持的轉換。當須要將一個較大的算術賦值給較小的類型時,如:
double d = 7.8;
int  n = static_cast<int>(d);

const_cast

const_cast最爲直接,是將轉換掉表達式的const性質。彷佛從理論上講,一個變量是const,那麼就應該一直是const。
然而實際上,有時候你會發現有這種狀況,好比咱們在使用第三方的庫時候,示例:
extern void fun(char* str); //第三方的函數
void f(const char *str)
{
    fun(const_cast<char*>(str));
}

dynamic_cast和reinterpret_cast

dynamic爲繼承層次結構內的類型轉換提供運行時檢測
reinterpret_cast一般爲操做數的位模式提供較低層次的從新解釋。reinterpret_cast本質上依賴於機器。爲了安全地使
用reinterpret_cast,要求程序員徹底理解所涉及的數據類型,以及編譯器實現強制類型轉換的細節 

reinterpret_cast用於指針和引用轉換,不能夠對對象自己。

相關文章
相關標籤/搜索