c和c++主要區別

摘選自《C++ Primer Plus》第6版ios

c和c++主要區別

根據書中的描述,進行了整理c++

一、 源代碼文件的擴展名

摘自1.4.1git

C++實現 源代碼文件的擴展名
UNIX C、cc、cxx、c
GNU C++ C、cc、cxx、cpp、c++
Digital Mars cpp、cxx
Borland C++ cpp
Watcom cpp
Microsoft Visual C++ cpp、cxx、cc
Freestyle Code Warrior cp、cpp、cc、cxx、c++

另外UNIX系統上的C程序的擴展名爲.c程序員

 

二、變量定義

摘自2.2.1編程

c語言中,全部的局部變量必須在函數或複合語句開始位置,c++沒有這個限制。數組

void main()  
{  
      int a;  //define variable a
      int b;  //define variable b
   
      a = 10;  
      printf("a=%d \n", a);  
   
      b = 11;  
      printf("b=%d \n", b); 

      {   
              int temp = 0;

              printf("test variable in processing\n");
      }   
}

註釋:安全

a、局部變量a和b位於函數開始位置,變量temp位於複合語句的開始位置。ide

b、複合語句(摘自5.1.10):使用兩個花括號來構造一條複合語句(代碼塊)。代碼塊由一對花括號和它們包含的語句組成。函數

 

三、 auto

摘自3.4.5編碼

c語言中, auto用於聲明變量爲自動變量,auto修飾符的定義裏有這麼一句「進入包含變量聲明的代碼時,變量開始存在。當程序離開這個代碼塊時,自動變量消失了。它所佔用的內存可用來作別的事情。」,從「當程序離開代碼塊時變量消失」、「內存可用來作別的事情」能夠推出auto修飾的變量是存儲在堆棧中的。而全局變量存儲在靜態存儲區中,因此用auto決不能修飾全局變量。

C++11標準引入auto類型說明符,用它就能讓編譯器替咱們去分析表達式所屬的類型

與原來那些只對應一種特定類型的說明符不一樣,auto讓編譯器經過初值來推算變量類型。顯然,auto定義的變量必需要有初始值。

auto i=0,*p=&i;         //正確,i是整數,p是整形指針

 

四、stuct

摘自4.4

在C語言中, struct類型的定義必須加上struct的前綴

struct opt {
        int len;
        int value;
};


void main()  
{  
      struct opt tmp;

      tmp.len = 1;
      tmp.value = 2;
}

而在C++中,struct能夠直接使用其類型名來定義

#include <iostream>
struct opt {
        int len;
        int value;
};

int main()
{
        opt tmp;
        tmp.len = 1;
        tmp.value = 2;

        std::cout<<tmp.len<<std::endl;
        std::cout<<tmp.value<<std::endl;

        return 0;
}

 

相比之下,C++的語法更簡潔一些。因此在用C語言編寫代碼的時候,C程序員一般是這麼來定義的struct的。在下面的代碼中,使用typedef來定義一個opt的類型

typedef struct _opt {
        int len;
        int value;
}opt;


void main()  
{  
      opt tmp;

      tmp.len = 1;
      tmp.value = 2;

}

 

五、stuct初始化

摘自4.4.2

與數組同樣,c++11也支持將列表初始化用於結構,且等號(=)是可選的:

opt tmp {1, 2};

其中不容許縮窄轉換,例如:

opt tmp {1.0, 2};

編譯報錯:

error: narrowing conversion of ‘1.0e+0’ from ‘double’ to ‘int’ inside { }

 

c語言可使用列表初始化,可是等號(=)是必須的。

opt tmp = {1,2};

 

六、枚舉的取值範圍

摘自4.6.2

c++如今經過強制類型轉換,增長了能夠賦值給枚舉變量的合法值。

每一個枚舉都有取值範圍,經過強制類型轉換,能夠將取值範圍中的任何整數賦值給枚舉變量,即便這個值不是枚舉值例如,假設bits 和myflag 的定義以下:

enum bits{ one=1,two=2,four=4,eight=8};

 bits myflag;

則下面的代碼是合法的:

myflag=bits(6);//正確,由於 6在bits的範圍

取值範圍的定義:首先,要找出上限,須要知道枚舉量的最大值。找到大於這個最大值的、最小的2的冪,將它減去1,獲得的即是取值範圍的上限。

例如對於:
 

enum bigstep{first,second = 100,third};

最大枚舉值是101,在2的冪中,比這個值大的最小的值爲128,所以取值範圍上限爲127.

要知道下限,須要知道枚舉量的最小值.若是它不小於0,則取值範圍的下限爲0.不然,採起與尋找上限方式一樣的方式,但加上負號,

例如,若是最小的枚舉量爲-6,則比它小的,2的冪最大的值爲-8,加1以後爲-7.因而,上限與下限便能算出來.

 

c語言中不能定義這樣的變量:bits myflag;

七、for循環

摘自5.1

C++11新增一種循環:基於範圍(range-based)的for循環:簡化一種常見的循環任務:對數組(或容器類,如vector和array)的每一個元素執行相同的操做.

格式以下:

for(Type VarName : Array){
    //每一個元素的值會依次賦給 VarName
}

示例:

double prices[5]={4.99, 2.33, 5.86, 6.42, 4.51};  
for (double x : prices)  
      std::cout<<x<<std::endl;

 

八、邏輯運算符的另外一種表示

摘自6.2.6

並非全部的鍵盤都提供了用做邏輯運算符的符號,標識符and、or和not都是c++保留字,這意味着不能將它們用做變量名等。它們不是關鍵字,由於它們都是已有語言特性的另外一種表示方式。另外,它們並非c語言中的保留字,但c語言程序能夠將它們用做運算符,只要在程序中包含了頭文件iso646.h.

邏輯運算符:另外一種表示方式

運算符 另外一種表示方式
&& and
|| or
! not

 

九、c++字符庫函數cctype

摘自6.3

cctype中一般包括一些經常使用函數的判斷,如某個字符是否爲大寫,用isupper()若是參數是大寫字母,函數返回true, 還有像isalnum(),若是參數是字母數字,即字母或者數字,函數返回true.

 

函數名稱   返回值

isalnum()  若是參數是字母數字,即字母或者數字,函數返回true

isalpha()   若是參數是字母,函數返回true

isblank()   若是參數是水平製表符或空格,函數返回true

iscntrl()     若是參數是控制字符,函數返回true

isdigit()     若是參數是數字(0-9),函數返回true

isgraph()   若是參數是除空格以外的打印字符,函數返回true

islower()    若是參數是小寫字母,函數返回true

isprint()      若是參數是打印字符(包括空格),函數返回true

ispunct()    若是參數是標點符號,函數返回true

isspace()   若是參數是標準空白字符,如空格、換行符、水平或垂直製表符,函數返回true

isupper()   若是參數是大寫字母,函數返回true

isxdigit()     若是參數是十六進制數字,即0-九、a-f、A-F,函數返回true

tolower()    若是參數是大寫字符,返回其小寫,不然返回該參數

toupper()   若是參數是小寫字符,返回其大寫,不然返回該參數

 

10 、wchar_t 和C++11新增類型:char16_t char32_t

摘自3.1.8

wcha_t:

wchar_t是C/C++的字符類型,是一種擴展的存儲方式,主要用在國際化程序的實現中。

wchar_t 存在的緣由:

char是八位字符類型,最多能包含256中字符,許多的外文字符集所包含的字符數目超過256個,char型不能表示。

wchar_t數據大小:

數據類型通常爲16或者32位,不一樣的C/C++庫有不一樣的規定。總之:wchar_t所能表示的字符遠遠多於char類型。

wchar_t的輸入輸出處理:

cin和cout將輸入和輸出看做是char流,所以不適合用於處理wchat類型,iostream頭文件提供了wcin 和wcout用於處理輸入輸出流另外能夠經過加上前綴L來只是寬字符常量和寬字符串。

 

char16_t和char32_t:

產生緣由:

隨着編程人員日益的熟悉Unicode,類型wchar_t顯然已經知足不了需求,在計算機系統上進行的編碼字符和字符串編碼時,僅僅使用Unicode碼點顯然是不夠的,

好比:若是在進行字符串編碼時,若是有特定長度和符號特徵的類型將頗有幫助,而類型wchar_t的長度和符號特徵隨實現而已,所以C++11新增了類型char16_t,char32_t。


char16_t:無符號類型,長16位,

char32_t無符號類型,長32位


C++11使用前綴u表示char16_t字符常量和字符串常量如:u‘L’;u「lilili」;

C++11使用前綴U表示char32_t字符常量和字符串常量如:U'L';U"lilili";


類型char16_t與/u00F6形式的通用字符名匹配,

類型char32_t與/U0000222B形式的通用字符名匹配。

前綴u和U分別指出字符字面值的類型爲char16_t和char32_t。

 

十一、函數重載

摘自8.4

C++ 容許多個函數擁有相同的名字,只要它們的參數列表不一樣就能夠,這就是函數的重載(Function Overloading)。藉助重載,一個函數名能夠有多種用途。

void test(int tmp1, int tmp2)
{

        std::cout << tmp1 <<std::endl;
        std::cout << tmp2 <<std::endl;
}

void test(double tmp1, double tmp2)
{

        std::cout << tmp1 <<std::endl;
        std::cout << tmp2 <<std::endl;
}

函數的重載的規則:

    函數名稱必須相同。
    參數列表必須不一樣(個數不一樣、類型不一樣、參數排列順序不一樣等)。
    函數的返回類型能夠相同也能夠不相同。
    僅僅返回類型不一樣不足以成爲函數的重載。

C++ 是如何作到函數重載的
C++代碼在編譯時會根據參數列表對函數進行重命名。當發生函數調用時,編譯器會根據傳入的實參去逐個匹配,以選擇對應的函數,若是匹配失敗,編譯器就會報錯,這叫作重載決議(Overload Resolution)。

 

在C語言中,不存在函數重載,緣由爲以函數名來惟一區分一個全局函數而在c++中 以函數名+參數列表來惟一區分函數。

 

十二、引用

摘自8.2

引用(reference)是c++對c語言的重要擴充。引用就是某一變量(目標)的一個別名,對引用的操做與對變量直接操做徹底同樣。其格式爲:類型 &引用變量名 = 已定義過的變量名。

引用的特色:
1. 一個變量可取多個別名。
2. 引用必須初始化。
3. 引用只能在初始化的時候引用一次 ,不能更改成轉而引用其餘變量。

總結:
1. 不要返回一個臨時變量的引用。
2. 若是返回對象出了當前函數的做用域依舊存在,則最好使用引用返回,由於這樣更高效。


* 引用和指針的區別和聯繫
1. 指針是一個實體,而引用僅是個別名;
2. 引用使用時無需解引用(*),指針須要解引用;
3. 引用只能在定義時初始化一次,以後不能改變指向其它變量(從一而終);指針變量的值可變。
4. 引用必須指向有效的變量,指針能夠爲空。
5. sizeof指針對象和引用對象的意義不同。sizeof引用獲得的是所指向的變量的大小,而sizeof指針是對象地址的大小。
6. 指針和引用自增(++)自減(--)意義不同。
7. 相對而言,引用比指針更安全。
8. 從內存分配上看:程序爲指針變量分配內存區域,而引用不須要分配內存區域。


* 相同點:二者都是地址的概念,指針指向一起內存,其內容爲所指內存的地址;引用是某塊兒內存的別名。

指針比引用更爲靈活,可是其風險也很大。使用指針時必定要檢查指針是否爲空(NULL),且空間回收後指針最好置零,以避免野指針的發生形成內存泄漏等問題。

#include <iostream>

int main()
{
        struct student{
                std::string name;
                int num;
        };

        student lily = {"andrew", 168};
        const student &ref = lily;
        student *p = &lily;


        std::cout << sizeof ref<< "= sizeof ref\n";
        std::cout << sizeof p<< "= sizeof pointer\n";
}

執行結果:

16= sizeof ref
8= sizeof pointer
相關文章
相關標籤/搜索