第七天2017/04/14(C++对C的扩充,C++与C的区别,C++的基础知识)
生活随笔
收集整理的這篇文章主要介紹了
第七天2017/04/14(C++对C的扩充,C++与C的区别,C++的基础知识)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、C++對C的擴展
(1)命名空間(作用域):namespace在C中,只有一個全局作用域,C語言的所有的全局標識符共享同一個作用域,標識符之間可能發生命名沖突。C++中提出了命名空間的概念,命名空間將全局作用域分成不同的部分,不同命名空間中的標識符可以同名而不會發生沖突,命名空間可以相互嵌套,全局作用域也叫默認命名空間。在C++中,名稱name可以使符號常量、變量、宏、函數、結構、枚舉、類和對象等,在大規模程序設計中,以及在程序員使用各種各樣的C++庫時,這些標識符發生“命名沖突”,標準C++引入了namespace關鍵字,可以很好地控制標識符的作用域。namespace是指標識符的各種可見問題。C++標準程序庫中的所有標識符(形如:endl/cout/cin等)都被定義在一個名為std的namespace中。命名空間定義:namespace name { ... }命名空間使用:using namespace name; (2)regiter關鍵字的增強 “請求”編譯器讓局部變量a直接放在寄存器里面,速度快。 //1.在c語言中register修飾的變量不能取地址,但是在C++編譯器中可以取地址,在C++編譯器中動了手腳。 //2.C++編譯器發現程序中需要取register變量的地址時,register對變量的聲明變得無效。 //3.早期的C語言編譯器不會對代碼進行優化,因此register變量是一個很好地補充。 (3)C++中,不允許定義多個同名的全局變量。int a;int a = 0; //在C語言中編譯可以成功,但是在C++中編譯會失敗。 【總結】 C語言中多個同名的全局變量最終會被鏈接到全局數據區的同一個地址空間上。 C++直接拒絕這種二義性的行為 (3)struct類型加強 (4)C++所有變量和函數必須有類型(對類型檢查將會更加嚴格) 結論:C語言中的默認類型在C++中是不合法的。在C語言中:int f();表示返回值為int,接受任意參數的函數int f(void);表示返回值為int的無參函數在C++中:int f();和int f(void);具有相同的意義,都表示返回int的無參函數C++更加強調類型,任何程序元素都必須顯示的指明類型。 (5)C++引出bool類型 bool類型只有兩個值:1和0 bool類型占用1個字節 (6)三目運算符在C和C++中的不同:C++對三目運算符做了優化。在C中:三目運算符不可以作“左值”,它返回的是一個值(a<b?a:b) = 30; //錯誤在C++中:三目運算符可以作“左值”,C++編譯器對它動了手腳,它返回的是一個變量(但是:如果三目運算符的a、b中有一個是常量值,則不能作為左值)(a<b?a:b) = 30; //正確 做了什么手腳: *((a<b?&a:&b)) = 30; //正確 (a<b?a:200) = 30; //錯誤 【注解】當左值的條件:這段內存空間可以被寫。 (7)const關鍵字 #include<iostream> using namespace std; int main() {const int a;int const a; //二者意義相同const int *c;int const *c; //二者意義相同int *const d;const int* const e; } ===================================================== 一般的const經常用作修飾結構體形參,防止結構體指向 中的變量被修改因此,我們先介紹下結構體作為形參的下面兩種case: ===================================================== 再次復習,深入了解:結構體作為形參、結構體的指針作為形參 #include<iostream> using namespace std;struct student {int age;char name[100]; };void f1( struct student stu) //結構體作為形參 //傳入的是結構體變量,此時:相當于 “形參=實參” 的賦值操作,相當于淺拷貝 //在f1中對形參進行修改,并不會導致實參的值發生任何變化 {stu.age = 100;strcpy(stu.name,"New"); }void f2( struct student* stu) //結構體指針作為形參 //傳入的是結構體的地址,此時形參和實參指向同一個內存塊 {(*stu).age = 100;strcpy((*stu).name,"New"); }int main() {struct student s = {20, "Old"};f1(s);cout<<s.age<<"+"<<s.name<<endl; //在f1中進行修改,但是在main并不會變化f2(&s);cout<<s.age<<"+"<<s.name<<endl; //在f2中進行修改,在main中會發生變化 } ===================================================== void f2(const struct student* stu) //此時用const修飾結構體指針變量, //此時會導致編譯失敗:因為在f2函數體中對結構體的內容作了修改 {(*stu).age = 100;strcpy((*stu).name,"New"); } =====================================================下面介紹一個“奇怪的東東”:把同樣的代碼,放在C和C++程序中編譯的結果竟然不一樣!代碼如下: #include "stdio.h" int main() {const int a = 10; //a是一個只讀的常量,按照理論a應該不能被修改printf("修改之前 a = %d\n",a);//a = 100; //注:此時編譯失敗,a不能被修改!疑問:那么a就不能被修改了么? //答案:在C中,a被修改,但是在C++中a沒被修改,具體情況見下:int *p = NULL;p = (int*)&a; //把a的地址賦給p :先取a的地址(&a是const int*類型),再把const int*轉成int*類型,最后賦值給p*p = 100; //用*p對a進行間接的修改,在C中修改成功,但是在C++中修改卻失敗printf("修改之后 a = %d\n",a);getchar(); } 執行結果竟然不一樣: 在C中:修改之前 a = 10修改之后 a = 100 //發現,a竟然被修改 在C++中:修改之前 a = 10修改之后 a = 10 //發現,a竟然沒被修改(這就是C++的牛逼之處,可以更好地使const修飾的變量不被修改) 【結論】在C語言中,const是一個冒牌貨,const是一個只讀變量,可以通過地址繞過const關鍵字并且對const修飾的變量進行間接修改;但是C++卻怎么都繞不過const,const在C++中是一個常量,沒法對const修飾的變量進行修改。 【疑問1:為什么發生上面的情況呢?】在C++中,通過const修飾的東西,會變成什么樣子的呢?當寫完const int a = 10;時,會把上面的信息放在C++里面的符號表中,形如:key = valuea 10... ... 當你去用a的時候,C++編譯器會從符號表里邊拿數據,因此此處的a就是“名副其實”的“真正意義上”的常量。 【疑問2:&a能取到a的地址么?此時的*p又是多少?】 p = (int*)&a; *p = 100;答:當執行到p = (int*)&a;中的取地址&a時,此時C++編譯器會給a變量分配一個內存,并且把a的值10放在該地址中,此時p的值確實等于a的地址。在進行*p = 100;后*p的值就是100。 這樣,C++編譯器既做到了對C編譯器的兼容,又做到了對const常量。 【小知識】#define與const的作用域不同 #include "stdio.h" void f1() { #define a 10 //a在f2中可用const int b = 10; //b在f2中不可用 }void f2() {printf("a = %d",a);//printf("b = %d",b); 編譯失敗 }int main() {f1();f2(); }引用專題
【普通引用】 1、變量名的回顧變量名實質上是一段連續存儲空間的別名程序中通過變量名來申請內存空間通過變量名可以使用內存 問題1:對一段連續內存空間只能取一個別名么?答:不是,引出“引用”。 2、引用是C++中的概念,屬于C++對C的擴展 引用能起到指針的作用 可讀性更高 3、引用有內存空間么? 答:引用也有內存空間! #include <iostream> using namespace std; struct student {char &a;char &b; }; int main() {cout<<sizeof(struct student)<<endl; //答案: 8 } 為什么結果是8?引用的本質是什么呢?答:引用在C++中的內部實現是一個常量指針:type &name <-->type* const name。C++編譯器在編譯過程中使用常指針作為引用的內部實現,因此引用所占用的內存大小與指針相同。 【結論】引用在實現上,只不過是吧間接賦值成立的三個條件的后兩步合二為一:當 實參穿給形參引用的時候,只不過C++編譯器幫我們程序員手工取了一個實參地址, 傳給形參引用(常量指針)3、C++引用注意事項當函數返回值為一個引用時,若返回值為“棧變量”,則不能成為其它引用的初始值,不能作為左值使用。若返回值為“靜態變量”或“全局變量”,則可以成為其它引用的初始值,既可作為右值使用,也可以作為左值使用。總結
以上是生活随笔為你收集整理的第七天2017/04/14(C++对C的扩充,C++与C的区别,C++的基础知识)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第六天2017/04/11(2:Linu
- 下一篇: 第七天2017/04/14(引用与con