嵌入式開發之C++基礎學習筆記2--總結全部基礎用法

1.關於全局變量和局部變量(global & local)

#include <iostream>
using namespace std;
int a = 10;
int avar = 10;
int main()
{
int avar = 20;
::avar = 30; // 做用域運算符
  cout << "local scope avar is" << avar << endl;
cout << "global scop avar is" << ::avar << endl;

return 0;
}

2.關於const和extern變量

test1.cpp
----------------------------
#include <iostream>
using namespace std;
string username = "jellon";
extern const int maxvalue = 512;

test2.cpp
---------------------------
#include <iostream>
using namespace std;
const int bufferSize = 512;
extern string username;//use username from test1
extern const int maxvalue; // use maxvalue from test1
int main()
{
cout << "bufferSize:" << bufferSize << endl;
       /*
        與C語言中的#define做用相似
優勢:有類型限制,能夠做爲常量在出如今程序的任何地方。
例:const int bufSize = 512;
一但定義,就必須初始化而且不能再改變其值。

非const變量默認爲在其它文件中能夠訪問,即默認爲extern。
而const變量必定要聲明爲extern,才能在其餘文件中訪問
*/

cout << "username from test1.cpp :" << username << endl;

cout << "username from test1.cpp :" << maxvalue << endl;
}


3.關於reference引用&

#include <iostream>
using namespace std;


int main()
{
int ival = 1024;
int &refval = ival;
cout << "reference:" << refval << endl;
int &refval2; //error
int &refval3 = 10; //error
}

引用就是對象的另外一個名字。
引用必須用與該引用同類型的對象初始化。

4.關於typedef

用來定義類型的同義詞。
typedef <已經有的類型> <新的類型名>
#include <iostream>
using namespace std;
int main() {
typedef double wages;
typedef int exam_score;
typedef wages salary;
typedef char CH10[10];//  (數組)
}


5.關於函數

1)函數的聲明

函數聲明也稱函數模型(或函數原型)。在主調函數中,若是要調用另外一個函數,則須在本函數或本文件中的開頭將要被調用的函數事先做一聲明。聲明函數,就是告訴編譯器函數的返回類型、名稱和形參表構成,以便編譯系統對函數的調用進行檢查。
函數聲明的通常格式爲:函數類型 函數名(形式參數表);

例如:設有一函數的定義爲:
double func1(double a, int b, float c)
{
     函數體
}
正確完整的函數聲明應爲:
double func1(double x, int y, float z);
                     //末尾要加上分號

2)函數調用:

在C++中,除了主函數main由系統自動調用外,其餘函數都是由主函數直接或間接調用的。函數調用的語法格式爲:
函數名 (實際參數表);


常見的函數調用有下列兩種:
方式一:將函數調用做爲一條表達式語句使用,而不使用其返回值。若函數調用帶有返回值,則這個值將會自動丟失。
例如:max(3,5);
方式二:對於具備返回值的函數來講,把函數調用語句看做語句一部分,使用函數的返回值參與相應的運算或執行相應的操做。
例如:
int a=max(3,5); 
int a=max(3,5)+1;
cout<<max(3,5)<<endl;
if(f1(a,b) cout<<」true」<<endl;
int a=2;
a=max(max(a,3),5);

當調用一個函數時,整個調用過程分爲三步進行:
第一步是參數傳遞;
第二步是函數體執行;
第三步是返回,即返回到函數調用表達式的位置。 

3)參數傳遞:

參數傳遞稱爲「實虛結合」,即實參向形參傳遞信息,使形參具備確切地含義(即具備對應的存儲空間和初值)。這種傳遞又分爲兩種不一樣的方式,一種是按值傳遞,另外一種是地址傳遞或引用傳遞。
A.按值傳遞
#include <iostream>
using namespace std;

void swap(int, int);
int main() {
int a = 3, b = 4;
cout << "a=" << a << ",b=" <<b<<endl;
swap(a,b);
cout << "a=" << a << ",b=" << b << endl;
return 0;
}

void swap(int x, int y) {
int t = x;
x = y;
y = t;
}
運行結果:
a=3,b=4
a=3,b=4

B. 引用傳遞
#include <iostream>
using namespace std;

void swap(int *, int *);
int main() {
int a = 3, b = 4;
cout << "a=" << a << ",b=" << b << endl;
swap(a, b);
cout << "a=" << a << ",b=" << b << endl;
return 0;
}


void swap(int *x, int *y) {
int t = *x;
*x = *y;
*y = t;
}
運行結果:
a=3,b=4
a=4,b=3

4)關於函數重載:

函數名相同
參數列表不一樣
例:
int circle ( int i );
double circle ( double b);
類型的自動轉換以匹配
例子:
#include <iostream>
using namespace std;

int circle ( int i );
double circle ( double i );

int main(){
cout << circle(10) << endl;
cout << circle(32.2) << endl;
}

int circle ( int i ){
return i * 20;
}

double circle (double i){
return i / 2.0;
}

5)帶默認參數的函數:

例:long Area ( int length = 1, int width = 1)
 {
return length*width;
 }   
表示兩個參數默認值都爲1。
調用以下:
Area (3, 5);  //求長爲3,寬爲5的面積
Area (3);  //求長爲3,寬爲默認值1的面積
Area ();  //求長寬都爲默認值1時的面積


函數參數的默認值:
void fun(int a, int b, int c=100)
在調用此函數時可寫成
fun(2,4,6),還可寫成fun(2,4)。
請注意:賦予缺省值的參數必須放在形參表列中的最右端。例如:

6)內聯函數:

內聯擴展(inline expansion)簡稱爲內聯(inline),內聯函數也稱爲內嵌函數。當在一個函數的定義或聲明前加上關鍵字inline則就把該函數定義爲內聯函數,它主要是解決程序的運行效率。
計算機在執行通常函數的調用時,不管該函數多麼簡單或複雜,都要通過參數傳遞、執行函數體和返回等操做,這些操做都須要必定的時間開銷。若把一個函數定義爲內聯函數後,在程序編譯階段,編譯器就會把每次調用該函數的地方都直接替換爲該函數體中的代碼,由此省去函數的調用及相應的保存現場、參數傳遞和返回操做,從而加快整個程序的執行速度。 
例子:
#include <iostream>
using namespace std;

inline float circle(float r)
{
return 3.14*r*r;
}

#define circle(r) 3.14*r*r

int main(){
cout << circle(10) << endl;
}

6.數組的概念和聲明

數組是一段連續的內存單元
聲明:char str[10];
用下標來訪問,從0到n-1。
做爲一個地址,數組名能夠賦值給一個合適類型的指針變量。
如:char *s;
 s = str;
 s[0] = ‘z’;

7.指針運算和地址運算

1)指針的基本概念

聲明:
int *a, *b; //聲明a、b爲整形指針變量
char *r, *s; //聲明r、s爲字符型指針變量
Account *u; //聲明指針u用來存放一個Account對象

2)操做符&和*

&是取地址操做符
*是取值操做符
如:int *ap = &m[3];
給整形指針ap賦於整形數組m[3]的地址,這樣ap就指向了m[3]。
注意:&僅僅適用於存儲在內存中的數據,不可用於常量,寄存器變量或者表達


只能用指向相同類型的指針給另外一個指針賦值,而在不一樣類型的指針之間進行賦值是錯誤的。好比:
int a,b;                    
int *p1=&a,*p2=p1;          //正確
而:
int a;
int *p1=&a;
double *p2=p1;              //錯誤

3)void指針和const指針

在C++語言中,能夠聲明指向void類型的指針。指向void類型的指針稱爲void指針。此外,在聲明指針時,還能夠用關鍵字const進行修飾,用關鍵字const修飾的指針稱爲const指針。

A.void指針
C++語言容許使用空類型(void)指針,即不指定指針指向一個固定的類型,它的定義格式爲: void *p;
表示指針變量p不指向一個肯定的類型數據,它的做用僅僅是用來存放一個地址。
void指針它能夠指向任何類型的C++數據。也就是說,能夠用任何類型的指針直接給void指針賦值。不過,若是須要將void指針的值賦給其餘類型的指針,則須要進行強制類型轉換。好比:
int a; 
int *p1=&a; 
void *p2=p1;
int *p4=(int *)p2;


B.const指針
關鍵字const放在不一樣的位置表示的意義也不相同: 
關鍵字const放在指針類型前,就是聲明一個指向常量的指針。此時,在程序中不能經過指針來改變它所指向的值,可是指針自己的值能夠改變,即指針能夠指向其餘數據。 
關鍵字const放在「*」號和指針名之間,就是聲明一個指針常量(也稱常指針)。所以,指針自己的值不可改變,也即它不能再指向其餘數據,但它所指向的數據的值能夠改變。 
關鍵字const在上述兩個地方都加,則是聲明一個指向常量的指針常量,指針自己的值不可改變,它所指向的數據的值也不能經過指針改變。


4)指針運算

地址運算
也稱爲指針運算,實際上就是用指針對內存的訪問。
指針+整數,產生一個指針;
指針-整數,產生一個指針;
指針-指針,產生一個整數。
已知p1和p2指向同一個數組的元素,則下面的語句實現什麼功能:p1 += p2 – p1;

5)指針和動態分配到存儲空間

new運算符
Delete運算符
應用程序數據所佔的內存能夠分爲3類:靜態(常量)存儲區、棧、堆。在程序運行開始前就分配的存儲空間都在靜態存儲區中;局部變量分配的存儲空間在棧中;動態內存分配的存儲空間在堆中,堆也稱爲自由存儲單元。new運算符與delete運算符一塊兒使用,就能夠直接進行動態內存的申請和釋放(也稱爲建立和刪除)

6)malloc

函數malloc 的原型以下:
void * malloc(size_t size);
用malloc 申請一塊長度爲length 的整數類型的內存:
int *p = (int *) malloc(sizeof(int) * length);
兩個要點是「類型轉換」和「sizeof」。

7)free

函數free 的原型以下:
void free( void * memblock );
例:
free(p);

8)new運算符

new運算符用於申請所需的內存單元,返回指定類型的一個指針。
它的語法格式爲:指針=new 數據類型;
例如:
int *p;
p = new int;
系統自動根據int類型的空間大小開闢一個內存單元,用來保存int型數據,並將地址保存在指針p中。
例如:
int *p;
p = new int[10];
則系統爲指針p分配了整型數組的內存,數組中有10個元素

9)delete運算符

delete運算符是釋放new申請到的內存。也即,當程序中再也不須要使用運算符new建立的某個內存單元時,就必須用運算符delete來刪除它。
它的語法格式爲:
delete 指針;    //釋放非數組內存單元
delete[] 指針;  //釋放數組內存單元


10)申請和釋放

例如:對int型內存單元的申請和釋放。
int *p;
p=new int;           //申請內存單元
*p=1;
delete p;            //釋放內存單元
例如:對數組內存單元的申請和釋放。
int *p;
p=new int[10];
delete[] p; 

注意事項:

在程序中對應於每次使用運算符new,都應該相應地使用運算符delete來釋放申請的內存。而且對應於每一個運算符new,只能調用一次delete來釋放內存,不然有可能致使系統崩潰。
運算符delete必須用於先前new分配的有效指針,而不能用於未定義的其餘任何類型的指針。
C++語言保留了C語言中的兩個庫函數:malloc()與free()。這兩個函數也是實現動態內存分配做用的,其功能分別與運算符new和delete類似。可是最好不要將庫函數和運算符混合使用,不然可能致使系統崩潰

對比:

int *p1 = (int *)malloc(sizeof(int) * length); int *p2 = new int[length];
相關文章
相關標籤/搜索