C++数组是如何识别的?
How is C++ array recognized?
当您在 C++ 中传递数组时,它们会作为指针传递。所以我们必须显式传递该数组的大小。
// This will not work.
int GetSize(int* arr){
return sizeof(arr)/size(int);
}
但是如果我们不使用函数来获取它的大小并在初始化数组的同一个函数中使用 "sizeof",现在我们得到正确的结果。
int main(){
int arr[5];
int size = sizeof(arr)/sizeof(int);
cout << size << endl;
}
那么我是否可以将数组视为带有指针的 class、它的大小和其中元素的类型?
现在想想,如果只是像指针一样处理,我不确定 C++ 如何知道后面代码中数组的大小。
宣言
int *arr; // arr = ptr to int
与声明不同
int arr[5]; // arr = base ptr to array of 5 ints
请注意,arr
在每种情况下都解析为地址 (ptr),但在第二种情况下,编译器可以解析 arr
是指向 5 [=16] 数组的基本 ptr =]的。如果第二个声明是函数参数,事情就会变得有点棘手:
void foo(int arr[5]) { ... }
那这真的和
没什么区别
void foo(int *arr) { ... }
void foo(int arr[]) { ... }
即,仅传递一个 ptr,sizeof(arr)
将 return ptr 中的字节数。
在第一种情况下,据我理解正确,您使用的是 int* 类型的大小,它是一个指向 int 的指针,在大多数情况下,它将产生 4 个字节(取决于体系结构和可能的其他因素)。
在第二种情况下,编译器还拥有计算 sizeof(arr) 所需的所有信息,因为明确给出了 int arr[5] 定义的 5 个 int 元素;结果在大多数情况下将等于 4 个字节 * 5 个元素,20 个字节
So is it adequate for me to look at the array as a class with a pointer, its size and type of elements in it?
不,因为它不是。 C 风格的数组只是一大块连续的内存,用于保存给定类型的元素,仅此而已。
Now that I think about it, I'm not sure how C++ knows array's size in the latter code if it's just handled the same as a pointer.
数组不是这样处理的。
在你的第一个例子中,函数只接受一个指针,它不关心那个指针来自哪里。传入数组会将 衰减 数组变成指向第一个元素的指针。所有大小信息都丢失了,数组的大小不能仅从指针确定。这就是 sizeof(arr)
在这种情况下不起作用的原因。它只知道指针本身的大小,不知道指针来自的数组的大小。
在您的第二个示例中,实际数组在使用 sizeof()
的范围内。编译器知道数组的声明,所以sizeof(arr)
可以知道数组的实际字节大小
如果你真的想知道在函数中传递的数组的大小,并且不想将大小显式地作为参数传递,那么通过reference[=29=传递数组] 而不是 pointer 所以数组的大小不会丢失:
template<size_t N>
int GetSize(int (&arr)[N]){
return N;
}
- 为什么在同一范围内时
sizeof()
? - 这是因为编译器看到你已经声明了int arr[5]
,它在编译时得到了大小为5。 sizeof()
在编译时计算。
- 为什么当数组作为指针传递时它不起作用? - 这是因为数组在这里退化为指针。因此,它丢失了大小信息。事实上,
sizeof(arr)
此处将为您提供系统指针的大小 - 64 位机器为 8 字节,32 位机器为 4 字节。
当您在 C++ 中传递数组时,它们会作为指针传递。所以我们必须显式传递该数组的大小。
// This will not work.
int GetSize(int* arr){
return sizeof(arr)/size(int);
}
但是如果我们不使用函数来获取它的大小并在初始化数组的同一个函数中使用 "sizeof",现在我们得到正确的结果。
int main(){
int arr[5];
int size = sizeof(arr)/sizeof(int);
cout << size << endl;
}
那么我是否可以将数组视为带有指针的 class、它的大小和其中元素的类型?
现在想想,如果只是像指针一样处理,我不确定 C++ 如何知道后面代码中数组的大小。
宣言
int *arr; // arr = ptr to int
与声明不同
int arr[5]; // arr = base ptr to array of 5 ints
请注意,arr
在每种情况下都解析为地址 (ptr),但在第二种情况下,编译器可以解析 arr
是指向 5 [=16] 数组的基本 ptr =]的。如果第二个声明是函数参数,事情就会变得有点棘手:
void foo(int arr[5]) { ... }
那这真的和
没什么区别void foo(int *arr) { ... }
void foo(int arr[]) { ... }
即,仅传递一个 ptr,sizeof(arr)
将 return ptr 中的字节数。
在第一种情况下,据我理解正确,您使用的是 int* 类型的大小,它是一个指向 int 的指针,在大多数情况下,它将产生 4 个字节(取决于体系结构和可能的其他因素)。
在第二种情况下,编译器还拥有计算 sizeof(arr) 所需的所有信息,因为明确给出了 int arr[5] 定义的 5 个 int 元素;结果在大多数情况下将等于 4 个字节 * 5 个元素,20 个字节
So is it adequate for me to look at the array as a class with a pointer, its size and type of elements in it?
不,因为它不是。 C 风格的数组只是一大块连续的内存,用于保存给定类型的元素,仅此而已。
Now that I think about it, I'm not sure how C++ knows array's size in the latter code if it's just handled the same as a pointer.
数组不是这样处理的。
在你的第一个例子中,函数只接受一个指针,它不关心那个指针来自哪里。传入数组会将 衰减 数组变成指向第一个元素的指针。所有大小信息都丢失了,数组的大小不能仅从指针确定。这就是 sizeof(arr)
在这种情况下不起作用的原因。它只知道指针本身的大小,不知道指针来自的数组的大小。
在您的第二个示例中,实际数组在使用 sizeof()
的范围内。编译器知道数组的声明,所以sizeof(arr)
可以知道数组的实际字节大小
如果你真的想知道在函数中传递的数组的大小,并且不想将大小显式地作为参数传递,那么通过reference[=29=传递数组] 而不是 pointer 所以数组的大小不会丢失:
template<size_t N>
int GetSize(int (&arr)[N]){
return N;
}
- 为什么在同一范围内时
sizeof()
? - 这是因为编译器看到你已经声明了int arr[5]
,它在编译时得到了大小为5。sizeof()
在编译时计算。 - 为什么当数组作为指针传递时它不起作用? - 这是因为数组在这里退化为指针。因此,它丢失了大小信息。事实上,
sizeof(arr)
此处将为您提供系统指针的大小 - 64 位机器为 8 字节,32 位机器为 4 字节。