什么是argv = NULL意味着什么?

时间:2018-04-29 04:37:16

标签: c

我试图让参数信息变得可修改。

#include <stdio.h>
#include <stdlib.h>

int main(const int argc, const char* const argv[]) {
  //argc = 1;         // error: assignment of read-only parameter 'argc'
  //argv[0] = "argv"; // error: assignment of read-only location '*argv'
  //argv[0][0] = 'a'; // error: assignment of read-only location '**argv'
  return EXIT_SUCCESS;
}

现在当我这样做时,

argv = NULL; // no compile-time error

编译器沉默。

该陈述实际上做了什么? 如何禁止我的代码执行此操作?

3 个答案:

答案 0 :(得分:10)

嗯,首先,不要这样做

我参考如何的现有答案,他们解释了const可以应用的不同级别以及如何在straight pointer syntax以及"disguised as an array"-syntax。这绝对是个好消息。

但是它来了:main非常特别。根据C标准,它没有原型,但定义应该只采用两种形式中的一种。这是原始文本,从N1570,最新草案到C11:

§5.1.2.2.1

  

程序启动时调用的函数名为main。实施宣布否   这个功能的原型。它应定义为返回类型int且没有   参数:
  int main(void) { /* ... */ }
  或者有两个参数(这里称为argcargv,但可能有任何名称   使用,因为它们是声明它们的函数的本地):
  int main(int argc, char *argv[]) { /* ... */ }
  或等效的; 10)或其他一些实现定义的方式。

脚注10甚至解释了等效的含义:

  

因此,int可以替换为定义为int的typedef名称,或者argv的类型可以写为   char ** argv,等等。

但至于添加一些const,请查看§6.7.6.1p2

  

要使两个指针类型兼容,两者都必须相同的合格并且两者都必须   是兼容类型的指针。

(强调我的)。 const是一个类型限定符。因此const char ** char **兼容。您定义的main不再符合C标准。因此,就是不要这样做。在程序中使用const正确性,但不要尝试更改程序启动的界面。

旁注:确切地说一个 const这里可能可以正常,因为它适用于指针本身,这只是一个函数的局部变量(因为参数在C函数调用中总是按值)。所以它不会改变函数的界面。这就是为什么在实践中,没有人喜欢添加这样的const。调用代码是否函数修改其本地函数并不重要。

答案 1 :(得分:8)

由于这个答案已被固定在最前面,我觉得我应该指出我的答案只能解决部分问题。有关为何不以这种方式声明main,请参见Felix Palmen's answer

如果使用数组类型声明参数,则使用指针类型隐式替换该类型:

int main(const int argc, const char* const argv[]) {

变为

int main(const int argc, const char* const *argv) {

所以argv是指向const char的const指针的非const指针。

argv = NULL只是将指针设置为空指针,就像为任何其他指针指定NULL一样。这不会有任何直接可见的外部效果 - 它不会删除你的命令行或任何东西 - 但它会干扰你在程序中使用参数信息的进一步尝试。

如果您希望argv本身为const,请将其声明为const:

int main(const int argc, const char * const * const argv) {

答案 2 :(得分:6)

您可以将const放在数组外观指针参数的括号中,以防止重新分配给它:

int main(const int argc, const char* const argv[const]) {

人们通常不会为此烦恼。