网站建设教程ppt,网络舆情监测存在的问题,wordpress 语法高亮,企业管理培训课程是不是传销目录
获取环境变量的后两种方法
环境变量具有全局属性
内建命令 和环境变量相关的命令
c语言访问地址 重新理解地址
地址空间 获取环境变量的后两种方法
main函数的第三个参数 #xff1a;char* env[ ]
也是一个指针数组#xff0c;我们可以把它的内容打印出来看看。 …目录
获取环境变量的后两种方法
环境变量具有全局属性
内建命令 和环境变量相关的命令
c语言访问地址 重新理解地址
地址空间 获取环境变量的后两种方法
main函数的第三个参数 char* env[ ]
也是一个指针数组我们可以把它的内容打印出来看看。 #includestdio.h #includestdlib.h #includestring.h Eint main(int argc,char* argv,char* env[]) { int i0; for(; env[i];i) {
E printf(env[%d]:%s\ni,env[i]); } return 0
}
我们再把pid也打印出来看看
输入命令
man getpid我们把这两个头文件加上 #includestdio.h #includestdlib.h #includestring.h #includesys/types.h
E#includeunistd.h
Eint main(int argc,char* argv,char* env[]) { int i0; for(; env[i];i) {
E printf(pid:%d,env[%d]:%s\n,getpid(),i,env[i]); } return 0
} 就可以把我们的此程序的环境变量打印出来
这个获取环境变量的方法和我们输入env命令获取的环境变量是一样的 我们之前说过如果我们把PATH置空很多系统命令都用不了了
但是我们重启xshell之后就又可以用了。这是因为我们置空的是加载进内存的PATH。
我们重启之后系统解释器会重新读取环境变量表形成新的环境变量环境变量是脚本配置文件的形式存在的的。
在家目录下有个隐藏文件bash_profile.
环境变量表就在这个文件里面。 假设我们自己写一个环境变量
然后用env调用环境变量通过管道只打印我们自己写的环境变量显示找不到 这是因为我们写的环境变量并没有被加载进环境变量表。
我们可以通过 export命令把我们写的环境变量加载进环境变量表里面再通过env打印就可以打印出来了。 但是我们重启xshell之后我们配置的这个环境变量仍然会消失不见。只有当我们去家目录下面的bash_profile文件下写入我们的环境变量才能再次重启之后仍然会存在。
vim ~/.bash_profile此刻我们就可以把我们自定义的变量打印出来看看 假如我们不想给main函数传参呢
有个外部变量叫 environ 它指向了char * env[ ] 我们把environ打印出来main函数不带参照样可以把环境变量打印出来。 int main()
{ extern char** environ; int i0; for(;environ[i];i) { printf(%d,%s,i,environ[i]); } return 0;
}到目前为止我们获取环境变量的方法有
main函数传参 getenv[ ] char** environ[ ] 环境变量具有全局属性
我们在我们将才的进程里再写个子进程看它能获取我们子进程的环境变量吗
#includestdio.h #includestdlib.h
#includestring.h
#includesys/types.h
#includeunistd.h int main()
{ pid_t idfork(); if(id0) { extern char** environ; int i0; for(;environ[i];i) { printf(%d,%s,i,environ[i]); } } sleep(3); return 0
} 照样可以这也证明了环境变量具有全局属性。 我们自定一个本地变量
OUR_ENV333 然后我们再把这个本地变量打印出来 #includestdio.h #includestdlib.h #includestring.h #includesys/types.h #includeunistd.h int main() {
printf(OUR_ENV_ENV:%S\n,getenv(OUR_ENV));return 0
}注意因为是子进程所以我们没export的时候子进程获取不到我们自定义的本地变量会显示为null
当我们export把我们定义的环境变量载入bash之后让它成为环境变量环境变量具有全局性子进程就可以获取到了 内建命令
我们再写几个本地变量
我们发现a,b都为本地变量echo是一个子进程但是可以直接打印本地变量 a,b这是为什么
再比如我们把PATH置空这时候ls,touch这种命令都用不了了但是echo还可以用
这是因为echo是shell的内置函数这种命令叫做linux的内建命令。
内建命令不创建子进程。 和环境变量相关的命令 set:
把本地变量和环境变量全部打印出来
set | grep本地变量名功能打印本地变量 c语言访问地址
程序的地址空间遵守的就是下面这张图
我们把这各个区的存的值的地址打印出来看看 int usa; int bbb100; int main () { printf(公共代码区:%p\n,main); const char* strhelo djwd; //常量区 printf(常量区:%p\n,str); printf(初始化全局数据区%p\n,bbb); Wprintf(未初始化全局数据区:%p\n,usa); char* heap(char*)malloc(100); printf(堆区%p\n,heap); printf(栈区:%p\n,str); 观察打印出来的地址可以发现一个问题从公共代码区到常量区再往下走地址都是呈递增状态。
当到了堆区之后从堆区到栈区中间宽度变的特别大。
按照这个结果我们可以有这种推论
得出结论堆和栈相对而生。 验证
把堆区地址打印看一下 char* heap1(char*)malloc(100);
char* heap2(char*)malloc(100);
char* heap3(char*)malloc(100);
char* heap4(char*)malloc(100); printf(堆区:%p\n,heap);
printf(堆区:%p\n,heap1);
printf(堆区:%p\n,heap2);
printf(堆区:%p\n,heap3);
printf(堆区:%p\n,heap4);
可以发现堆区越来越大这也证明堆区向上增长 把栈区地址打印一下看一下
char* strhello;
char* heap1(char*)malloc(100);
char* heap2(char*)malloc(100);
char* heap3(char*)malloc(100);
char* heap4(char*)malloc(100); printf(栈区:%p\n,str);
printf(栈区:%p\n,heap);
printf(栈区:%p\n,heap1);
printf(栈区:%p\n,heap2);
printf(栈区:%p\n,heap3);
printf(栈区:%p\n,heap4);
观察图我们发现栈区越往下越小 如果定义一个结构体object ,里面有三个成员变量 int a,b,cabc谁最大
struct d
{ int a; int b; int c;
}object; printf(%p\n,object.a);
printf(%p\n,object.b);
printf(%p\n,object.c);
很明显c最大
这是因为虽然栈区向下增长但整体是向上增长的 假设我们定义一个 int b,一个int类型有4个字节那就应该有4个地址但是我们打印b的地址显示出来只有一个这个地址就是最小的地址。
然后向上按照int类型访问4个字节访问到最大字节 类型的本质叫做偏移量
c语言中就是以起始位置偏移量访问任何地址。
定义一个int a,打印a的地址。
a因为是常量所以在栈区又因为后开辟所有地址偏小。 现在我们a重定义为 static int a此刻再重新打印a。我们发现a的地址变量它和全局变量的地址是一个样子也就是此时a就是一个全局变量
所以我们可以说已初始化全局变量区就是静态区 在栈区之上还有一个环境变量区和命令参数区 重新理解地址
地址空间 写一个子进程写一个父进程 pid_t idfork();