int *p:設定一個變數 p ,p 可用來儲存 int型態變數的記憶體位址
&x: 取得 x 的記憶體位址
測試範例(環境 VS2012):
#include "stdafx.h" #include <iostream> #include <Windows.h> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { int *p; int x = 5; /* 指標測試 */ p = &x; // 將 p 指標,指到 x 的記憶體位址 cout << "x=" << x << endl; // x=5 cout << "p=" << p << endl; // p=0038FBB0 cout << "*p=" << *p << endl; // *p=5 cout << "*p+1=" << *p+1 << endl; // *p+1=6 cout << "x=" << x << endl; // x=5 /* 陣列 */ int arr[3]; cout << "sizeof(arr)=" << sizeof(arr) << endl; // sizeof(arr)=12 #int大小 4bytes x 3 = 12 cout << "arr=" << arr << endl; // arr=0038FB9C #陣列的變數值就是位址? cout << "&arr=" << &arr << endl; // &arr=0038FB9C #陣列有無用 & 取值都沒差? ZeroMemory(arr, sizeof(arr)); // 清除記憶體內容,將陣列初始值設為 0 p = arr; // 將 p 指標,指到 arr 的記憶體位址 cout << "p=" << p << endl; // p=0038FB9C cout << "&arr[0]=" << &arr[0] << endl; // &arr[0]=0038FB9C cout << "arr[1]=" << arr[1] << endl; // arr[1]=0 *p = 3; // 使用指標設定陣列第0個元素的值 *(p+1) = 10; // 使用指標設定陣列第1個元素的值 *(p+2) = 20; // 使用指標設定陣列第2個元素的值 cout << "arr[0]=" << arr[0] << endl; // arr[0]=3 cout << "arr[1]=" << arr[1] << endl; // arr[1]=10 cout << "arr[2]=" << arr[2] << endl; // arr[2]=20 /* 指標的指標 */ p = &x; // 將 p 指標,指到 x 的記憶體位址 int y = 100; int **pp; // 指標的指標 pp = &p; // 指標也能指到另一個指標的記憶體位址 cout << "pp=" << pp << endl; // pp=0038FBBC cout << "&p=" << &p << endl; // &p=0038FBBC cout << "*p=" << *p << endl; // *p=5 cout << "*pp=" << *pp << endl; // *pp=0038FBB0 # *pp = p的值 = x的記憶體位址 cout << "**pp=" << **pp << endl; // **pp=5 *pp = &y; //將 p 改指到 y 的記憶體位址 cout << "*p=" << *p << endl; // *p=100 /* 一維陣列,變數名稱當指標用 */ int arr2[5]; cout << "arr2=" << arr2 << endl; // arr2=0038FB68 *arr2 = 11; // 把陣列變數名稱當指標用? 設定第0個元素的值 cout << "arr2[0]=" << arr2[0] << endl; // arr2[0]=11 *(arr2+1) = 22; // 把陣列變數名稱當指標用? 設定第1個元素的值 cout << "arr2[1]=" << arr2[1] << endl; // arr2[1]=22 /* 二維陣列 */ int arr3[2][3]; cout << "arr3[1][2]=" << arr3[1][2] << endl; // arr3[1][2]=-858993460 cout << "sizeof(arr3)=" << sizeof(arr3) << endl; // sizeof(arr3)=24 #int大小 4bytes x 2 x 3 = 24 ZeroMemory(arr3, sizeof(arr3)); // 清除記憶體內容,將陣列初始值設為 0 cout << "arr3[1][2]=" << arr3[1][2] << endl; // arr3[1][2]=0 int* m = &arr3[0][0]; // 設定 m 指標,指到 arr3 第0個元素位址,即指到 arr3 位址 *(m+1*3+2) = 50; // 使用指標設定 arr3[1][2] 的值為50 (第 1*3+2 = 5 個元素) cout << "arr3[1][2]=" << arr3[1][2] << endl; // arr3[1][2]=50 cout << "&arr3[0][0] - &arr3[0][0]=" << (&arr3[0][0] - &arr3[0][0]) << endl; // &arr3[0][0] - &arr3[0][0]=0 #兩陣列元素位址相減,得到兩元素相距幾個元素 cout << "&arr3[0][1] - &arr3[0][0]=" << (&arr3[0][1] - &arr3[0][0]) << endl; // &arr3[0][1] - &arr3[0][0]=1 #兩陣列元素位址相減,得到兩元素相距幾個元素 cout << "&arr3[0][2] - &arr3[0][0]=" << (&arr3[0][2] - &arr3[0][0]) << endl; // &arr3[0][2] - &arr3[0][0]=2 #兩陣列元素位址相減,得到兩元素相距幾個元素 cout << "&arr3[1][0] - &arr3[0][0]=" << (&arr3[1][0] - &arr3[0][0]) << endl; // &arr3[1][0] - &arr3[0][0]=3 #兩陣列元素位址相減,得到兩元素相距幾個元素 cout << "&arr3[1][1] - &arr3[0][0]=" << (&arr3[1][1] - &arr3[0][0]) << endl; // &arr3[1][1] - &arr3[0][0]=4 #兩陣列元素位址相減,得到兩元素相距幾個元素 cout << "&arr3[1][2] - &arr3[0][0]=" << (&arr3[1][2] - &arr3[0][0]) << endl; // &arr3[1][2] - &arr3[0][0]=5 #兩陣列元素位址相減,得到兩元素相距幾個元素 /* int 型態指標加減 */ int z = 10; int *g = &z; cout << "z=" << z << endl; // z=10 cout << "*g=" << *g << endl; // *g=10 cout << "g=" << g << endl; // g=0038FB30 g++; // 指標改指到下一個元素的記憶體位址 cout << "g++=" << g << endl; // g++=0038FB34 #比原本 0038FB30 多了一個int元素大小 4bytes cout << "*(g++)=" << *g << endl; // *(g++)=-858993460 getchar(); return 0; }
struct 與指標
/* 結構 */ struct cc{ int aa; char bb; int *pp; // 結構裡面也能存放指標 }; struct cc mm; mm.aa = 123; mm.bb = 'h'; int x = 5; mm.pp = &x; // 將 mm.pp 指標,指到 x 的記憶體位址 cout << "mm.aa=" << mm.aa << endl; // mm.aa=123 cout << "mm.bb=" << mm.bb << endl; // mm.bb=h cout << "mm.pp=" << mm.pp << endl; // mm.pp=0038FBB0 cout << "*mm.pp=" << *mm.pp << endl; // *mm.pp=5 struct cc *pm =&mm; // 將 pm 指標,指到 mm 的記憶體位址 // 由 pm 指標存取內部元素的方法 // 方法1 cout << "(*pm).aa=" << (*pm).aa << endl; // (*pm).aa=123 cout << "(*pm).bb=" << (*pm).bb << endl; // (*pm).bb=h cout << "(*pm).pp=" << (*pm).pp << endl; // (*pm).pp=0038FBB0 // 方法2:使用"->",可由指標存取 struct 內部元素的值 cout << "pm->aa=" << pm->aa << endl; // pm->aa=123 cout << "pm->bb=" << pm->bb << endl; // pm->bb=h cout << "pm->pp=" << pm->pp << endl; // pm->pp=0038FBB0 cout << "*pm->pp=" << *pm->pp << endl; // *pm->pp=5 cout << "*(pm->pp)=" << *(pm->pp) << endl; // *(pm->pp)=5,結果同*pm->pp,因 -> 優先權比 * 大
char 型態指標
char c = 's'; char *d = &c; // char 型態的指標 cout << "c=" << c << endl; // c=s cout << "d=" << d << endl; // d=s昍昍昍昍`? # 用cout出現亂碼 printf_s("printf_s %%p d=%p \n", d); // printf_s %p d=002DF947 # 改用 printf_s %p cout << "(void *)d=" << (void *)d << endl; // (void *)d=002DF947 # 轉成 (void *) cout << "(int *)d=" << (int *)d << endl; // (int *)d=002DF947 # 轉成 (int *) cout << "*d=" << *d << endl; // *d=s
string 與指標
char *pstr = "sxtcv"; // 將字串常數"直接指定"給字元指標 printf_s("printf_s %%p pstr=%p \n", pstr); // printf_s %p pstr=00B6EE7C cout << "pstr=" << pstr << endl; // pstr=sxtcv cout << "pstr+1=" << pstr+1 << endl; // pstr+1=xtcv cout << "pstr+2=" << pstr+2 << endl; // pstr+2=tcv cout << "*pstr=" << *pstr << endl; // *pstr=s cout << "*(pstr+1)=" << *(pstr+1) << endl; // *(pstr+1)=x cout << "*(pstr+2)=" << *(pstr+2) << endl; // *(pstr+2)=t cout << "(void *)pstr=" << (void *)pstr << endl; // (void *)pstr=00B6EE7C cout << "(int *)pstr=" << (int *)pstr << endl; // (int *)pstr=00B6EE7C void *pv; pv = pstr; cout << "pv=" << pv << endl; // pv=00B6EE7C cout << "*((char *)pv)=" << *((char *)pv) << endl; // *((char *)pv)=s
宣告一個陣列,陣列的元素可用來存放記憶體位址
int x=1, y=2, z=3; int* a[3]; // a是一個陣列,裡面的元素,用來儲存記憶體位址 a[0] = &x; a[1] = &y; a[2] = &z; cout << "a[0]=" << a[0] << endl; // a[0]=0018FACC cout << "a[1]=" << a[1] << endl; // a[1]=0018FAC0 cout << "a[2]=" << a[2] << endl; // a[2]=0018FAB4 cout << "*a[0]=" << *a[0] << endl; // *a[0]=1 cout << "*a[1]=" << *a[1] << endl; // *a[1]=2 cout << "*a[2]=" << *a[2] << endl; // *a[2]=3 cout << "*a=" << *a << endl; // *a=0018FACC cout << "*(a+1)=" << *(a+1) << endl; // *(a+1)=0018FAC0 cout << "*(a+2)=" << *(a+2) << endl; // *(a+2)=0018FAB4 cout << "**a=" << **a << endl; // **a=1 cout << "**(a+1)=" << **(a+1) << endl; // **(a+1)=2 cout << "**(a+2)=" << **(a+2) << endl; // **(a+2)=3
用 new 配置記憶體位址給指標
int* p; p = new int; // 配置一個 int 位址給指標 p cout << "p=" << p << endl; // p=0031E078 *p=50; cout << "p=" << p << endl; // p=0031E078 cout << "*p=" << *p << endl; // *p=50 delete p; // 刪除配置的記憶體 new int,但 p 依舊存在 cout << "p=" << p << endl; // 在VS2012中p=00008123,在Netbeans(MinGW)中 p 依舊為 0031E078 cout << "*p=" << *p << endl; // 在VS2012會出錯,在Netbeans(MinGW)中 *p 值無法預期
動態陣列(Dynamic Array):系統在 heap 配置記憶體,大小不固定,須使用者自行釋放記憶體
(靜態陣列Static Array,系統在 stack 配置記憶體,大小固定,系統會自己回收記憶體)
參考:
http://stackoverflow.com/questions/2672085/c-static-array-vs-dynamic-array
http://hatsukiakio.blogspot.tw/2009/04/c-static.html
http://www.functionx.com/cpp/Lesson14.htm
http://www.cplusplus.com/doc/tutorial/dynamic/
int* p; p = new int[3]; // p是一個指標,p 指到一個 int 動態陣列(有3個元素) p[0] = 10; p[1] = 20; p[2] = 30; cout << "p[0]=" << p[0] << endl; // p[0]=10 cout << "p[1]=" << p[1] << endl; // p[1]=20 cout << "p[2]=" << p[2] << endl; // p[2]=30 cout << "p=" << p << endl; // p=004D3090 cout << "p+1=" << p+1 << endl; // p+1=004D3094 cout << "p+2=" << p+2 << endl; // p+2=004D3098 cout << "*p=" << *p << endl; // *p=10 cout << "*(p+1)=" << *(p+1) << endl; // *(p+1)=20 cout << "*(p+2)=" << *(p+2) << endl; // *(p+2)=30 delete []p; //刪除配置的動態陣列,一定要delete,否則會Memory Leak
其他參考資料:
C 語言常見誤解/指標/表示法與轉型
C 語言常見誤解/指標/空指標與NULL
C 語言常見誤解/指標/指標運算
C和C++運算子
沒有留言:
張貼留言