C++ 如何可靠地获得C型阵列的大小?
如何可靠地获取C样式数组的大小?通常推荐的方法似乎是使用C++ 如何可靠地获得C型阵列的大小?,c++,c,arrays,size,C++,C,Arrays,Size,如何可靠地获取C样式数组的大小?通常推荐的方法似乎是使用sizeof,但它在foo函数中不起作用,其中x被传入: #include <iostream> void foo(int x[]) { std::cerr << (sizeof(x) / sizeof(int)); // 2 } int main(){ int x[] = {1,2,3,4,5}; std::cerr << (sizeof(x) / sizeof(int));
sizeof
,但它在foo
函数中不起作用,其中x
被传入:
#include <iostream>
void foo(int x[]) {
std::cerr << (sizeof(x) / sizeof(int)); // 2
}
int main(){
int x[] = {1,2,3,4,5};
std::cerr << (sizeof(x) / sizeof(int)); // 5
foo(x);
return 0;
}
#包括
void foo(整数x[]{
C中的std::cerrC中的数组参数实际上只是指针,因此sizeof()
将不起作用。您需要将大小作为另一个参数传递,或者使用哨兵-以最适合您的设计为准
其他一些选择:
其他一些信息:
> P> C++,而不是传递原始数组指针,您可能希望参数使用包中的数组来跟踪数组大小,并提供方法以安全的方式将数据复制到数组中。类似或有帮助。e、 在使用参数的函数中,可以得到类似于std::vector
的操作,但是函数的调用方可以使用简单的C数组。没有对数组的复制-array\u proxy
模板几乎自动打包数组指针和数组大小
- 在C中用于确定数组中元素数的宏(当sizeof()可能有帮助时,例如,您没有处理简单的指针):
您可以传递大小,使用sentinel,或者更好地使用std::vector。尽管std::vector缺少初始值设定项列表,但使用一组元素构建向量仍然很容易(尽管没有那么好)
static const int arr[]={1,2,3,4,5};
向量向量向量(arr,arr+sizeof(arr)/sizeof(arr[0]);
STD::向量类也使得错误更难,这是它的重量,它的重量是金的。另外一个好处是所有的C++都应该熟悉它,并且大多数C++应用程序应该使用一个STD::vector而不是原始C数组。
作为简要说明,C++0x添加了
std::vector v={1,2,3,4};
您也可以使用来做同样的事情,尽管语法有点复杂
std::vector<int> v = boost::assign::list_of(1)(2)(3)(4);
std::vector v=boost::assign::list_of(1)(2)(3)(4);
或
std::vector v;
v+=1,2,3,4;
c对此不提供本机支持。一旦数组超出其声明的作用域,其大小将丢失
你可以通过数组传递大小。如果你总是想保持大小,你甚至可以将它们捆绑到一个结构中,尽管这样会有一些簿记开销。这个怎么样
template <int N>
void foo(int (&x)[N]) {
std::cerr << N;
}
模板
void foo(int&x)[N]){
std::cerr您需要将大小与数组一起传递,就像在许多库函数中一样,例如strncpy()
,strncmp()
等。抱歉,这只是C:-)中的工作方式
或者,您可以推出自己的结构,如:
struct array {
int* data;
int size;
};
并将其传递给您的代码
<>当然可以使用<代码> STD::列表< /COD>或 STD::向量< /代码>,如果你想更多的C++-ISH。 < P> >在GNU LIbSTDC++文档中提到的是<代码>长度 函数:
template<typename T, unsigned int sz>
inline unsigned int lengthof(T (&)[sz]) { return sz; }
模板
内联无符号整数长度(T(&)[sz]){return sz;}
你可以把它当作
int x[] = {1,2,3,4,5};
std::cerr << lengthof(x) << std::endl;
intx[]={1,2,3,4,5};
std::cerr数组表达式的类型将从“T的N元素数组”隐式转换为“指向T的指针”,其值将是数组中第一个元素的地址,除非数组表达式是sizeof
的操作数或(&
的地址)运算符,或者如果数组表达式是用于初始化声明中另一个数组的字符串文字。简而言之,不能将数组作为数组传递给函数;函数接收的是指针值,而不是数组值
必须将数组大小作为单独的参数传递
因为你使用C++,使用向量(或者其他合适的STL容器)代替C样式数组。是的,你失去了方便的速记语法,但是折衷是不值得的。认真。
< P>我也同意Corwin的方法是非常好的。< /P>
模板
void foo(int&x)[N])
{
自c++11以来,有一种非常方便的方法:
static const int array[] = { 1, 2, 3, 6 };
int size = (int)std::distance(std::begin(array), std::end(array))+1;
现在,您可以使用C++11的和
举例来说:
#include <iostream>
#include <type_traits>
int main()
{
int a[][3] = {{1, 2, 3}, {4, 5, 6}};
std::cout << "\nRank: : " << std::rank<decltype(a)>::value;
std::cout << "\nSize: [_here_][]: " << std::extent<decltype(a), 0>::value;
std::cout << "\nSize: [][_here_]: " << std::extent<decltype(a), 1>::value;
std::cout << "\nSize: [][]_here_: " << std::extent<decltype(a), 2>::value;
}
如果函数的用户没有按照文档的要求去做,那是他们的问题,而不是你的问题。不可能防止无知者误用API。foo
中的x
是一个指针,而不是数组。另外,请看,.dup:@Neil Butterworth:这就是private
修饰符的作用。@Brian:可能是,也可能是ot是个坏主意,这取决于上下文。为什么你认为它很糟糕?这是个好主意,因为如果你传入一个指针,它将不会编译。如果函数很大,并且使用许多不同的数组大小调用,它将生成一组函数,这是个坏主意-它将生成一组函数。另一种选择可能是,这个foo然后转过来调用private/internal foo____________________________________________________。
int x[] = {1,2,3,4,5};
std::cerr << lengthof(x) << std::endl;
template <int N>
void foo(int (&x)[N])
{
std::cerr << N;
}
int numbers [] = {1, 2, 3, 4};
for(int i = 0; i < numbers.length(); i++)
{
System.out.println(numbers[i]+"\n");
}
int numbers [] = {1, 2, 3, 4};
int size = sizeof(numbers)/sizeof(int);
for(int i = 0; i < size; i++)
{
cout << numbers[i] << endl;
}
template <int N>
int size(int (&X)[N])
{
return N;
}
template < int N >
int size(int (&X)[N])
{
int value = (sizeof(X)/sizeof(X[0]));
return value;
}
int numbers [] = {1, 2, 3, 4};
for(int i = 0; i < size(numbers); i++)
{
cout << numbers[i] << endl;
}
static const int array[] = { 1, 2, 3, 6 };
int size = (int)std::distance(std::begin(array), std::end(array))+1;
#include <iostream>
#include <type_traits>
int main()
{
int a[][3] = {{1, 2, 3}, {4, 5, 6}};
std::cout << "\nRank: : " << std::rank<decltype(a)>::value;
std::cout << "\nSize: [_here_][]: " << std::extent<decltype(a), 0>::value;
std::cout << "\nSize: [][_here_]: " << std::extent<decltype(a), 1>::value;
std::cout << "\nSize: [][]_here_: " << std::extent<decltype(a), 2>::value;
}
Rank: : 2
Size: [_here_][]: 2
Size: [][_here_]: 3
Size: [][]_here_: 0