如果 arr[3] 是一个数组而 ptr 是一个指针,那么为什么 arr 和 &arr 给出相同的结果而 ptr 和 &ptr 不
If arr[3] is an array and ptr is a pointer, then why do arr and &arr give same result but ptr and &ptr don't
我是数据结构和算法的初学者,现在开始研究指针,在问这里的问题之前我读了 this recommended post 但我不明白所以我在这里问问题。
朋友告诉我数组名是指向数组第一个值的指针,如arr returns arr[0], arr+1 returns arr[1] 的地址,所以当我写这个
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i = 10;
int arr[3] = {1, 2, 3};
int *ptr = &i;
cout << arr << " " << &arr << endl;
cout << ptr << " " << &ptr;
return 0;
}
arr和&arr都给同样的结果
0x61ff00 0x61ff00
而 ptr 和 &ptr 给出不同的结果
0x61ff0c 0x61fefc
谁能告诉我为什么会这样?
数组不是指针!
数组在各种情况下都会衰减到指向其第一个元素的指针。例如 std::cout << arr;
实际上打印了数组第一个元素的内存地址。 std::cout << &arr;
打印数组的内存地址。由于第一个元素的地址与数组的地址相同,因此您会看到相同的值。
但是,仅仅因为它们具有相同的值,并不意味着它们是相同的。 arr
可以衰减为 int*
,而 &arr
是指向数组的指针,int(*)[3]
.
我希望以下内容能帮助大家理清头绪:
#include <iostream>
#include <type_traits>
void make_it_decay(int x[]) {
std::cout << std::is_same_v< decltype(x), int*> << "\n";
}
int main() {
int arr[3] = {1,2,3};
//std::cout << (arr == &arr) << "\n"; // does not compile !
std::cout << (arr == &(arr[0])) << "\n";
std::cout << std::is_same_v< decltype(arr), int[3]> << "\n";
std::cout << std::is_same_v< decltype(&arr),int(*)[3]> << "\n";
std::cout << std::is_same_v< decltype(&arr[0]), int* > << "\n";
make_it_decay(arr);
}
1
1
1
1
1
我使用 decltype
来推断某些表达式的类型,并使用 std::is_same_v
来查看表达式是否属于同一类型。
arr
是 int[3]
类型。它是一个数组。它不是指针。
&arr
是数组的地址。它是一个指向具有三个元素的数组的指针,a int(*)[3]
.
&arr[0]
尽管它与 &arr
具有相同的值但类型不同。它是一个指向 int
的指针,一个 int*
.
当我们将 arr
传递给函数时,它会衰减为指向数组第一个元素的指针。而我们可以看到函数x
里面是int*
.
现在回答你的问题...
上面我试图说明当你写 std::cout << arr
时会发生什么。指针是不同的,因为......好数组不是指针。
std::cout << ptr; // prints the value ptr
std::cout << &ptr; // prints the address of ptr
也许一些形象化的帮助。当递增指针时,类型的差异变得最明显
-------------------
| arr |
-------------------
| 1 | 2 | 3 |
-------------------
^ ^ ^
&arr | &arr + 1
&arr[0] |
&arr[0] + 1
array's name is a pointer to the first value in the array
以上说法在技术上是不正确的。发生的情况是,在许多情况下,由于 类型衰减 ,数组 衰减 指向指向其第一个元素的指针。这意味着,在您的示例中,当您编写 std::cout << arr
时,有一个 隐式 array-to-pointer 转换 转换了类型 [=12] 的数组 arr
=] 指向其第一个元素的指针,类型为 int*
.
备注
另请注意,即使衰减指针和数组地址都具有相同的值,但它们的类型不同。衰减指针的类型为 int*
而 &arr
的类型是 int (*)[3]
.
我是数据结构和算法的初学者,现在开始研究指针,在问这里的问题之前我读了 this recommended post 但我不明白所以我在这里问问题。
朋友告诉我数组名是指向数组第一个值的指针,如arr returns arr[0], arr+1 returns arr[1] 的地址,所以当我写这个
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i = 10;
int arr[3] = {1, 2, 3};
int *ptr = &i;
cout << arr << " " << &arr << endl;
cout << ptr << " " << &ptr;
return 0;
}
arr和&arr都给同样的结果
0x61ff00 0x61ff00
而 ptr 和 &ptr 给出不同的结果
0x61ff0c 0x61fefc
谁能告诉我为什么会这样?
数组不是指针!
数组在各种情况下都会衰减到指向其第一个元素的指针。例如 std::cout << arr;
实际上打印了数组第一个元素的内存地址。 std::cout << &arr;
打印数组的内存地址。由于第一个元素的地址与数组的地址相同,因此您会看到相同的值。
但是,仅仅因为它们具有相同的值,并不意味着它们是相同的。 arr
可以衰减为 int*
,而 &arr
是指向数组的指针,int(*)[3]
.
我希望以下内容能帮助大家理清头绪:
#include <iostream>
#include <type_traits>
void make_it_decay(int x[]) {
std::cout << std::is_same_v< decltype(x), int*> << "\n";
}
int main() {
int arr[3] = {1,2,3};
//std::cout << (arr == &arr) << "\n"; // does not compile !
std::cout << (arr == &(arr[0])) << "\n";
std::cout << std::is_same_v< decltype(arr), int[3]> << "\n";
std::cout << std::is_same_v< decltype(&arr),int(*)[3]> << "\n";
std::cout << std::is_same_v< decltype(&arr[0]), int* > << "\n";
make_it_decay(arr);
}
1
1
1
1
1
我使用 decltype
来推断某些表达式的类型,并使用 std::is_same_v
来查看表达式是否属于同一类型。
arr
是 int[3]
类型。它是一个数组。它不是指针。
&arr
是数组的地址。它是一个指向具有三个元素的数组的指针,a int(*)[3]
.
&arr[0]
尽管它与 &arr
具有相同的值但类型不同。它是一个指向 int
的指针,一个 int*
.
当我们将 arr
传递给函数时,它会衰减为指向数组第一个元素的指针。而我们可以看到函数x
里面是int*
.
现在回答你的问题...
上面我试图说明当你写 std::cout << arr
时会发生什么。指针是不同的,因为......好数组不是指针。
std::cout << ptr; // prints the value ptr
std::cout << &ptr; // prints the address of ptr
也许一些形象化的帮助。当递增指针时,类型的差异变得最明显
-------------------
| arr |
-------------------
| 1 | 2 | 3 |
-------------------
^ ^ ^
&arr | &arr + 1
&arr[0] |
&arr[0] + 1
array's name is a pointer to the first value in the array
以上说法在技术上是不正确的。发生的情况是,在许多情况下,由于 类型衰减 ,数组 衰减 指向指向其第一个元素的指针。这意味着,在您的示例中,当您编写 std::cout << arr
时,有一个 隐式 array-to-pointer 转换 转换了类型 [=12] 的数组 arr
=] 指向其第一个元素的指针,类型为 int*
.
备注
另请注意,即使衰减指针和数组地址都具有相同的值,但它们的类型不同。衰减指针的类型为 int*
而 &arr
的类型是 int (*)[3]
.