C++ main()函数中第三个环境变量参数有什么用途?

8

我已经了解到char **envpmain函数的第三个参数,通过以下代码的帮助,我能够查看它实际包含的内容。

int main(int argc, char *argv[], char *env[])
{
  int i;
  for (i=0 ; env[i] ; i++)
    std::cout << env[i] << std::endl;
  std::cout << std::endl;
}

我的问题是:程序员在什么情况下需要使用这个参数?我已经找到了很多关于这个参数的解释,但没有一个能告诉我它通常在哪里使用。试图理解这可能在哪些实际情况下使用。


3
这是早期POSIX标准之前的老Unix版本。甚至苹果CRT(C运行时库)也传递了第四个参数。现在不再需要它,因为自C89起,getenv()被标准化了。 - Hans Passant
4
虽然getenv()函数可以帮助你找到已知环境变量的值,但它无法帮助你找到未知名称的环境变量的值。通过main()函数的参数envp和全局变量environ,你才能够找到所有的环境变量。因此,单独使用getenv()函数并不能替代envp参数。 - Jonathan Leffler
C和C++中main()函数应该返回什么?密切相关,但略有不同的是作为main()函数第三个参数的char *envp[]是否可移植?也很有趣。 - Jonathan Leffler
哇,我不知道 C/C++ 的这个特性!回想起来,我能在这里找到它 http://en.cppreference.com/w/cpp/language/main_function (3)。 - alfC
在POSIX系统上,环境变量也可以通过全局变量environ进行访问,该变量声明为extern char **environ;在<unistd.h>中,并且可以通过main函数的可选第三个参数envp进行访问。此外,从http://en.cppreference.com/w/cpp/utility/program/getenv中可以看到,全局变量char **environ具有相同的信息。 - alfC
4个回答

11

这是一个包含所有环境变量的数组。它可以被用来获取当前登录用户的用户名或主目录,例如,如果我想在用户的主目录中保存一个配置文件并需要获取 PATH,那么就可以使用它。

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

std::cout << env[11] << '\n';  //this prints home directory of current user(11th for me was the home directory)

return 0;
}

env的等价函数是char* getenv (const char* name)函数,该函数更易于使用,例如:

 std::cout << getenv("USER");

输出当前用户的用户名。


1
@srihari 我不明白,你为什么需要访问用户密码?没有环境变量保存用户密码。 - khajvah
哇,我不知道 C/C++ 还有这个特性!说实话,出于某种原因,我觉得使用带有三个参数的 main 函数比使用 getenv 更加优雅。特别是因为它为环境变量提供了具体的作用域,而不是全局的。 - alfC
@alfC 环境变量在本质上是进程全局的,因此在全局范围内使用是可以的。当然,您可以通过随意在各处使用getenv来滥用它,但这并不是它的问题 :)。 - khajvah
1
@alfC 这不是关于新旧的问题。据我所知,只有 getenv 是 C 标准的一部分,这就是为什么人们建议不要使用 envp 的原因。https://dev59.com/0Wkv5IYBdhLWcg3w1kIJ#10321474 - khajvah
2
@alfC 另一种方法是使用 getenv,这是由 C 标准定义的标准方式。 - khajvah
显示剩余2条评论

8

getenv()函数允许您查找特定环境变量的值,但不提供扫描整个环境变量列表的机制。而envp参数可以让您迭代整个环境变量列表,正如您的演示代码所示,这是使用getenv()接口无法实现的。

在POSIX系统上,有一个全局变量extern char **environ;,它也指向环境变量。函数putenv()(古老的、不推荐使用,因为它会出现内存管理问题)、setenv()unsetenv()也可以操作环境变量列表(由environ定义)。程序可以直接修改environ或它所指的值,但这不可取。

如果您使用fork()exec*()函数族,除非您使用execve()并显式指定环境,否则子进程将接收由environ定义的环境。

没有头文件声明environ —— 据我所知,这是POSIX定义的唯一一个没有头文件声明的变量。C标准识别了int main(int argc, char **argv, char **envp)签名作为标准的常见扩展,在附录J中有文档记录。


2

这通常用于设置一组程序的配置选项或其他信息。另一个用途是为特定的计算机或用户设置指定环境设置。
著名的例子是包含可执行文件查找路径的PATH变量,或包含查找共享库路径的LD_LIBRARY_PATH变量。


1
env 允许您访问环境变量。它包含一个字符串数组。例如,用户的主目录、配置语言方案、PATH 变量(用于查找可直接执行程序的位置)等。
您还可以设置单个环境变量。例如,如果您有测试(学习)和生产系统,您将应用部署到这两个系统中。在一个系统上,您可以设置变量“MY_APP_MODE=TEST”,而在另一个系统上,您可以指定“MY_APP_MODE=PROD”。因此,您不需要将不同的应用程序部署到测试和生产系统中。您的应用程序可以自行确定运行环境。

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