"argv + argc" 的意思是什么?

8

我正在编写一个程序,它可以接受命令行参数,并使用自定义比较器按字母数字顺序将它们打印出来。

在此过程中,我卡在了如何将命令行参数插入std::set容器上。查看了一些类似代码,发现了以下内容:

std::set<char*, decltype(customComparator)> args (argv, argv+argc, customComparator)

argv + argc参数是什么意思/做什么?

当我尝试插入cmd参数时,例如:

std::set<char*, decltype(customComparator)> args (argv, customComparator)

argv参数上有一个红色的波浪线。


1
argv + argv 相当于 std::end(argv),但这样不会编译通过。 - πάντα ῥεῖ
2
这不是What does int argc, char *argv[] mean?的重复。问题是argv+argc的含义,而不是argvargc本身。 - John Kugelman
4
了解“指针算术运算”,可以帮助你理解为什么。 - Kenny Ostrom
谢谢@KennyOstrom。我解决了。它指向字符数组的末尾。 - clancy
1
这是 std::set 构造函数 的第二个重载。argvargv + argc 是范围的起始和结束,customComparator 是比较器,您正在使用默认分配器。 - Nathan Pierson
1
它实际上指向包含指向单个参数的指针的数组的末尾。 - n. m.
3个回答

11

“argv + argc”的意思是一个指针,它指向最后一个命令行参数的末尾(或者指向下面图示中显示的空值)。以下是文字和图形解释。

该图显示的是argc = 5

argv + argc

解释

让我们考虑以下声明:

int main (int argc, char *argv[])
在上述声明中,名为argv的第二个参数的类型实际上是char **。也就是说,argv是一个指向char指针的指针。这是因为char* []由于类型衰减(decay),变成了 char**

换句话说,argv是一个指针,它指向一个元素类型为char*的数组的第一个元素。此外,该数组的每个元素argv[i](元素类型为char*)本身指向一个起始位置是空字符结尾(null terminated)的字符。也就是说,每个元素argv[i]指向一个元素类型为char的数组的第一个元素。


1
在你的示例中,在argv[4]之后使用NULL是正确的,以区分空指针和空字符。我明白这一点,但你不希望新用户认为它们都是相同的。 - David C. Rankin
1
@DavidC.Rankin,你认为使用其他符号更好吗?我可以在我的图中加上它。 - Jason
1
不错,我喜欢你的图表,它真的很有帮助,NULL/null 是唯一引人注目的地方。 - David C. Rankin
1
@DavidC.Rankin 哦,谢谢您的赞赏 :) - Jason
我会这样做。null 可以有不同的解释,但在字符串末尾的上下文中,它很明显表示 nul-character。但是改为 '\0' 会更清晰明了。 - David C. Rankin
显示剩余6条评论

6

您展示的代码使用了基于迭代器的构造函数,该构造函数接收一个 begin 迭代器,以及一个指向末尾的 end 迭代器。

需要注意的是,STL中指针也被视为迭代器。 ++ptr 运算符工作正常,并且 ptr != end_ptr 以及 *ptr 也可以使用。

因此,如果您想从C样式的对象集合构建STL容器,完全有可能这样做。 argv 是所有参数值的开始,而 argv[argc - 1] 则是结束。要获取末尾后面的指针,只需执行 argv + argc 即可。


“指针可以像迭代器一样运作”这句话听起来有点奇怪。迭代器是通过它们所表现的行为来定义的,而指向数组的指针本身就是一个迭代器,而不是某种类似的不同东西。 - Nathan Pierson

6
  1. std::set构造函数的这个重载接受两个迭代器和一个比较器。这两个迭代器应该定义一个左闭右开区间。第二个迭代器指向范围结尾,对于许多种类型的范围来说,它指向的是最后一个元素之后的位置。
  2. 指针是一个迭代器。
  3. 如果argv指向数组的第一个元素,并且argc是一个整数,则argv + argc指向同一数组的第argc个元素(从零开始)。
  4. 由于在argv数组中恰好有argc个有意义的元素,因此argv + argc指向数组中最后一个有意义的元素之后的位置。(在那里恰好还有另一个元素,但它是一个空指针,我们对它不感兴趣。)

总的来说,范围[argv, argv + argc)恰好是标准库在许多地方所期望的左闭右开区间类型。


你说的“半开区间”是什么意思?先谢谢了! - Milan
也许第二个迭代器被排除在外,即最后一个元素的下一个位置(参见1.)?从数学意义上讲,这是半开区间。 - Sebastian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接