extern char ** environ和extern char * environ []之间有什么区
#include <stdio.h> #include <stdlib.h> #include <unistd.h> extern char *environ[]; int main(int argc,char *argv[]) { int index = 0; char **env = environ; printf("Environment variables:n"); index = 0; while (env[index]) { printf("envp[%d]: %sn",index,env[index]); ++index; } return 0; } 输出: Environment variables: envp[0]: GH#t 我想打印所有环境,但它无法正常工作. Environment variables: envp[0]: XDG_SESSION_ID=8 envp[1]: TERM=xterm envp[2]: SHELL=/bin/bash envp[3]: SSH_CLIENT=192.168.1.224 1085 22 envp[4]: SSH_TTY=/dev/pts/0 ... 解决方法
我发现这些东西不可能不考虑实际内存中的内容,以及它是如何组织的.
内存中的某个地方是一堆包含环境字符串的数据块 – “foo = bar”,“hello = world”等等.让我们假设为了论证,“foo = bar”在地址100,“hello = world”在地址200. 内存中的其他位置是另一个列出这些数据块地址的数据块(通常后跟零,所以我们知道列表实际结束的位置,如果我们事先不知道大小}.所以这个块包含数据 {100,200,0} 如果我将此数据定义为char * env [],这意味着内存中有一个名为env的位置,并且该位置是实际数据块{100,0}.也就是说,env本身的数据将是数字100,它是一个环境字符串的地址. env之后的下一个位置将包含200,然后是0之后的下一个位置(好的,我正在简化一点). 如果我将数据块{100,0}定义为char **,则意味着内存中有一个名为env的位置,其中包含数据块{100,0}的地址.存储在env中的数据不是“100”(字符串的地址).它将是一个指示数据块开始的地址{1??00,0}. 在C程序中,环境实际上是一个char **,也就是说,environ不是字符串地址列表的开头,它是字符串地址列表的地址.要查看它,您可以错误地定义它,然后更正它,就像在原始代码的这个修改版本中一样: extern char *environ[]; int main(int argc,char *argv[]) { int index = 0; char **env = (char **)environ[0]; printf("Environment variables:n"); index = 0; while (env[index]) { printf("envp[%d]: %sn",env[index]); ++index; } return 0; } 使用char * environ []告诉编译器(错误地)名为environ的位置开始一个指向字符串的指针列表,从那一点开始在内存中一个接一个地排列.实际上,只有确切位置环境中的数据才是相关的.我们可以将该数据视为environ [0],并将其转换为真实数据类型,这是一个char **. char **和char * []之间的差异被侵蚀,因此C将不允许将数组传递给函数,这使得混淆.函数的所有参数都是单个数字 – 可以是整数或浮点数的基元,也可以是某个地址.如果尝试传递数组(即数据块),则会传递块开头的地址.这意味着在大多数代码中,您实际上可以使用char **和char * [],就好像它们是相同的东西.你会遇到问题 – 就像这个问题一样 – 当数据以某种方式排列在内存中时,除非程序员通过使用正确的类型声明告诉它,否则编译器无法解决这种问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |