2016-12-16 119 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)。