In computer science, a pointer is a programming language data type whose value refers directly to (or "points to") another value stored elsewhere in the computer memory using its address.
簡單來說 指標變數就是指出資料存在哪個記憶體位址,也就是指標變數就是一個記憶體位置記錄器,如下圖(轉至wiki)
指標的宣告:
int a=100; int *a_ptr; a_ptr=&a; //將a 取位址放到指標 a_ptr char b=200; char *b_ptr; b_ptr=&b; //將b 取位址放到指標 b_ptr
→指標也是一個變數 所以他存的地方也有他的記憶體位址, 因此可以使用指標的指標
int a=100; int *a_ptr; int **a_ptr_ptr; a_ptr=&a; //將a 取位址放到指標 a_ptr a_ptr_ptr=&a_ptr; //將a 取位址放到指標 a_ptr
附註:"&"為取址運算子,利用他可取得變數之記憶體位址
另外" * "也有人稱為取值運算子,可取得該記憶體位址的值
在該範例 *a_ptr_ptr 就為 a_ptr 的值而 a_ptr 的值就是a的記憶體位址
**a_ptr_ptr 就為 a 的值
→當需要很多指標時可使用指標陣列
int a[10]; int *a_ptr[10]; a_ptr[0]=(a+0); //a為矩陣起始記憶體位址 a_ptr[1]=(a+1); //每+1,記憶體就前進一個資料型態的記憶體長度 ....
→ 其他指標宣告
int *ptr1, ptr2;.//只有ptr1是指標 int *ptr1, *ptr2;.//都是是指標 void *ptr1 //宣告的指標不含型別,只用來持有位址資訊,不可用*運算子提取值 const int *ptr1 //指標ptr1不可變更 //口訣配合*()[]的優先權:()[]是第一優先權左結合,而*是第二優先權右結合 //看見[]就說array[] of //看見*就說pointer to //看見變數後面的()就說function() returning char *x; // x: a pointer to char char x[3]; // x: an array[3] of char char x(); // x: a function() returning char char *x[3]; // x: an array[3] of pointer to char char (*x)[3]; // x: a pointer to array[3] of char char **x; // x: a pointer to pointer to char char *x(); // x: a function() returning pointer to char char *x()[3]; // x: a function() returning array[3] of pointer to char char (*x[])(); // x: an array[] of pointer to function() returning char char (*x())(); // x: a function() returning pointer to function() returning char char (*(*x)[])(int, int); // x: a pointer to array[] of pointer to function(int,int) returning char指標的操作:
相當於告訴程式,將值放到ptr所指向的記憶體位址
int a=100; int *a_ptr; a_ptr=&a; //將a 取位址放到指標 a_ptr *a_ptr=300;//此舉就是將300裝到a的記憶體位址→ 指標與二維陣列
char aaa[2][3]={{1,2,3},{6,7,8}}; //a本身為一個指標的指標
printf("%d\n",*(aaa+0));
printf("%d\n",**(aaa+0));//要取值兩次才能取到值
//所以若要直接以aaa指標的指標操作的話此陣列依位址由小到大為
*(*(aaa+0)+0)=1 //aaa[0][0]
*(*(aaa+0)+1)=2 //aaa[0][1]
*(*(aaa+0)+2)=3 //aaa[0][2]
*(*(aaa+1)+0)=6 //aaa[1][0]
*(*(aaa+1)+1)=7 //aaa[1][1]
*(*(aaa+1)+2)=8 //aaa[1][2]
//但若使用指標變數取aaa第一個位址,必須將陣列攤開成一維陣列
char *ptr
ptr=&aaa[0][0]; //取陣列第一個位址
//此陣列依位址由小到大為
*( ptr +0)=1 //aaa[0][0]
*( ptr +1)=2 //aaa[0][1]
*( ptr +2)=3 //aaa[0][2]
*( ptr +3)=6 //aaa[1][0]
*( ptr +4)=7 //aaa[1][1]
*( ptr +5)=8 //aaa[1][2]
函數指標:→ 函數指標
程式在執行時,函式在記憶體中也佔有一個空間,函式名稱就為指向該空間位址的參考名稱,當呼叫函式名稱時,程式就會去執行該函式名稱所指向的記憶體空間中的指令。
→ 函數指標宣告與使用
一個函式型態由傳回值型態與參數列決定,不包括函式名稱,一個函式指標可指向具有相同型態的函式,也就是具有相同傳回值型態和參數列的函式。
→ 函數指標應用例:多個指令利用指標排程
一個函式型態由傳回值型態與參數列決定,不包括函式名稱,一個函式指標可指向具有相同型態的函式,也就是具有相同傳回值型態和參數列的函式。
//宣告 int function1(int,int); int function1(int,char);//重載函式 int (*funcPtr1)(int int); int (*funcPtr2)(int char);//重載函式佔有不同的空間,必須對應到相同參數型態的函式 //使用 funcPtr1=function1;//提取function1指標 funcPtr2=function1;//前面已宣告 程式可以判斷是哪個重載函式 funcPtr1(100,2000);//執行 funcPtr1(100,200);//執行
→ 函數指標應用例:多個指令利用指標排程
void func1(void);//多個指令要執行
void func2(void);
void func3(void);
...
void(*funcPrt)(void)//函式指標
void(*funcPrt_Queue)[COMSize](void)//函式指標陣列 儲存指令隊列
//執行
if(time<=200)&&(time>0)//在第0ms~100ms執行指令
{
funcPrt=funcPrt_Queue[COMIndex]; //提取排到的函式指標
funcPrt();//執行
}
//其他函式void XXX(void)
{
...
funcPrt_Queue[QueueIndex]=func1;//func1隊列入待執行
}
void YYY(void)
{
...
funcPrt_Queue[QueueIndex]=func2;//func2隊列入待執行
}
→ 函數指標應用例:快速排序法(轉自http://caterpillar.onlyfun.net/Gossip/index.html)
sort.h
sort.cpp
main.cpp
http://caterpillar.onlyfun.net/Gossip/CppGossip/FunctionPointer.html
http://www.wretch.cc/blog/DreamYeh/721080
sort.h
typedef bool (*CMP)(int, int);//定義CMP 讓程式更好閱讀 void swap(int&, int&); bool larger(int a, int b); bool smaller(int a, int b); void sort(int*, int, CMP);//原本為void sort(int*, int, bool (*compare)(int, int));
sort.cpp
#include "sort.h";
void swap(int &a, int &b)
{
int t = a;
a = b;
b = t;
}
bool larger(int a, int b)
{
return a > b;
}
bool smaller(int a, int b)
{
return a < b;
}
void sort(int* arr, int length, bool (*compare)(int, int))
{
int flag = 1;
for(int i = 0; i < length-1 && flag == 1; i++)
{
flag = 0;
for(int j = 0; j < length-i-1; j++)
{
if(compare(arr[j+1], arr[j]))
{
swap(arr[j+1], arr[j]);
flag = 1;
}
}
}
}
main.cpp
#include "iostream"
#include "sort.h"
using namespace std;
int main()
{
int number1[] = {3, 5, 1, 6, 9};
sort(number1, 5, larger);
int number2[] = {3, 5, 1, 6, 9};
sort(number2, 5, smaller);
return 0;
}
參考:http://caterpillar.onlyfun.net/Gossip/CppGossip/FunctionPointer.html
http://www.wretch.cc/blog/DreamYeh/721080

沒有留言:
張貼留言