1. 程式人生 > 實用技巧 >Mysql資料庫操作

Mysql資料庫操作

技術標籤:C++

目錄

例項

什麼是指標?

C++ 中使用指標

NULL(nullptr)指標


學習 C++ 的指標既簡單又有趣。通過指標,可以簡化一些 C++ 程式設計任務的執行,還有一些任務,如動態記憶體分配,沒有指標是無法執行的。所以,想要成為一名優秀的 C++ 程式設計師,學習指標是很有必要的。

正如您所知道的,每一個變數都有一個記憶體位置,每一個記憶體位置都定義了可使用連字號(&)運算子訪問的地址,它表示了在記憶體中的一個地址。請看下面的例項,它將輸出定義的變數地址:

例項

#include <iostream> 
using namespace std; 
int main () 
{ 
    int var1; 
    char var2[10]; 
    cout << "var1 變數的地址: "; 
    cout << &var1 << endl; 
    cout << "var2 變數的地址: "; 
    cout << &var2 << endl; 
    return 0; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

var1 變數的地址: 0xbfebd5c0
var2 變數的地址: 0xbfebd5b6

通過上面的例項,我們瞭解了什麼是記憶體地址以及如何訪問它。接下來讓我們看看什麼是指標。

什麼是指標?

指標是一個變數,其值為另一個變數的地址,即,記憶體位置的直接地址。就像其他變數或常量一樣,您必須在使用指標儲存其他變數地址之前,對其進行宣告。指標變數宣告的一般形式為:

type *var-name;

在這裡,type 是指標的基型別,它必須是一個有效的 C++ 資料型別,var-name 是指標變數的名稱。用來宣告指標的星號 * 與乘法中使用的星號是相同的。但是,在這個語句中,星號是用來指定一個變數是指標。以下是有效的指標宣告:

int    *ip;    /* 一個整型的指標 */
double *dp;    /* 一個 double 型的指標 */
float  *fp;    /* 一個浮點型的指標 */
char   *ch;    /* 一個字元型的指標 */

所有指標的值的實際資料型別,不管是整型、浮點型、字元型,還是其他的資料型別,都是一樣的,都是一個代表記憶體地址的長的十六進位制數。不同資料型別的指標之間唯一的不同是,指標所指向的變數或常量的資料型別不同。

C++ 中使用指標

使用指標時會頻繁進行以下幾個操作:定義一個指標變數、把變數地址賦值給指標、訪問指標變數中可用地址的值。這些是通過使用一元運算子 * 來返回位於運算元所指定地址的變數的值。下面的例項涉及到了這些操作:

例項

#include <iostream> 
using namespace std; 
int main () 
{ 
    int var = 20; // 實際變數的宣告 
    int *ip; // 指標變數的宣告 
    ip = &var; // 在指標變數中儲存 var 的地址 
    cout << "Value of var variable: "; 
    cout << var << endl; // 輸出在指標變數中儲存的地址 
    cout << "Address stored in ip variable: "; 
    cout << ip << endl; // 訪問指標中地址的值 
    cout << "Value of *ip variable: "; 
    cout << *ip << endl; 
    return 0; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

Value of var variable: 20
Address stored in ip variable: 0xbfc601ac
Value of *ip variable: 20

NULL(nullptr)指標

在變數宣告的時候,如果沒有確切的地址可以賦值,為指標變數賦一個 NULL 值是一個良好的程式設計習慣。賦為 NULL 值的指標被稱為指標。

NULL 指標是一個定義在標準庫中的值為零的常量。請看下面的程式:

#include <iostream>

using namespace std;

int main ()
{
   int  *ptr = NULL;

   cout << "ptr 的值是 " << ptr ;
 
   return 0;
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

ptr 的值是 0

在大多數的作業系統上,程式不允許訪問地址為 0 的記憶體,因為該記憶體是作業系統保留的。然而,記憶體地址 0 有特別重要的意義,它表明該指標不指向一個可訪問的記憶體位置。但按照慣例,如果指標包含空值(零值),則假定它不指向任何東西。

如需檢查一個空指標,您可以使用 if 語句,如下所示:

if(ptr)     /* 如果 ptr 非空,則完成 */
if(!ptr)    /* 如果 ptr 為空,則完成 */

因此,如果所有未使用的指標都被賦予空值,同時避免使用空指標,就可以防止誤用一個未初始化的指標。很多時候,未初始化的變數存有一些垃圾值,導致程式難以除錯。

指標的算術運算

指標是一個用數值表示的地址。因此,您可以對指標執行算術運算。可以對指標進行四種算術運算:++、--、+、-。

假設 ptr 是一個指向地址 1000 的整型指標,是一個 32 位的整數,讓我們對該指標執行下列的算術運算:

ptr++

在執行完上述的運算之後,ptr 將指向位置 1004,因為 ptr 每增加一次,它都將指向下一個整數位置,即當前位置往後移 4 個位元組。這個運算會在不影響記憶體位置中實際值的情況下,移動指標到下一個記憶體位置。如果 ptr 指向一個地址為 1000 的字元,上面的運算會導致指標指向位置 1001,因為下一個字元位置是在 1001。

遞增一個指標

我們喜歡在程式中使用指標代替陣列,因為變數指標可以遞增,而陣列不能遞增,因為陣列是一個常量指標。下面的程式遞增變數指標,以便順序訪問陣列中的每一個元素:

例項

#include <iostream> 
using namespace std; 

const int MAX = 3; 

int main () 
{ 
    int var[MAX] = {10, 100, 200}; 
    int *ptr; // 指標中的陣列地址 
    ptr = var; 
    for (int i = 0; i < MAX; i++) 
    { 
        cout << "Address of var[" << i << "] = "; 
        cout << ptr << endl; 
        cout << "Value of var[" << i << "] = "; 
        cout << *ptr << endl; // 移動到下一個位置 ptr++; 
    } 
    return 0; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

Address of var[0] = 0xbfa088b0
Value of var[0] = 10
Address of var[1] = 0xbfa088b4
Value of var[1] = 100
Address of var[2] = 0xbfa088b8
Value of var[2] = 200

遞減一個指標

同樣地,對指標進行遞減運算,即把值減去其資料型別的位元組數,如下所示:

例項

#include <iostream> 
using namespace std; 
const int MAX = 3; 
int main () 
{ 
    int var[MAX] = {10, 100, 200}; 
    int *ptr; // 指標中最後一個元素的地址 
    ptr = &var[MAX-1]; 
    for (int i = MAX; i > 0; i--) 
    { 
        cout << "Address of var[" << i << "] = "; 
        cout << ptr << endl; 
        cout << "Value of var[" << i << "] = "; 
        cout << *ptr << endl; // 移動到下一個位置 
        ptr--; 
    } 
    return 0; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

Address of var[3] = 0xbfdb70f8
Value of var[3] = 200
Address of var[2] = 0xbfdb70f4
Value of var[2] = 100
Address of var[1] = 0xbfdb70f0
Value of var[1] = 10

指標的比較

指標可以用關係運算符進行比較,如 ==、< 和 >。如果 p1 和 p2 指向兩個相關的變數,比如同一個數組中的不同元素,則可對 p1 和 p2 進行大小比較。

下面的程式修改了上面的例項,只要變數指標所指向的地址小於或等於陣列的最後一個元素的地址 &var[MAX - 1],則把變數指標進行遞增:

例項

#include <iostream> 
using namespace std; 
const int MAX = 3; 
int main ()
{ 
    int var[MAX] = {10, 100, 200}; 
    int *ptr; // 指標中第一個元素的地址 
    ptr = var; 
    int i = 0; 
    while ( ptr <= &var[MAX - 1] ) 
    { 
        cout << "Address of var[" << i << "] = "; 
        cout << ptr << endl; 
        cout << "Value of var[" << i << "] = "; 
        cout << *ptr << endl; // 指向上一個位置 
        ptr++; 
        i++; 
    } 
    return 0; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

Address of var[0] = 0xbfce42d0
Value of var[0] = 10
Address of var[1] = 0xbfce42d4
Value of var[1] = 100
Address of var[2] = 0xbfce42d8
Value of var[2] = 200

指向指標的指標

指向指標的指標是一種多級間接定址的形式,或者說是一個指標鏈。

指標的指標就是將指標的地址存放在另一個指標裡面。

通常,一個指標包含一個變數的地址。當我們定義一個指向指標的指標時,第一個指標包含了第二個指標的地址,第二個指標指向包含實際值的位置。

C++ 中指向指標的指標

一個指向指標的指標變數必須如下宣告,即在變數名前放置兩個星號。例如,下面聲明瞭一個指向 int 型別指標的指標:

int **var;

當一個目標值被一個指標間接指向到另一個指標時,訪問這個值需要使用兩個星號運算子,如下面例項所示:

例項

#include <iostream> 
using namespace std; 
int main () 
{ 
    int var; 
    int *ptr; 
    int **pptr; 
    var = 3000; 
    // 獲取 var 的地址 
    ptr = &var; 
    // 使用運算子 & 獲取 ptr 的地址 
    pptr = &ptr; 
    // 使用 pptr 獲取值 
    cout << "var 值為 :" << var << endl; 
    cout << "*ptr 值為:" << *ptr << endl; 
    cout << "**pptr 值為:" << **pptr << endl; 
    return 0; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

var 值為 :3000
*ptr 值為:3000
**pptr 值為:3000

傳遞指標給函式

C++ 允許您傳遞指標給函式,只需要簡單地宣告函式引數為指標型別即可。

下面的例項中,我們傳遞一個無符號的 long 型指標給函式,並在函式內改變這個值:

例項

#include <iostream> 
#include <ctime> 
using namespace std; 
// 在寫函式時應習慣性的先宣告函式,然後在定義函式 
void getSeconds(unsigned long *par); 

int main () 
{ 
    unsigned long sec; 
    getSeconds( &sec ); 
    // 輸出實際值 
    cout << "Number of seconds :" << sec << endl; 
    return 0;
}

void getSeconds(unsigned long *par) 
{ 
    // 獲取當前的秒數 
    *par = time( NULL ); 
    return; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

Number of seconds :1294450468

能接受指標作為引數的函式,也能接受陣列作為引數,如下所示:

例項

#include <iostream> 
using namespace std; 
// 函式宣告 
double getAverage(int *arr, int size); 

int main ()
{ 
    // 帶有 5 個元素的整型陣列 
    int balance[5] = {1000, 2, 3, 17, 50}; 
    double avg; 
    // 傳遞一個指向陣列的指標作為引數 
    avg = getAverage( balance, 5 ) ; 
    // 輸出返回值 
    cout << "Average value is: " << avg << endl; 
    return 0; 
} 

double getAverage(int *arr, int size) 
{ 
    int i, sum = 0; 
    double avg; 
    for (i = 0; i < size; ++i) 
    { 
        sum += arr[i]; 
    } 
    avg = double(sum) / size; 
    return avg; 
}

當上面的程式碼被編譯和執行時,它會產生下列結果:

Average value is: 214.4