C++(二十二) — 指針變量、函數指針、void指針


1、指針變量

(1)指針變量必須在初始化后才可以正常使用,初始化就是給他分配一個有效的數據地址。

  先初始化,后使用。

(2)指針可以進行加減運算,++ 或者 --:將指針的位置向前或者向后移動一個數據單元(char是一個格,int 是4個格子)。

(3)指針之間直接相加沒有意義,但相減是求出:兩個指針間能存放幾個指定類型的數據,不是地址值的具體差值。

(4)不同類型指針之間,不可以相互賦值。

(5)動態內存的申請和釋放

// 申請一個內存空間地址給一個指針
    int *pi = 0;
    pi = new int(10); cout << *pi << endl; delete pi; // 申請動態的整型數組, int *piarray = 0; piarray = new int[10]; delete[] piarray;

 2、函數指針

  函數指針是指向函數的指針變量。 因而“函數指針”本身首先應是指針變量,只不過該指針變量指向函數。程序在編譯時,每一個函數都有一個入口地址,該入口地址就是函數指針所指向的地址。很多c++泛型算法以及linux庫函數經常見到函數指針的使用。

// 聲明一個函數類型
typedef void (myTypeFunc)(int a, int b);
// myTypeFunc *myfuncp = nullptr;  // 定義一個函數指針,指向函數入口地址

// 聲明一個函數指針類型
typedef void (*myPTypeFunc)(int a, int b);
// myPTypeFunc myfuncp = nullptr;  // 通過   函數指針類型  定義了一個函數指針

// 定義一個函數指針變量
void(*myVarPFunc)(int a, int b);

   函數重載和函數指針,一起使用時,定義的函數指針會根據定義的參數類型,選擇正確的重載函數。

  typedef是在計算機編程語言中用來為復雜的聲明定義簡單的別名,它與宏定義有些差異。它本身是一種存儲類的關鍵字,與auto、extern、mutable、static、register等關鍵字不能出現在同一個表達式中。

//對復雜變量建立一個類型別名的方法很簡單,你只要在傳統的變量聲明表達式里用類型名替代變量名,然后把關鍵字typedef加在該語句的開頭就行了。
int *(*a[5])(int, char*);
//pFun是我們建的一個類型別名
typedef int *(*pFun)(int, char*);
//使用定義的新類型來聲明對象,等價於int* (*a[5])(int, char*);
pFun a[5];


void(*b[10]) (void(*)());
//首先為上面表達式加粗部分聲明一個新類型
typedef void(*pFunParam)();
//整體聲明一個新類型
typedef void(*pFun)(pFunParam);
//使用定義的新類型來聲明對象,等價於void (*b[10]) (void (*)());
pFun b[10];

3、void 類型指針

(1)無類型指針:void *pi,也指向內存地址,但不指定這個地址單元內的數據類型。

  不可以直接賦值給其他類型的指針;訪問內存數據時,必須進行強制轉換,才可以間接訪問內存數據。

  不會單獨使用,只是作為指針類型轉換的中介。比如:通過內存區域的復制函數:memcpy()。原理:將某種類型數據的地址轉換 void 指針,進行復制后,再強制轉換為原理的地址類型。

   //memcpy()函數的原型,參數:源地址指針、目標地址指針、復制字節數 // 接受的參數是:任意類型的實參地址指針,void 類型;
    // 返回的也是 void 類型目的地址指針,可以賦值給任何類型的指針。
    void *memcpy(void *dest, const void *src, size_t count);

(2) memcpy()通用復制函數的使用,實例:

#include <iostream>
using namespace std;
#include <string.h>

void main()
{
    // memcpy()通用復制函數的使用
    char src[10] = "012345678";
    char dest[10];
    char* pc = (char*)memcpy(dest, src, 10);  //復制字節數據
    cout << pc << endl;

    int s1[3] = { 1,2,3 };
    int d1[3];
    int *pi = (int*)memcpy(d1, s1, 12);
    cout << *pi << "   " << *(pi + 1) << "   " << *(pi + 2) << endl;

    system("pause");
}

(3)顯示字符指針的內容

  使用 cout 輸出字符指針的地址值,而不是內容。

    char *pch = "hello c++";
    cout << pch << endl;  // hello c++
    cout << *pch << endl; // h
    cout << (void*)pch << endl;// 輸出的內存地址    

  對於單個字符的處理:

   char a = 'h';
    char *pch1 = &a;
    cout << &pch1 << endl;  // 輸出 pch1 的地址
    cout << *pch1 << endl; // h
    cout << (void*)pch1 << endl;// 輸出的內存地址,即 pch1 中保存的地址的值

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM