system()函数功能强大,很多人用却对它的原理知之甚少先看linux版system函数的源码:

 #include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h> int system(const char * cmdstring)
{
pid_t pid;
int status; if(cmdstring == NULL){
return ();
} if((pid = fork())<){
status = -;
} else if(pid = ){
execl("/bin/sh", "sh", "-c", cmdstring, (char *));
exit(); //子进程正常执行则不会执行此语句
} else{
while(waitpid(pid, &status, ) < ){
if(errno != EINTER){
status = -;
break;
}
}
} return status;
}

分析一下原理估计就能看懂了:

当system接受的命令为NULL时直接返回,否则fork出一个子进程,因为fork在两个进程:父进程和子进程中都返回,这里要检查返回的pid,fork在子进程中返回0,在父进程中返回子进程的pid,父进程使用waitpid等待子进程结束,子进程则是调用execl来启动一个程序代替自己,execl("/bin/sh", "sh", "-c", cmdstring, (char*)0)是调用shell,这个shell的路径是/bin/sh,后面的字符串都是参数,然后子进程就变成了一个shell进程,这个shell的参数是cmdstring,就是system接受的参数。在windows中的shell是command,想必大家很熟悉shell接受命令之后做的事了。

再解释下fork的原理:当一个进程A调用fork时,系统内核创建一个新的进程B,并将A的内存映像复制到B的进程空间中,因为A和B是一样的,那么他们怎么知道自己是父进程还是子进程呢,看fork的返回值就知道,上面也说了fork在子进程中返回0,在父进程中返回子进程的pid。

windows中的情况也类似,就是execl换了个又臭又长的名字,参数名也换的看了让人发晕的,我在MSDN中找到了原型,给大家看看:

 HINSTANCE   ShellExecute(
HWND hwnd,
LPCTSTR lpVerb,
LPCTSTR lpFile,
LPCTSTR lpParameters,
LPCTSTR lpDirectory,
INT nShowCmd
);

用法见下:
ShellExecute(NULL, "open", "c:\\a.reg", NULL, NULL, SW_SHOWNORMAL);

你也许会奇怪 ShellExecute中有个用来传递父进程环境变量的参数 lpDirectory,linux中的execl却没有,这是因为execl是编译器的函数(在一定程度上隐藏具体系统实现),在linux中它会接着产生一个linux系统的调用 execve, 原型见下:
int execve(const char * file,const char **argv,const char **envp);

看到这里就会明白为什么system()会接受父进程的环境变量,但是用system改变环境变量后,system一返回主函数还是没变。原因从system的实现可以看到,它是通过产生新进程实现的,从我的分析中可以看到父进程和子进程间没有进程通信,子进程自然改变不了父进程的环境变量。

使用了system函数就能执行dos指令。

 #include <stdio.h>
#include <stdlib.h> xiaoyu()
{
char *a;
int n=;
FILE *f;
f=fopen("file.bat","w+");/*新建一个批处理*/
if(f==NULL) {
exit();
} a="echo"; /*DOS命令*/
for(n=;n<=;n++) {/*大写A-Z*/
fprintf(f,"%s %c\n",a,n);/*利用ASCII码输出A-Z,写出批处理*/
}
fclose(f);
system("file.bat");/*运行批处理*/
} int main(int argc, char argv[])
{
char *string; xiaoyu();
string="echo C语言的system函数\n";/*输出中文*/
system(string);
system("pause");/*程序暂停*/
return ;
}

C中可以使用DOS命令,以后编程通过调用DOS命令很多操作就简单多了。

转至:C语言中system()函数的用法总结

C语言中system()函数的用法总结(转)的更多相关文章

  1. C语言中sprintf()函数的用法

    sprintf函数的用法 1.该函数包含在stdio.h的头文件中. 2.sprintf和平时我们常用的printf函数的功能很相似.sprintf函数打印到字符串中,而printf函数打印输出到屏幕 ...

  2. C语言中strtod()函数的用法详解

    函数原型: #include <stdlib.h> double strtod(const char *nptr, char **endptr); C语言及C++中的重要函数. 名称含义 ...

  3. C语言中qsort函数用法

    C语言中qsort函数用法-示例分析    本文实例汇总介绍了C语言中qsort函数用法,包括针对各种数据类型参数的排序,非常具有实用价值非常具有实用价值. 分享给大家供大家参考.C语言中的qsort ...

  4. R语言中apply函数

    前言 刚开始接触R语言时,会听到各种的R语言使用技巧,其中最重要的一条就是不要用循环,效率特别低,要用向量计算代替循环计算. 那么,这是为什么呢?原因在于R的循环操作for和while,都是基于R语言 ...

  5. 使用C语言中qsort()函数对浮点型数组无法成功排序的问题

    一 写在开头 1.1 本节内容 本节主要内容是有关C语言中qsort()函数的探讨. 二 问题和相应解决方法 qsort()是C标准库中的一个通用的排序函数.它既能对整型数据进行排序也能对浮点型数据进 ...

  6. C语言中malloc函数返回值是否需要类型强制转换问题

    1. 在C语言中, 如果调用的函数没有函数原型, 则其返回值将默认为 int 型. 考虑调用malloc函数时忘记了 #include <stdlib.h>的情况 此时malloc函数返回 ...

  7. (转)C语言中Exit函数的使用

    C语言中Exit函数的使用 exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如 ...

  8. C语言中malloc函数的理解

    在C语言中malloc函数主要是用在堆内存的申请上,使用malloc函数时,函数会返回一个void *类型的值,这个值就是你申请的堆内存的首地址:为什么返回的地址是一个void *类型的地址呢?首先我 ...

  9. 关于C语言中printf函数“输出歧视”的问题

    目录 关于C语言中printf函数"输出歧视"的问题 问题描述 探索问题原因 另一种研究方法 问题结论 关于C语言中printf函数"输出歧视"的问题 问题描述 ...

随机推荐

  1. iOS应用架构谈 view层的组织和调用方案

    当我们开始设计View层的架构时,往往是这个App还没有开始开发,或者这个App已经发过几个版本了,然后此时需要做非常彻底的重构. 一般也就是这两种时机会去做View层架构,基于这个时机的特殊性,我们 ...

  2. vim - multiple windows

    https://www.cs.oberlin.edu/~kuperman/help/vim/windows.html

  3. Oracle中的rownum和rowid

    http://blog.csdn.net/mitedu/article/details/3584399  rownum http://blog.csdn.net/mitedu/article/deta ...

  4. django静态文件数据库设置

    STATIC_URL = '/static/'STATICFILES_DIRS = (        os.path.join(BASE_DIR,'static')) DATABASES = {    ...

  5. kafka java代码实现消费者

    public class KafkaConsumer { public static void main(String[] args) { Properties props = new Propert ...

  6. Tomcat6.0+Jdk1.5+Axis1.3搭建java webservice环境,并使用c#调用该服务。

    java jdk:jdk1.5.0_17 下载网址:http://pan.baidu.com/s/1gdmAkgV tomcat 6.0 下载地址:http://tomcat.apache.org/d ...

  7. MVC HtmlHelper用法(一)@Html.BeginForm的使用总结

    1.@using(Html.BeginForm()){}                                                      //提交到当前页面 2.@using ...

  8. winform 窗体移动API、窗体阴影API

    //窗体移动API [DllImport("user32.dll")] public static extern bool ReleaseCapture(); [DllImport ...

  9. request.get request.GET……

    发现他们是不同的. 报错: AttributeError at /add/ 'WSGIRequest' object has no attribute 'get' Request Method: GE ...

  10. 4.用PHP打印出前一天的时间格式是2006-5-10 22:21:21

    echo date('Y-m-d H:i:s', strtotime('-1 days'));