一個指針曾經指向一個已知對象,在對象的內存空間釋放後,雖然該指針還是原來的內存地址,但指針所指已經是未知對象,稱爲「迷途指針」。ios
兩個指針相減運算:p一、p2是相同類型的兩個指針(常量或變量),則p2-p1的結果爲兩個指針之間對象的個數,若是p2的地址值大於p1結果爲正,不然爲負。c++
int x[5], *p1 = &x[0], *p2 = &x[4]; cout << p2 - p1; //4
①const int p;
②const int* p;
③int const* p;編程
④int * const p;數組
⑤const int * const p;模塊化
⑥int const * const p;函數
第一種是常量整數,沒什麼好說的。工具
後面五種是指針,有一個簡便的辦法記憶。spa
從右往左讀,遇到p就替換成「p is a 」遇到*就替換成「point to」。設計
好比說②,讀做:p is a point to int const.指針
p是一個指向整型常量的指針。
③讀做:p is a point to const int.
意思跟②相同。
④讀做:p is a const point to int.
p是一個常量指針,指向整型。
⑤讀做:p is a const point to int const.
⑥讀做:p is a const point to const int.
⑤和⑥的意思相同,p都是常量指針,指向整型常量。
做者:李鵬
連接:https://www.zhihu.com/question/19829354/answer/44950608
來源:知乎
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
②③ const 指向類型 *指針變量 (不容許經過指針來改變所指向的const對象的值,p不是隻讀的,*p是隻讀的;不能把一個const對象的地址賦給非const對象的指針,但容許把一個非const對象的地址賦給一個const對象的指針,不能經過*p改變a的值,但能夠經過a直接改a的值。)
實際編程中,指向const的指針經常使用做函數的形參,以此確保傳遞給函數的實參對象在函數中不被修改。
void fun(const int *p) { ... } int main() { int a; fun(&a); }
④⑤ const指針
指向類型 * const 指針變量;( 一個指針變量能夠是隻讀的,稱爲const指針)
int const *pc = &a;
pc是指向int型對象的const指針,不能使pc再被賦值指向其餘對象。任何企圖給const指針賦值的操做都會致使編譯錯誤,但能夠經過*p間接引用修改該對象的值。
⑥指向const對象的const指針 const 指向類型 *const 指針變量;
c++規定,數組名即表明數組自己,又表明整個數組的地址,仍是數組首元素的地址值,即a與第0個元素的地址&a[0]相同。
數組名是一個指針常量(pointer to const),於是它不能出如今左值和某些算術運算中。
c++容許定義一個字符指針,初始化時指向一個字符串常量,通常形式爲:char *p="C Language"; 初始化時,p儲存了這個字符串首地址4000,而不是字符串常量自己,稱p指向字符串。
char str[] = "C language", *p = str; cout << p << endl; // C language cout << str << endl; // C language cout << p + 2 << endl; // language cout << str[7] << endl; // a cout << &str[7] << endl; // age cout << *(p + 7) << endl; // a
char str[] = "C language", *p = str; while (*p != '\0') cout << *p++;
指針最重要的應用是做爲函數參數,它使得被調函數除了返回值以外,可以將更多的運算結果返回到主調函數中。指針是函數參數傳遞的重要工具。
經過將指針做爲函數參數的方法,既能夠返回多個運算結果,又避免了使用全局變量。
自定義函數實現strcpy_s函數的字符串複製功能
#include<iostream> using namespace std; char *stringcopy(char *str1, const char *str2) { char *p1 = str1; const char *p2 = str2; while (*p2 != '\0') *p1 = *p2, p1++, p2++; *p1 = '\0'; return str1; } int main() { char s1[100], s2[100], s3[100] = "string="; cin >> s1; stringcopy(s2, s1); cout << "s2=" << s2 << endl; stringcopy(&s3[7], s1); cout << s3 << endl; system("pause"); return 0; }
注:數組名是一個指針常量,因此函數要返回一個指針(char *stri...)
經過對象名稱直接訪問對象,優勢是直觀,操做哪一個對象一目瞭然,肯定是一個函數內部不能使用另外一個函數的局部變量。
經過指針(或地址)間接訪問對象,優勢是無所不能,缺點是程序中大量出現的間接訪問,實在分不清具體是哪一個對象,須要經過上下文去分析。
C++擴充了C語言對象訪問方式,提供了引用訪問。經過引用訪問對象,結合了按名訪問和按地址訪問各自的優勢,很是適合做爲函數參數。
在C++中,引用所有是const類型,聲明以後不可更改(即不能再是別的對象的引用)。聲明一個引用類型變量是,必須同時初始化它,聲明它是哪一個對象的別名,即綁定對象。
函數返回指針 即 函數返回地址。
函數返回引用與函數返回值有重大區別,它不是返回一個臨時對象,而是返回實體對象自己,所以,函數返回引用能夠做爲左值。
函數是實現特定功能的程序代碼的集合,實際上,函數代碼在內存中也要佔據一段存儲空間(代碼區內),這段存儲空間的起始地址稱爲函數入口地址。C++規定函數入口地址爲函數的指針,即函數名既表明函數,又是函數的指針(或地址)。
C++容許定義指向函數的指針變量,定義形式爲:
返回類型 (*函數指針變量名) (形式參數列表);
int max(int a, int b); int(*p)(int a, int b); p = max;
經過函數指針調用函數
對函數指針間接引用是經過函數指針調用函數,通常形式爲:函數指針(實參列表);
c = p(a, b); //等價於c=max(a,b);
指向函數的指針多用於指向不一樣的函數,從而能夠利用指針變量調用不一樣函數,至關於將函數調用又靜態方式(固定的調用指定函數)變爲動態方式(調用哪一個函數是由指針值來肯定)。熟練掌握函數指針的應用,有利於程序的模塊化設計,提升程序的可擴展性。
#include<iostream> using namespace std; double integral(double a,double b,double (*f)(double x)){ int n = 1000; double h,x,s=0; h = (b - a) / 1000; for (int i = 1; i <= n; i++) { x = a + (i - 1)*h; s += (f(x) + f(x + h))*h / 2; } return s; } double f1(double x){ return x + 1; } double f2(double x) { return exp(-x*x / 2); } double f3(double x) { return x*x*x; } int main(){ double a, b; cin >> a >> b; cout << (integral(a, b, f1) + integral(a, b, f2) + integral(a, b, f3)); system("pause"); return 0; }