C++——指针2
指向指針的指針是一種多級間接尋址的形式,或者說是一個指針鏈。通常,一個指針包含一個變量的地址。當我們定義一個指向指針的指針時,第一個指針包含了第二個指針的地址,第二個指針指向包含實際值的位置。
一個指向指針的指針變量必須如下聲明,即在變量名前放置兩個星號。例如,下面聲明了一個指向 int 類型指針的指針:
int **var #include <iostream.h>int main () {int var;int *ptr;int **pptr;var = 100;// 獲取 var 的地址ptr = &var;// 使用運算符 & 獲取 ptr 的地址pptr = &ptr;// 使用 pptr 獲取值cout << "var 值為 :" << var << endl;cout << "*ptr 值為:" << *ptr << endl;cout << "**pptr 值為:" << **pptr << endl;cout << "&var 為 :"<< &var <<endl ;cout << "ptr 為 :"<< ptr <<endl ;cout << "&ptr 為 :"<< &ptr <<endl ;cout << "pptr 為 :"<< pptr <<endl ;cout << "&ptr 為 :"<< &pptr <<endl ;return 0; }/* 運行結果為 var 值為 :3000 *ptr 值為:3000 **pptr 值為:3000 var 地址為 :0x0019FF3C ptr 地址為 :0x0019FF3C ptr 地址為 :0x0019FF38 */?
C++ 傳遞指針給函數,只需要簡單地聲明函數參數為指針類型即可。在函數內部,*ptr是得到傳入指針,原本指向地址的值。
#include <iostream>using namespace std;void Fun_Num(unsigned int *par);int main () {unsigned int num;cout<<"輸入一個數字";cin>>num ;Fun_Num(&num);// 輸出實際值cout << "The num is :" << num << endl;return 0; }void Fun_Num(unsigned int *par) {*par = *par + 1; }/*輸出結果為 輸入一個數字99 The num is :100 */以前我們說過,數組名字代表的是指向該數組的常量指針,所以我們同樣可以傳入數組給函數。
#include <iostream>using namespace std ;double Get_Balance(int *ptr , int size );void main() {int data[5] = {1,2,3,4,5};double balance = 0 ;balance = Get_Balance(data,5);cout << "Ths balance value is :" << balance <<endl ; }double Get_Balance(int *ptr , int size ) {int sum = 0 ;int i = 0 ;double balance = 0 ;for(i = 0 ; i < size ; i ++){sum = sum + ptr[i];}balance = sum / size ;return balance ; }/* 輸出結果為 Ths balance value is :3 */同樣的,我們可以傳入一個指針到某一個函數,那么我們也可以在某一個函數中返回一個指針。為了做到這點,必須聲明一個返回指針的函數,如下:
int * Function() { . . . }另外,C++ 不支持在函數外返回局部變量的地址,除非定義局部變量為?static?變量。
#include <iostream> #include <ctime> #include <cstdlib>using namespace std ;float Get_Balance(int *ptr , int size ); int *Get_num(void);void main() {float balance = 0 ;balance = Get_Balance(Get_num(),5);cout << "Ths balance value is :" << balance <<endl ; }int *Get_num() {static int data[5] ;srand( (unsigned)time( NULL ));for (int i = 0; i < 5; i++){data[i] = rand()%10;cout << data[i] << endl;}return data; }float Get_Balance(int *ptr , int size ) {int sum = 0 ;int i = 0 ;float balance = 0 ;for(i = 0 ; i < size ; i ++){sum = sum + ptr[i];}balance = sum / size ;cout << balance << endl ;return balance ; }/* 輸出結果為 9 2 1 7 2 4 Ths balance value is :4 */函數指針? 與? ?指針函數 分析(重點與難點)
指針函數是指帶指針的函數,即本質是一個函數,函數返回類型是某一類型的指針
指針函數在上面已經提及過了,什么是指針函數。就是返回值是一個指針的函數。聲明方法如下:
類型說明符 * 函數名(參數)
int * A(int B,int C);函數指針是指向函數的指針變量,即本質是一個指針變量。
先看一段代碼
其中?void (*fun)();? 是函數指針的聲明,并沒傳入任何函數進去。
void Output_1(void);?聲明了一個函數。
fun = Output_1;? 將一個函數的地址(函數名就代表了該函數的地址)賦值給了函數指針。這樣?fun 這個函數指針就具備了Output_1這個函數的功能。
這就是函數指針的用法。
#include <iostream>using namespace std ;void (*fun)(); void Output_1(void);void main() {fun = Output_1;(*fun)(); }void Output_1(void) {cout<<"1"<<endl; }/* 輸出結果為 1 */還有一個更高級的聲明方式
typedef void (*FunP)();可以看出這是一個無返回類型的函數指針,不帶任務參數。后面我們就可以像定義普通變量一樣,輕松的定義函數指針了。
函數指針的用處
將函數作為參數傳遞給函數(此部分轉自https://blog.csdn.net/yuexiang321/article/details/52658947)
相信,大家中學的時候都學過積分這個鬼東西。不知道還記不記得積分最原始的計算方法。對,沒錯,無限細分,求面積。好的。我們接下來就給大家一個應用函數指針有關積分計算的例子。
直接貼出代碼。
? #include <iostream> using namespace std; //Calculate用于計算積分。一共三個參數。第一個為函數指針func,指向待積分函數。二三參數為積分上下限 double Calculate(double(*func)(double x), double a, double b) {double dx = 0.0001;//細分的區間長度 double sum = 0; for (double xi = a+dx; xi <= b; xi+=dx) { double area = func(xi)*dx; sum +=area; } return sum; } double func_1(double x) { return x*x; }double func_2(double x) { return x*x*x; } void main() { cout<<Calculate(func_1, 0, 1)<<endl ;cout<<Calculate(func_2, 0, 1)<<endl ; // printf("%lf\n", Calculate(func_1, 0, 1)); // printf("%lf\n", Calculate(func_2, 0, 1)); } /* 輸出結果為 0.333383 0.25005 */?
通過函數指針,我們可以在函數中使用別的函數作為參數。此程序可以完成對不同函數的積分。
2)引用不在代碼段中的函數
此功能在嵌入式系統中經常使用。我們知道,我們寫的用戶程序的code是存放在代碼段中的,在嵌入式系統中,一般情況下是存放在flash中的。什么叫不在代碼段中的函數?很多微控制器在出廠前會將一些功能函數(系統函數)固化在rom中(類似于PC機中的BIOS),如Flash擦寫功能,Flash Copy功能。而我們寫的代碼是不認識這些函數的,不能直接使用函數名調用。所以,當我們想在用戶程序中調用這些系統函數時,就只能使用函數指針的方式,通過將系統函數的入口地址傳給函數指針,來達到調用rom中程序的目的。這些系統函數一般都會在官方手冊中給出功能,返回值類型和參數列表。
下面是從三星的S5PV210_applicationnote中截取的一個系統函數。
從上我們可以分析出,此系統函數的入口地址為0xD0037F98。返回bool型,帶有int, unsigned int, unsigned short, unsigned int*, bool型五個參數。實際使用時,我們可以如下調用:
// 實際使用時
pCopySDMMC2Mem p1 = (pCopySDMMC2Mem)0xD0037F98;
p1(x, x, x, x, x);
傳入五個合適的參數即可。
?
?
部分資料來自于CSDN博客,菜鳥教程!!!!
?
?
?
總結
- 上一篇: 51单片机创建工程操作流程
- 下一篇: 51单片机 自动重装载值计算