数组中使用指针的元素数 C++
The number of elements in an array using pointers in C++
所以在为考试做准备时,我试图为指针做一道练习题。
在下面的代码中,我尝试显示第一次出现 0 之前的元素数。
只有一部分我不明白,请看倒数第六行。
#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是一个指针而A是一个数组?
有人可以详细解释一下吗?
当在表达式中使用时,如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
,直到它指向值为0
的int
。 如果用户输入任何零值,则第二个循环将在找到第一个时停止(即使用户在此之后输入非零元素)。 如果用户输入的值不等于0
,则while
循环具有未定义的行为,因为Aptr
将在A
结束时继续遍历内存,直到碰巧找到比较(作为int
)等于0
的内存。
首先,数组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;
}
更新
为了更好地准备考试,请考虑以下带有指针的示例:
#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)
表示为整个数组分配的内存(每个 5 项sizeof(int)
项),但sizeof(P)
表示为数据类型int *
分配的内存(指向 int 的指针)。因此,sizeof(P)
仅取决于编译器和操作系统平台(例如指针可以是 32 位或 64 位),但sizeof(A)
取决于项目的大小(int
可能不是 32 位)和数组中的项目数。
您可以使用指针"转到下一项":
P++;
cout << *P << endl;
但你做不到:
A++;
因为A
不是指针类型的变量(它只是在"第一项的地址"的意义上相似),编译器会这样说你:
错误:"++"需要 L 值
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 使用函数"remove"删除重复元素
- 具有最大子序列大小的序列,每个元素都相同
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将元素添加到数组的线程安全函数?
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 我想访问std::unique_ptr中的一个特定元素
- 如何通过 getter 函数删除矢量的元素?
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 从控制台中删除最后打印的元素
- 擦除while循环中迭代的元素