我一直在研究散列表,以及如何在C ++中通过链接创建它们。在我发现的代码示例中,列表和存储桶的声明如下:
int bucket;
std::list<int> *table;
然后,在程序中的其他地方称为:
table[bucket].push_back(1);
我的问题是,当声明为*表时,为什么可以使用方括号运算符[],但是如果声明时不带*,那么我将不再使用方括号运算符?
ex:
std::list<int> *table;
table[bucket].... OKAY
std::list<int> table;
table[bucket]... NOT OKAY
所以当使用*时,就像每个存储桶都有一个列表。所以table [1]是一个列表,table [2]是另一个列表。他们如何通过使用*来实现这一目标?
我已经注意到我也可以使用其他类型的代码进行此操作
ex:
int *test;
test[index]... OKAY
int test;
test[index]... NOT OKAY
这显然与指针声明有关,但是经过无数次阅读和环顾之后,我似乎无法理解这一点。我的想法是“ std :: list * table”创建一个指向列表的指针。但这并不清楚我现在如何使用[]。
任何澄清都将不胜感激。
如果指针是数组,则可以使用[]
运算符。这就是为什么它可以编译。但是,您的指针未初始化,因此使用它来访问任何内容都是未定义的行为。这就是为什么出现使用指针的原因。
std::list
类不支持随机访问,因此不支持[]
运算符。这就是为什么当您未将其定义为指针时它不会编译的原因。
“指针算术”是要理解的关键概念。
对于std::list<int> table
(†),table[1]
等于*(table + 1)
。从概念上说,这是“查看表指向的内存地址。向右看sizeof(table)
,然后给我那里的std::list<int>
。
(†)或任何其他类型,但为了确保与您的问题保持一致,我坚持使用std::list<int>
。
举个例子,如果我们有以下内容:
const char* foo = "Hi!";
那么以下是等效的:
foo[2];
*(foo + 2);
*(2 + foo);
2[foo];