为什么我在主函数和其他函数中看到不同的数组大小值
why do I see different values of array size in main vs other function
我创建了一个包含十个整数的数组并打印了它的大小
1.主要
2. 在名为 print
的函数中
#include <iostream>
using namespace std;
void print(int *a)
{
cout<<sizeof(a);
}
int main()
{
int arr[10];
cout<<sizeof(arr)<<endl;
print(arr);
}
输出为:
40
8
我在这两种情况下都期望 40(因为 1 integer=4 乘以 10 的大小)但第二种情况显示单个指针的大小而不是整个数组。这里发生了什么?
当您将数组传递给函数时,它会被调整为指向函数内第一个元素的指针。
所以你在 print
函数中看到的不是数组的大小而是指针的大小,即 sizeof(a)
等同于 sizeof(int*)
.
从函数声明可以看出
void print(int *a)
{
cout<<sizeof(a);
}
函数处理指针。所以这个声明
cout<<sizeof(a);
根据使用的系统输出等于 4 或 8 字节的指针大小。
请注意,即使您将函数声明为
void print(int a[])
{
cout<<sizeof(a);
}
你会得到相同的结果,因为参数被编译器隐式调整为 int * 类型。
也就是说前面和这个函数声明是等价的。
如果您希望该函数处理原始数组而不是指向传递数组的第一个元素的指针作为参数,那么至少要像这样声明该函数。
void print( int ( &a )[10] )
{
cout<<sizeof(a);
}
也就是将参数声明为引用。
或者您可以将函数设为模板函数,例如
template <size_t N>
void print( int ( &a )[N] )
{
cout<<sizeof(a);
}
由于传递的数组在函数中没有改变,因此参数应该有限定符 const
template <size_t N>
void print( const int ( &a )[N] )
{
cout<<sizeof(a);
}
这是一个演示程序。
#include <iostream>
template <size_t N>
void print( const int ( &a )[N] )
{
std::cout << sizeof( a ) << '\n';
}
int main()
{
int arr[10];
std::cout << sizeof( arr ) << '\n';
print( arr );
return 0;
}
它的输出是
40
40
或者您可以使用类型模板参数定义模板函数。但是函数参数再次具有引用类型。
#include <iostream>
template <typename T>
void print( const T &a )
{
std::cout << sizeof( a ) << '\n';
}
int main()
{
int arr[10];
std::cout << sizeof( arr ) << '\n';
print( arr );
return 0;
}
程序输出与上图相同。
您应该看到这段代码的输出,并观察其中的区别:
#include <iostream>
using namespace std;
int* h()
{
int *a[10];
cout<<sizeof(a);
return a;
}
int main()
{
int *a=h();
cout<<sizeof(a);
}
输出:
40
8
现在 main 显示大小为 8(指针大小),函数 print 显示数组大小为 40。
我创建了一个包含十个整数的数组并打印了它的大小 1.主要 2. 在名为 print
的函数中#include <iostream>
using namespace std;
void print(int *a)
{
cout<<sizeof(a);
}
int main()
{
int arr[10];
cout<<sizeof(arr)<<endl;
print(arr);
}
输出为:
40
8
我在这两种情况下都期望 40(因为 1 integer=4 乘以 10 的大小)但第二种情况显示单个指针的大小而不是整个数组。这里发生了什么?
当您将数组传递给函数时,它会被调整为指向函数内第一个元素的指针。
所以你在 print
函数中看到的不是数组的大小而是指针的大小,即 sizeof(a)
等同于 sizeof(int*)
.
从函数声明可以看出
void print(int *a)
{
cout<<sizeof(a);
}
函数处理指针。所以这个声明
cout<<sizeof(a);
根据使用的系统输出等于 4 或 8 字节的指针大小。
请注意,即使您将函数声明为
void print(int a[])
{
cout<<sizeof(a);
}
你会得到相同的结果,因为参数被编译器隐式调整为 int * 类型。
也就是说前面和这个函数声明是等价的。
如果您希望该函数处理原始数组而不是指向传递数组的第一个元素的指针作为参数,那么至少要像这样声明该函数。
void print( int ( &a )[10] )
{
cout<<sizeof(a);
}
也就是将参数声明为引用。
或者您可以将函数设为模板函数,例如
template <size_t N>
void print( int ( &a )[N] )
{
cout<<sizeof(a);
}
由于传递的数组在函数中没有改变,因此参数应该有限定符 const
template <size_t N>
void print( const int ( &a )[N] )
{
cout<<sizeof(a);
}
这是一个演示程序。
#include <iostream>
template <size_t N>
void print( const int ( &a )[N] )
{
std::cout << sizeof( a ) << '\n';
}
int main()
{
int arr[10];
std::cout << sizeof( arr ) << '\n';
print( arr );
return 0;
}
它的输出是
40
40
或者您可以使用类型模板参数定义模板函数。但是函数参数再次具有引用类型。
#include <iostream>
template <typename T>
void print( const T &a )
{
std::cout << sizeof( a ) << '\n';
}
int main()
{
int arr[10];
std::cout << sizeof( arr ) << '\n';
print( arr );
return 0;
}
程序输出与上图相同。
您应该看到这段代码的输出,并观察其中的区别:
#include <iostream>
using namespace std;
int* h()
{
int *a[10];
cout<<sizeof(a);
return a;
}
int main()
{
int *a=h();
cout<<sizeof(a);
}
输出:
40
8
现在 main 显示大小为 8(指针大小),函数 print 显示数组大小为 40。