2016-12-16 120 views
0

因此,在爲我的考試學習時,我試圖爲指針做練習問題。在C++中使用指針的數組中元素的數量

在下面的代碼我試圖顯示元素的個數爲0

只有一個,我不明白,請參見第6最後一行的部分中第一次出現了。

#include <iostream> 

using namespace std; 

int main() 
{ 
    int A[10]; 
    for (int i = 0; i < 10; i++){ 
     cout << "Please enter number " << i + 1 << " in the array: "; 
     cin >> A[i]; 
    } 
    int *Aptr = A; 
    while(*Aptr !=0){ 
     cout << *Aptr << ""; 
     Aptr++; 
    } 
    cout << "\nThere are " << (Aptr - A) //Here is what i don't understand. 
    << " numbers before the first occurrence of 0." << endl; 

    system("pause"); 
    return 0; 
} 

那麼,爲什麼恰好是(APTR - A)給我元素,而不是一個存儲器位置的數目,並且這是爲什麼即使可行,因爲APTR是一個指針和是一個數組?

有人可以向我詳細解釋一下嗎?

+1

一個數組和一個指針並不像它們看起來那麼不同。 – CollinD

+1

另外A是指向A [0]的指針 – solti

+0

請參見[C++指針算術](https://www.tutorialspoint.com/cplusplus/cpp_pointer_arithmatic.htm)。 – qxz

回答

1

首先,數組A的名稱與(指針在)數組中第一項的地址相關聯。

那麼,爲什麼(Aptr - A)給我的元素數量?

因爲根據規則地址算術減法操作(也+,和類似的)是基於數據類型執行的。

我的意思是,編譯器int*操作使得++--,加法,減法的整數,等等增加了需要用於轉移到下一個/前一個項目的地址。

如果你真的想看看有多少字節位於地址之間,只是地址轉換爲int做減法之前:

cout << endl << "Address difference is " << int(Aptr) - int(A) << endl; 

你可以嘗試用不同的數據類型如下:

#include <iostream> 
#include <iomanip> 
using namespace std; 

int main() 
{ 
    int A[5]; 
    short B[5]; 
    unsigned char C[5]; 
    cout << "Array (data type) | Syze of array | Size of item | Item distanse | Bytes distance" << endl; 
    cout << "A (int)   :" << setw(10) 
          << sizeof(A) << setw(15) 
          << sizeof(A[0]) << setw(15) 
          << &A[4] - A << setw(15) 
          << int(&A[4]) - int(A) << endl; 
    cout << "B (short)   :" << setw(10) 
          << sizeof(B) << setw(15) 
          << sizeof(B[0]) << setw(15) 
          << &B[4] - B << setw(15) 
          << int(&B[4]) - int(B) << endl; 
    cout << "C (un.char)  :" << setw(10) 
          << sizeof(C) << setw(15) 
          << sizeof(C[0]) << setw(15) 
          << &C[4] - C << setw(15) 
          << int(&C[4]) - int(C) << endl; 

    system("pause"); 
    return 0; 
} 

UPDATE

爲了更好地爲您的考試做準備,請仔細閱讀呃下面的示例中使用指針:

#include <iostream> 
using namespace std; 

int main() 
{ 
    int A[5] = {0}; // all items now are 0 
    int * P = A + 2; // the same as P = &A[2]; 
    *P = 33; // writing to item A[2]; 
    cout << A[2] << endl; // just to check in usual way 
    cout << *(A + 2) << endl; // using A as a pointer 
    cout << *(2 + A) << endl; // almost the same to previous 
    cout << 2[A] << endl; // quite strange, but it works 
    cout << 0[P] << endl; // and this is the same 
    return 0; 
} 

你必須明白,0[P]意味着編譯器*(0 + P),以及2[A]手段 - *(2 + A),但你不應該在你的這種風格的節目寫(例外是僅情況下,當你想混淆讀者)。

還有一重要的事情 - 陣列和指針之間的差異 - 示於下面的示例:

int A[] = {1, 2, 3, 4, 5}; 
    int *P = A; 
    cout << "A = " << A << endl; 
    cout << "P = " << P << endl; 
    cout << "size of A = " << sizeof(A) << endl; 
    cout << "size of P = " << sizeof(P) << endl; 

即使地址(vaules A和P)是相等的,編譯器可與陣列(A)與指針不同:sizeof(A)表示分配給整個陣列的內存(每個sizeof(int) 5個項目),但sizeof(P)表示分配給數據類型int *(指向int的指針)的內存。因此,sizeof(P)僅取決於編譯器和OS平臺(例如指針可以是32位或64位),但sizeof(A)取決於項目的大小(int可能不是32位)和數組中的項數。

你可以「轉到下一個項目」與指針:

P++; 
    cout << *P << endl; 

,但是你是不是能夠做到:

A++; 

因爲A不是指針類型的變量(它是隻是類似於「第一項的地址」),編譯器會這樣說:

錯誤:'++'需要l-val UE

4

當在表達式中使用,像Aptr - A,陣列A的名稱將被隱式轉換爲指針(等於&A[0])。

然後編譯器面臨減去兩個相同類型的指針(在您的情況下都是int *類型)。這被指定爲給出std::ptrdiff_t類型的值,其依次是「能夠表示減去兩個指針的結果的有符號整數類型」。

指針運算,減法int類型(即,兩個int * S)的兩個指針時給出的int S中的兩個指針之間(數假設它們處於相同的對象,這是真實的在這種情況下,由於Aptr點數組A的元素)。

實際上,如果Aptr等於&A[i],減法Aptr - &A[0]給出std::ptrdiff_t等於i

注:還有另外一個問題,在你的代碼,因爲作爲第一個(for)循環讀取10值,而第二while循環不斷遞增Aptr直到它指向一個int與價值0。如果用戶輸入任何零值,第二個循環將在找到第一個循環時停止(即使用戶在此之後輸入非零元素)。如果用戶輸入不等於0值,那麼while環路不確定的行爲,因爲Aptr將繼續穿行記憶過去的A結束,直到它恰好找到等於0內存比較(作爲int)。