首页 > 解决方案 > 如何获取字符串列表的大小?

问题描述

我不明白需要澄清什么。请解释您的疑虑。从我的角度来看,我已经提出了一个符合所解决技术领域的问题,我已经解释了我的困惑,我已经给出了一个说明我的问题的例子,并且我已经详细说明了收到的诊断信息。这个问题的受访者充分详细地理解了我的问题、示例和诊断信息,因此他们能够做出适当的回应并纠正我的错误和误解。以什么方式可以通过适当地提出问题使这个对话更加尖锐?

@Ruzihm 说没有列表,我想在我的例子中。我想解释一下为什么这种说法是错误的。几年前有一个 LIFO 堆栈和一个 FIFO 堆栈。我们将 LIFO 堆栈称为“堆栈”,将 FIFO 堆栈称为“队列”。在英国,排在前面的队伍,例如剧院票房,是一个队列,而中国男人在蒙古征服中国后所戴的辫子也是一个队列。这一切都取决于上下文。

没有“列表”的抱怨可能源于没有<list>对象实例化的概念。但是这样的对象更恰当地称为链表,链表的链表称为图,参见例如 Gnu gSlip 文档。显然没有涉及到链表。

在 C/C++ 中,可以形成一个非矩形的多维数组。此类对象在历史上被称为“列表列表”,而不是“数组数组”。原因很清楚,'list' 是一个包含项目的对象,用编程术语来说,可以通过索引访问,如 list[index]。这并不是说链表 aka <list>不是一个“列表”,但通常的约定更明确地表明 a<list>是一个链表。

如果将问题更改为“数组数组”,那么这些示例就没有什么意义了。在比喻为 using 的术语中<list>,没有<array>'s。因此,任何对使用“列表列表”的批评都会被保留并与使用“数组数组”相关。如果一个不合适,另一个也是。

给出的答案,即使用向量的向量,是中肯的、准确的,并且正确地回答了关于列表列表的问题。如有关向量的文档中所述,例如在https://cpluscplus.com上,向量是可以通过索引访问元素的列表。在这种情况下,向量的向量是列表的特定列表,更具体地说,是锯齿状列表的列表,而不是必须是矩形的数组的数组。

我相信任何声明说发布示例以解释我在形成列表列表时的困惑是不恰当的,这表明对软件实践和行话的一些误解。问题形成正确,示例正确解决了问题。

如果此问题被删除,或以其他方式无法访问,则您支持有关该问题的格式错误的陈述。我希望不要这样做。

MSVS 16.9.1

我创建了一个字符串列表列表。我很难获得列表列表的大小或列表中字符串数组的大小。我收到相互冲突的错误消息,我不知道如何解决它们。


# include <string>

using namespace std;

static const string   x[3] = { "a", "b", "c" };
static const string   y[]  = { "a", "b", "c" };
static const string*  z[]  = { x, y };
int xSize  = x->size();
int ySize  = y->size();
int zSize  = z.size();    // expression must have class type
int zpSize = z->size();   // expression must have pointer-to-class type
int xzSize = z[0]->size();
int yzSize = z[1]->size();

错误描述如下:

C++ 中的表达式必须具有类类型错误 最后更新时间:2021 年 1 月 14 日 表达式必须具有类类型是当点 (.) 运算符用于访问对象的属性、用于指向对象的指针时引发的错误。

和:

那么这里我们有一个问题。我的 MSVS 使用 bing 进行网络搜索以寻找答案,但没有一个答案像上面的那样尖锐。要点是对象必须是指针,但不是。

结果是 zpSize 和 zSize 都不起作用,并且给出的错误是矛盾的。我难住了。

标签: c++pointers

解决方案


学习时最好避免像 C-Arrays 这样的低级结构(有一些不明显的陷阱)。

使用 C++ 容器(std::liststd::vectorstd::array),您将获得您想要的行为:

static const std::list<std::string>   x = { "a", "b", "c" };
static const std::list<std::string>   y = { "x", "y", "z" };

int xSize  = x.size();
int ySize  = y.size();

列表的列表变得有点复杂。不是因为它更难,而是您想要的实际上是其他列表的引用列表。制作列表列表很容易。

// A list of lists
std::list<std::list<string>> z = {{ "a", "b", "c" }, { "x", "y", "z" }};
int zSize  = z.size();

但是,如果您想保留原始列表以及新列表:

std::list<std:: reference_wrapper<const std::list<string>> z1 = {x,y};
int zSize1  = z1.size();

您当前代码的问题:

static const string   x[3] = { "a", "b", "c" };

x是一个 C 数组std::string。问题在于数组很容易衰减为指针。这就是这里发生的事情:

x->size(); // the array is converted into a pointer (to the first element).
           // So this will return the size of the string "a"
           // Which is 1.

你应该做的是:

x[0].size();

这是使用 C++ 容器而不是像 C-Arrays 这样的低级结构的一个很好的理由。如果您想要一个固定大小的数组,您可以使用std::array<>它并实现与 C-Array 相同的效果(并且具有相同的足迹),但具有成为一个成熟类的所有保护。


查看您对 z 的访问:

static const string*  z[]  = { x, y };

z指向 std::string 指针的 C 数组也是如此。这有更多问题,因为内存管理尚不清楚(如果我没有查看这部分代码)。

但是您可以在此处创建 z,因为 x 和 y 都会自动从数组衰减为指针。

该声明:

获取第一个元素z是指向 X 中第一个元素的指针,然后调用该对象的 size() 成员。

int xzSize = z[0]->size();

C-Arrays 没有成员,因此您无法获取它们的大小。从技术上讲,您可以计算它们的大小:

int xSize = sizeof(x) / sizeof(x[0]);

但是,如果你对指针执行此操作,它将不起作用:

// This will fail as z stores the pointer not the array.
int xzSize = sizeof (z[0]) / sizeof(z[0][0]);

推荐阅读