12

我试图简单地打印出数组中包含的值。

我有一个名为“结果”的字符串数组。我不知道它到底有多大,因为它是自动生成的。

根据我的阅读,您可以通过以下方式确定数组的大小:

sizeof(result)/sizeof(result[0])

这个对吗?因为对于我的程序,sizeof(result) = 16 和 sizeof(result[0]) = 16 所以代码会告诉我我的数组大小为 1。

但是,这似乎不正确,因为如果我手动打印出这样的数组值:

std::cout << result[0] << "\n";
std::cout << result[1] << "\n";
std::cout << result[2] << "\n";
std::cout << result[3] << "\n";
etc...

...然后我看到了我正在寻找的结果值。该数组的长度/大小超过 100 个以上。

似乎确定数组的大小/长度应该非常简单......所以希望我只是在这里遗漏了一些东西。

我有点 C++ 新手所以任何帮助将不胜感激。

4

8 回答 8

12

您无法在 C++ 中动态确定数组的大小。您必须将大小作为参数传递。

附带说明一下,使用标准库容器(例如向量)可以缓解这种情况。

在您的sizeof示例中,sizeof(result)是询问指针的大小(可能是 std::string)。这是因为当传递给函数时,实际的数组类型“衰减”为指向元素的指针类型(即使函数被声明为采用数组类型)。返回数组中第一个元素的sizeof(result[0])大小,巧合的是,它也是 16 个字节。在您的平台上,指针似乎是 16 字节(128 位)。

请记住,在 C++sizeof总是在编译时进行评估,而不是在运行时进行评估。

于 2010-02-16T04:56:01.210 回答
8

作为旁注,有更好的方法来检查数组的大小(对于数组在范围内并且没有衰减为指针的情况),它们是类型安全的:

// simple: runtime result
template <typename T, std::size_t N>
inline std::size_t sizeof_array( T (&)[N] ) {
   return N;
}

// complex: compile time constant
template <typename T, std::size_t N>
char (&static_sizeof_array( T(&)[N] ))[N];   // declared, not defined
#defined SIZEOF_ARRAY( x ) sizeof(static_sizeof_array(x))

在这两种情况下,编译器都会检测您是否尝试传入指针(动态数组或衰减数组):

void f( int array[] ) { // really: void f( int *array )
{
//   sizeof_array(array);              // compile time error
//   int another[SIZEOF_ARRAY(array)]; // compile time error
}
int main() {
   int array[] = { 1, 2, 3 };
   std::cout << sizeof_array(array) << std::endl; // prints 3
   int another_array[ SIZEOF_ARRAY(array) ];
   std::cout << sizeof_array(another_array) << std::endl; // 3 again
}
于 2010-02-16T08:54:32.497 回答
3

如果你拥有的是一个“真正的”数组,那么 sizeof(x)/sizeof(x[0]) 技巧有效。然而,如果你拥有的是一个指针(例如从函数返回的东西),那么这个技巧就行不通了——你最终会用指针的大小除以指针的大小。它们指向不同类型的指针,但在典型系统上,所有指针的大小都相同,因此您会得到一个。即使指针大小不同,结果仍然与您拥有多少个字符串无关。

于 2010-02-16T04:59:05.990 回答
1

更好地使用std::vector<std::string>而不是原始数组。然后您不必手动管理数组内存,size()如果您想知道元素的数量,您可以使用该方法。

如果您使用动态分配的原始数组,您需要自己跟踪其大小,则无法从数组中获取大小。最好将其保存在一个额外的变量中。

于 2010-02-16T05:02:28.453 回答
1

sizeof(array)/sizeof(element) 适用于定长数组的定长数组(不是指针)。作为字符串数组,我们最常使用指向各种(固定)长度字符串的指针(固定长度)数组,因此这个技巧不起作用。sizeof() 用于在编译时知道大小的对象。它不适用于动态分配的数据本身。

当对象包含指针时,例如字符串数组,sizeof() 返回最高级别(固定大小)结构的大小。通常它只是单个指针的大小。它不包括指针指向的已分配数据的大小。因为该数据实际上不是主要对象的一部分,它确实是一个或多个单独的对象(我们在这里有聚合而不是组合,请参阅http://en.wikipedia.org/wiki/Object_composition)。

在 C++ 中,使用向量非常方便满足您的需求。也可以使用其他合适的标准容器。length() 和 size() 方法是同义词,请参见http://www.cplusplus.com/reference/string/string/size/ )

PS 请注意,对于 std::string s 对象 sizeof(s) 是一个常数,与 s.length() 返回的实际(可变)字符串长度无关。实际分配的内存大小由 s.capacity() 返回,并且可能大于 length()。

使用向量数组的示例:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    string s = "01234";
    cout << "s[" << s.length() << "]=\"" << s << "\"" << endl; 
    cout << "sizeof(s)=" << sizeof(s) << " (implementation dependent)" << endl;
    cout << endl;

    s += "56789012345";
    cout << "s[" << s.length() << "]=\"" << s << "\"" << endl; 
    cout << "sizeof(s)=" << sizeof(s) << " (implementation dependent)" << endl;
    cout << endl;

    vector<string>vs={"12","23","345","456","567","67888","7899999999","8","9876543210"};

    cout << "vs[" << vs.size() << "]={";
    size_t sz=0;
    for (size_t index=0; index<vs.size(); index++)
    {
        sz+=vs[index].size();
        if (index>0)
            cout << ",";
        cout << "\"" << vs[index] << "\":" << vs[index].size();
    }
    cout << "}:" << sz << endl;
    cout << "sizeof(vs)=" << sizeof(vs) << " (implementation dependent)" << endl;

    return 0;
}

结果:

s[5]="01234"
sizeof(s)=8 (implementation dependent)

s[16]="0123456789012345"
sizeof(s)=8 (implementation dependent)

vs[9]={"12":2,"23":2,"345":3,"456":3,"567":3,"67888":5,"7899999999":10,"8":1,"9876543210":10}:39
sizeof(vs)=24 (implementation dependent)
于 2014-03-02T12:40:16.600 回答
1
template< class T, size_t N >
std::size_t Length(const T(&)[N])
{
    return N;
};

std::cout << Length(another_array) << std::endl;
于 2016-04-04T12:51:00.640 回答
0

在字符串向量中使用 size() 方法

于 2010-02-16T06:52:34.243 回答
0

需要注意的一点:文本可以用不同的方法表示。文本数组也可以用不同的方法表示。

指向 C 样式字符串的指针数组

一种常见的方法是拥有一个指向char. 问题是数组的大小并不代表所有文本的大小。此外,还必须建立数据或指针的所有权,因为可能必须删除文本(被调用者可以删除文本还是调用者删除文本?)。因为它是一个数组,所以数组的大小必须始终伴随数组的所有参数(除非数组始终是固定大小)。

数组char- 压缩文本

另一种方法是传递一个数组,char并使数组中的字符串连续。一个字符串跟随前一个的终止字符。使用这个数组,可以表示所有字符串的总大小,不会浪费空间。同样,对于数组,数组的大小在传递时必须伴随数组。

数组std::string

在 C++ 中,文本可以使用std::string. 在这种情况下,数组表示字符串的数量(类似于上面的 C-Strings 数组)。要获得所有字符串的总大小,必须将每个单独字符串的大小相加。由于这是一个数组,因此还必须传递数组的大小。

概括

在运行时数组大小必须伴随数组传递时数组。 sizeof仅在编译时处理。一个更简单的结构是std::vector,它动态地处理大小和内存分配。

于 2010-02-16T18:09:04.073 回答