用php做網站要用構架嗎專業(yè)代寫文案的公司
c++(一)
- C與C++有什么區(qū)別
- 命名空間
- 使用
- 輸入輸出流
- 引用
- 指針和引用的區(qū)別
- 定義
- 拓展
- 函數重載
- 例子
- 測試
- 函數重載原理
- 參數默認值
- 什么是參數默認值
- 注意
- 在c++中如何引入c的庫
- 動態(tài)內存分配
- new、delete與malloc、free的區(qū)別?

C與C++有什么區(qū)別
<1>都是編程語言
<2>C是面向過程的,C++是面向對象的
<3>第一個字母都是相同,在C語言中只要是合法的C語言語句,在C++中都是可以使用的(C++完全兼容C)
<4>++:在C的基礎上增加了一些新的內容(新特性、關鍵字、數據類型等等)
<5>C是面向過程的編程語言;C++是面向對象的編程語言!C是注重過程的!C++注重的是結
果!!!C也有在面向對象編程,是通過結構體,但是因為C里面的結構體中只能描述屬性,不能有函數,所以面向對象編程不夠徹底,引入C++來解決這個問題!
命名空間
理解成是一個容器,可以放數據類型、函數、變量!
為了解決:在C語言中,能出現同名的函數嗎?能出現同樣的自定義的數據類型嗎? 在同一個作用域內能出現同名的變量嗎? 都不可以的!
作用:解決命名沖突,命名沖突的情況: 函數、數據類型、變量!
格式: namespace 命名空間的名字
{
函數;
數據類型;
變量
}
namespace s1
{int count = 10;struct STU_T{int sno;char name[20];};void print(){printf("s1中的count=%d\n", count);}
}
namespace s2
{int count = 10;struct STU_T{int sno;char name[20];};void print(){printf("s2中的count=%d\n", count);}
}
使用
方法1 命名空間::函數();
int main()
{//使用方法1s1::print();s2::print();printf("hello world\n");return 0;
}
方法2 將命名空間搞成全局變量,訪問時只需要變量前面加上::(域運算符)
using namespace s1; //切換到這個命名空間中===》把命名空間中的內容做成全局
int main()
{//使用方法2::print();printf("%d\n", count);//使用方法1s2::print();printf("hello world\n");return 0;
}
輸入輸出流
流: 以字節(jié)為單位, 連續(xù)不斷,方向統(tǒng)一的。
C中標準輸入輸出函數: printf()、scanf()、 putchar()、getchar()、 gets()、puts()。這些函數在C++中仍然是可以使用的!除此之外,C++中引入了新的可以做輸入輸出的方法:
//之前需要引用
#include <iostream>
using namespace std;
輸入:cin >> 變量;
輸出:cout << 變量;
引用
是一種數據類型,用來給變量起別名
弱化指針(在C中可以用指針來實現的,在C++中都可以使用引用來替換)
減少臨時空間的分配
指針和引用的區(qū)別
1. 指針可以定義后不初始化,但引用定義后必須初始化;
2. 指針定義時,需要開辟內存空間;引用和變量公用同一塊內存空間,不會重新分配內存空間;
3. 指針是存儲某個實例的地址;引用是實例的別名
4. 指針變量的值可以為空;引用沒有空引用;
5. 理論上指針級數沒有限制,但引用只有一級,不存在引用的引用,但可以有指針的指針
6. 不可以對函數的局部變量或對象以引用或者指針的方式返回
7. ++引用與++指針效果不同,對指針變量的操作會使指針指向下一個實體的地址,而不是改變所指實體的內容
8. 對指針變量使用“sizeof”得到的是指針變量的大小,對引用使用“sizeof”得到的是變量的大小
9. 指針變量作為形參時需要測試合法性進行判空,引用不需要判空
10. 指針使用時要加 “ * ”,引用可以直接使用
11. 指針是可以改變指向的; 引用是不可以改變指向的 引用比指針安全
定義
數據類型 &別名 = 變量名;
//注意:引用必須初始化,一旦初始化之后再不能給引用賦值
拓展
int a = 10;
const int &a_pt = a;
a_pt = 20;//error(不能對引用再次賦值)
const int &m = 200;// 等價于 #define m 200
函數重載
解決命名困難的問題
概念:函數功能相似,函數名相同,參數不同,與返回值類型無關的一組函數,互為重載
參數不同: 參數個數不同、參數類型不同、參數類型的順序不同
例子
#include <iostream>
using namespace std;int sum(int a, int b)
{cout << "int,int" << endl;return a + b;
}
int sum(int a, double b)
{cout << "int, double" << endl;return a + b;
}
int sum(double a, int b)
{cout << "double, double" << endl;return a + b;
}
int sum(int a)
{cout << "int" << endl;return a + 0;
}
double sum(double a, double b)
{cout << "double, double" << endl;return a + b;
}
char sum(char a, char b)
{cout << "char, char" << endl;return a + b;
}
string sum(string a, string b)
{cout << "string,string" << endl;return a + b;
}int main()
{//調用的函數名是相同的,只是傳入了不同的參數,他根據傳入的參數的類型匹配了對應的函數去執(zhí)行了cout << sum(5) << endl;cout << sum(5,6) << endl;cout << sum(5.3, 6) << endl;cout << sum(5, 6.8) << endl;cout << sum(5.3, 6.8) << endl;cout << sum('A', '\0') << endl;cout << sum("123", "abc") << endl;//如上執(zhí)行了不同的代碼塊,根據函數調用的原理,說明每一個調用函數的地方,函數地址都是不同的,也就說明// 函數名應該是不一樣的! 函數名不一樣,那是因為用的編譯器不同了! gcc / g++return 0;
}
1.函數調用原理:在調用函數的地址其實保存的是函數的地址,執(zhí)行的時候會根據函數地址到對應的內存空間,然后執(zhí)行對應的代碼塊;
2.當代碼塊執(zhí)行完之后再返回到調用函數的地址,繼續(xù)向下執(zhí)行!
測試
同一個.c文件,分別使用gcc和g++進行編譯,使用nm 可執(zhí)行文件名
gcc編譯后的結果,函數名沒有變
g++編譯后的結果, 函數名發(fā)生變化了: 根據函數名的長度、函數名、參數的個數以及參數的類型進行重命名,名字發(fā)生了變化,對應函數的地址也就不同,執(zhí)行的時候就根據不同的地址執(zhí)行不同代碼塊!
函數重載原理
使用g++編譯后,函數名根據函數名的長度、參數個數、數據類型進行了重命名,函數名變了地址也就
變了,調用時執(zhí)行的就是不同的函數體
參數默認值
簡化代碼:
函數重載:當只有參數個數不同的情況下造成的代碼冗余
什么是參數默認值
在定義/聲明的時候給形參進行初始化
int sum(int a = 0,int b = 0,int c = 0)
注意
- 寫默認參數的時候是從右至左,因為調用的時候實參給的順序是從左至右
- 沒有給默認參數傳參時,就按默認值處理
- 給默認參數傳參時,就按傳入的實參進行處理
- 二義性:函數重載有默認參數時
- 解決:保留參數個數最多的,且有默認值的函數
- 當聲明和定義同時存在時,參數默認值只能放在函數聲明中
在c++中如何引入c的庫
以靜態(tài)庫為例
使用gcc編譯
使用g++編譯
問題:使用g++編譯時函數的名稱發(fā)生了改變
解決:使用g++編譯器編譯時函數的名稱不能發(fā)生改變
問題:如何判斷是gcc還是g++編譯器
方法1:通過宏來判斷
__cplusplus
方式2:通過單個字符來測試
在c里面單個字符當做整型來用,長度是四個字節(jié)
在c++里面單個字符占一個字節(jié)
動態(tài)內存分配
在C語言中,使用malloc做動態(tài)內存分配, 使用free去做釋放!
int main()
{int* p = nullptr;p = (int *)malloc(4 * 4);if (p==nullptr){printf("malloc error\n");return -1;}else{memset(p, 0, sizeof(int)*4);*p = 100;*(p+1) = 200;*(p + 2) = 300;*(p + 3) = 400;free(p);}return 0;
}
在C++中引入新的方式來動態(tài)內存分配 new運算符開空間 delete 運算符釋放空間
語法:
一塊空間分配與釋放:
數據類型 *變量 = new 數據類型; //不初始化
delete 變量;
數據類型 *變量 = new 數據類型();//有初始化
delete 變量;
連續(xù)空間分配與釋放:
數據類型 *變量 = new 數據類型[幾塊]; //不初始化
delete [] 變量;
數據類型 *變量 = new 數據類型[元素個數]();//括號
int main()
{int* p = nullptr;//去堆區(qū)分配了4字節(jié)的內存空間p = new int;cout << *p << endl; // 隨機數----沒有初始化int* pp = nullptr;//去堆區(qū)分配了4字節(jié)的內存空間pp = new int(6);cout << *pp << endl; // 自動進行了初始化,不 傳值,默認值為0;傳了值進來,就按傳進來的值進行初始化char* ptr = new char[10]; //連續(xù)分配了10char類型的空間cout << ptr << endl;delete p; //釋放一塊空間delete [] ptr; //釋放連續(xù)空間return 0;
}
new、delete與malloc、free的區(qū)別?
-
new/delete是c++的操作符,而malloc/free是庫函數
-
new 在調用時會先為對象分配內存,再調用對象的構造函數,而malloc不會;
delete 在調用時會調用析構函數,而free不會
-
使用malloc為對象指針分配內存,要明確指定分配內存大小,而new不需要
-
new作為操作符,可以被重載,而malloc不行
-
new分配內存成功,則返回對象指針;而malloc分配成功會返回void*類型指針
-
new如果分配內存失敗會拋出bad_alloc異常;而malloc分配內存會返回NULL指針
-
new從自由存儲區(qū)為對象分配內存;malloc從堆上分配內存(自由存儲區(qū)可以在堆也可以在其他地方(比如靜態(tài)存儲區(qū)),這取決于編譯器從哪里為new的使用分配內存。)