1、指針概念理解
int* p 定義一個指針(推薦使用這種寫法int* ,理解上有好處)
p 指針變量;
* 間接運算符(訪問符),代表訪問該地址所指向的空間;
*p 指針所保存(指向)的地址中對應(指向)的值;
&p 獲取指針變量的內存地址(指針本身占用內存空間);
故 指針是
(1)通過間接的方式訪問內存空間(直接方式是通過變量名稱(內存空間名字)直接訪問空間);
(2)指針是一種保存變量內存地址的變量,自身也占用內存空間。
eg:
指針初始化的兩種方式
int a = 40; //指針初始化方式第一種寫法 int* p;//p是指針變量,而不是*p p = &a;//指針變量用來存放內存地址;注意,此處使用*p = &a是錯誤的定義,應該是對p(指針變量)賦值,而不是*p(指針保存的地址指向的值) //指針初始化方式第二種寫法,實質是第一種寫法的簡化方式。 int* p1 = &a; cout << " &p--對指針變量取地址--輸出指針變量的地址:" << &p << endl; cout << " *p--該指針保存的地址對應的值--輸出指針所存放的地址對應的在堆內存中的值:" << *p << "\n";
2、聲明指向int類型的指針,即指針包含的地址對應的內存單元存儲了一個整數
int* p = NULL;
3、使用 指針 存儲 由地址運算符& 獲取的地址
int age = 30; int* pa = &age; cout << "*pa = " << *pa << endl; cout << "pa = " << pa << endl; //age的內存地址 cout << "&age = " << &age << endl; cout << "指針自身的地址----&pa = " << &pa << endl; //指針自身的地址
4、const指針
int day = 30; int* const pDay = &day; //指針包含的地址是常量---常量指針 cout << pDay << endl; int hour = 24; const int* pHour = &hour; //指針指向的數據是常量---指向常量的指針 cout << pHour << endl; int h = 24; const int* const ph = &h; //指針包含的地址以及指向的值都是常量---指向常量的常量指針 cout << ph << endl;
5、 聲明指向內存塊的指針,即void指針
void 指針是一種特殊的指針,表示為“無類型指針”,由於 void 指針沒有特定的類型,因此它可以指向任何類型的數據。也就是說,任何類型的指針都可以直接賦值給 void 指針,而無需進行其他相關的強制類型轉換。
eg:
void* p1; int* p2; p1 = p2; p2 = (int* )p1;
6、野指針:
把沒有合法指向的指針稱為“野”指針。因為“野”指針隨機指向一塊空間,該空間中存儲的可能是其他程序的數據甚至是系統數據,故不能對“野”指針所指向的空間進行存取操作,否則輕者會引起程序崩潰,嚴重的可能導致整個系統崩潰。
eg:
int *pi,a; //pi未初始化,無合法指向,為“野”指針 *pi=3; //運行時錯誤!不能對”野”指針指向的空間做存入操作。該語句試圖把 3 存入“野”指針pi所指的隨機空間中,會產生運行時錯誤。 a=*pi; //運行時錯誤!不能對”野”指針指向的空間取操作。該語句試圖從“野”指針pi所指的空間中取出數據,然后賦給變量a同樣會產生運行時錯誤。
7、指針運算
eg:
int* p = 4;
p++;
指針變量 p 進行 p++,p 是一個 int 類型的指針,指向內存地址 0x10000008 處。則 p++ 將指向與 p 相鄰的下一個內存地址,由於 int 型數據占 4 個字節,因此 p++ 所指的內存地址為 1000000b。這種運算並不會改變指針變量 p 自身的地址,只是改變了它所指向的地址(存放的地址)。
8、補充:
c++指針內存空間釋放
int* pb = new int; int* pb2 = new int[4]; delete pb; delete[] pb2;
9、數組與指針:
(1)一維數組和指針
int* p,a[10] = {1,2,3,4,5};
p = a;//p指向數組a的首地址,即p=&a[0],數組名相當於數組首元素的地址a[0] //數組的訪問方式 //1、直接訪問---數組名[下標] cout << a[1] << "\n"; //2、間接訪問---*(數組名+i) cout << *(a+2) << endl;// a+2表示數組首地址向后移動2個位置,a+2相當於&a[2] //3、間接訪問--- *(指針變量) for (int i=0; i<10; i++) { cout << * p++ << endl;//++運算符的優先級要高於* }
指針數組:存儲指針的數組,int* p[5]
int a0,a1,a2,a3; int* b[5]; b[0] = &a0; b[1] = &a1; b[2] = &a2;
數組指針:指向一維數組的指針,int (*p)[5]
int c[3][4]; int (*p)[4];//定義一個數組指針,指向含4個元素的一維數組 p = c;//二維數組的首地址賦給p,即a[0],或&a[0][0]
(2)二維數組
int* p;
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
p = &a[0][0]; //通過數組下邊直接訪問 /* * 通過地址間接訪問,即*(*(a+i)j)的形式,二維數組可看成由特殊一維數組組成的一維數組,a[i]可看成一個由N列組成的一維數組, a表示a[0][0]的地址 * a[i]等價於*(a+i),表示i的首行地址,i行對應的一維數組的數組名。 * a[i]+0 <---> *(a+i)+0 <---> &a[i][0] * a[i]+j <---> *(a+i)+j <---> &a[i][j] * 地址即指針,通過間接運算符*,可以訪問內存空間,則 * *(a[i]+j) <---> *(*(a+i)+j) <---> *&a[i][j] <---> a[i][j] */ cout << "a[0][0]的地址:" << a << endl; cout << "a[0][1]的地址:" << a+1 << endl; cout << "a[1][0]的地址:" << a[1]+0 << endl; cout << *(a+1)+0 << endl; cout << &a[1][0] << endl;
10、函數與指針:
(1)指針函數,函數返回調用者某個地址即指針類型;
char* str_cat(char* c1, char* c2){ char* p1 = c1; char* p2 = c2; while (*p1!='\0'){ p1++; } *p1++=' '; while (*p2!='\0'){ *p1++=*p2++; } return c1;//返回結果為指針類型
}
(2)函數指針---指向函數的指針
int* pf (int, int);//函數的返回值為int指針類型,int* int (*pf1) (int, int);//函數指針變量pf,可以指向任意含有兩個整形參數,且返回值為整形的函數 pf = &fun; pf = fun;//可以不用取地址,一個函數標識符就代表了它的地址
調用函數指針的方式兩種方式
x = (*func)();
x = func();
非常感謝您的閱讀,如需轉載,請注明出處,本文鏈接https://www.cnblogs.com/huyangshu-fs/p/11617216.html