当我是 白痴 好了,什么是C语言的解释器
解释器(英语:Interpreter),又译为直译器,是一种电脑程序,能够把高级编程语言一行一行直接转译运行
预编译器的不同在于它逐行解释运行,与解释执行语言如python相似
求解释代码,有关用c语言写一个简单的shell解释器的
#include stdio.h
#include stdlib.h
#include string.h
#include fcntl.h
#include unistd.h
#include sys/wait.h
#define CMD_LINE 1024
#define PIPE_MAX 16
#define ARG_MAX 10
typedef struct {
char *arg[ARG_MAX];
char *in;
char *out;
} cmd_t;
extern int parse_token(char *buf, cmd_t cmd[]);
extern int parse(char *buf, cmd_t * cmd);
extern int test_parse(cmd_t cmd[], int len);
int main(int argc, char *argv[])
{
char buf[CMD_LINE];
cmd_t cmd[PIPE_MAX + 1];
int fd[PIPE_MAX][2];
int j, i;
int cmd_len, pipe_len;
pid_t pid;
while (1) {
printf(“my_shell#”); //打印提示符
fgets(buf, CMD_LINE, stdin); //获得输入
buf[strlen(buf) – 1] = ‘\0’; //去掉结尾的换行符?
cmd_len = parse_token(buf, cmd);//解析命令
pipe_len = cmd_len – 1; //
if (pipe_len PIPE_MAX)
continue;
for (i = 0; i pipe_len; ++i)
pipe(fd[i]); //创建pipe_len个管道
for (i = 0; i cmd_len; ++i) //创建cmd_len个进程
if ((pid = fork()) == 0) //判断是否为子进程
break; //如果是子进程,跳出for循环
if (pid == 0) { //循环中是子进程代码
if (pipe_len) {
if (i == 0) { //第一个子进程
close(fd[i][0]); //关闭管道的读取端
dup2(fd[i][1], 1); //复制管理的写入端为标准输出(标准输出会写入管道)
close(fd[i][1]); //关闭管道的写入端
for (j = 1; j pipe_len; ++j)
close(fd[j][0]), //关闭无关进程的管道
close(fd[j][1]);
} else if (i == pipe_len) { //第pipe_len个子进程
close(fd[i – 1][1]); //关闭管道的写入端
dup2(fd[i – 1][0], 0); //复制管理的读取端为标准输出(标准输入会读取管道)
close(fd[i – 1][0]); //关闭管道的读取端
for (j = 0; j pipe_len – 1; ++j)
close(fd[j][0]), //关闭无关进程的管道
close(fd[j][1]);
} else { //其他子进程
dup2(fd[i – 1][0], 0); //复制管理的读取端为标准输出(标准输入会读取管道)
close(fd[i][0]); //关闭管道的读取端
dup2(fd[i][1], 1); //复制管理的写入端为标准输出(标准输出会写入管道)
close(fd[i][1]); //关闭管道的写入端
for (j = 0; j pipe_len; ++j) {
if ((j != i – 1) //关闭无关进程的管道
|| (j != i))
close(fd[j][0]),
close(fd[j]
[1]);
}
}
}
if (cmd[i].in) { //如果需要,打开输入文件并重定向
int fd = open(cmd[i].in, O_RDONLY);
dup2(fd, STDIN_FILENO);
close(fd);
}
if (cmd[i].out) { //如果需要,打开输出文件并重定向
int fd =
open(cmd[i].out,
O_RDWR | O_CREAT | O_TRUNC, 0644);
dup2(fd, STDOUT_FILENO);
close(fd);
}
execvp(cmd[i].arg[0], cmd[i].arg); //执行当前命令
fprintf(stderr, “Failed exec\n”); //执行命令失败后才会执行之后的代码
exit(127);
} //子进程代码结束
/* parent */
for (i = 0; i pipe_len; ++i)
close(fd[i][0]), close(fd[i][1]);
for (i = 0; i cmd_len; ++i)
wait(NULL); //等待子进程结束
}
return 0;
}
int parse_token(char *buf, cmd_t cmd[])
{
int n = 0;
#if 1
char *save_p;
char *p = strtok_r(buf, “|”, save_p);//以’|’分割命令将分割后的第一部分给p
while (p != NULL) {
parse(p, cmd[n++]);
p = strtok_r(NULL, “|”, save_p);//将之后的部分给p,每次给一部分,每调用一次给下一部分
}
#else //下一块语句不被执行
cmd[n].arg[0] = “ls”;
cmd[n].arg[1] = “-l”;
cmd[n].arg[2] = NULL;
#endif
return n;
}
int test_parse(cmd_t cmd[], int len) //此函数未被调用
{
int i;
for (i = 0; i len; ++i) {
printf(“cmd[%d]:”, i);
int j = 0;
while (cmd[i].arg[j])
printf(” %s”, cmd[i].arg[j++]);
if (cmd[i].in)
printf(“\tin:%s”, cmd[i].in);
if (cmd[i].out)
printf(“\tout:%s”, cmd[i].out);
printf(“\n”);
}
return 0;
}
int parse(char *buf, cmd_t * cmd)
{
int i = 0;
cmd-in = NULL;
cmd-out = NULL;
char *p = strtok(buf, ” “);//以空格分割命令(此时命令已被|分割过了)
while (p) {
if (*p == ”) { //如果命令以开头,即需要做输入重定向
if (*(p + 1)) //这种情况是后无空格直接跟文件名
cmd-in = p + 1;
else //这种情况是后有空格
cmd-in = strtok(NULL, ” “);
} else if (*p == ”) { //如果命令以开头,即需要做输出重定向
if (*(p + 1)) //这种情况是后无空格直接跟文件名
cmd-out = p + 1;
else //这种情况是后有空格
cmd-out = strtok(NULL, ” “);
} else
cmd-arg[i++] = p; //这种情况是正常命令或参数
p = strtok(NULL, ” “);
}
cmd-arg[i] = NULL;
return 0;
}
如何用C语言实现C的解释器
将C语言翻译成“汇编”塞到内存里,然后用“虚拟机”来跑这段汇编。
因此我们需要的东西是:
一个虚拟机:用来跑下面这种汇编。
一种汇编:用来描述原来的C语言。
一个“翻译器”:将C语言翻译成上面这种汇编。
c语言cmd窗口在哪
ㄑ
m.wangchao.net.cn
推荐

cmd窗口是什么,怎么打开
举报/纠错
分类: 电脑/网络 操作系统/系统故障
参考答案:
cmd是command的缩写.命令行
在9x系统下输入command就可以打开命令行.而在NT系统上可以输入cmd来打开.
在命令行里你可以看到你的系统版本,文件系统版本等等
你可以敲入help查看帮助
Cmd启动命令解释器 Cmd.exe 的新实例。如果在不含参数的情况下使用,则 cmd 显示 Windows XP 的版本和版权信息。
语法
cmd [[{/c|/k}] [/s] [/q] [/d] [{/a|/u}] [/t:fg] [/e:{on|off}] [/f:{on|off}] [/v:{on|off}] string]
参数
/c
执行 string 指定的命令,然后停止。
/k
执行 string 指定的命令并继续。
/s
修改位于 /c 或 /k 之后的 string 处理。
/q
关闭回显。
/d
禁用自动运行命令执行。
/a
创建美国国家标准协会 (ANSI) 输出。
/u
创建 Unicode 输出。
/t:fg
设置前景 f 和背景 g 的颜色。下表列出了可用作 f 和 g 的值的有效十六进制数字。 值 颜色
0 黑色
1 蓝色
2 绿
3 湖蓝色
4 红
5 紫色
6 黄
7 白色
8 灰色
9 浅蓝色
A 浅绿色
B 浅水绿
C 浅红色
D 浅紫色
E 浅黄色
F 亮白色
/e:on
启用命令扩展。
/e:off
禁用命令扩展。
/f:on
启用文件和目录名完成。
/f:off
禁用文件和目录名完成。
/v:on
启用延迟的环境变量扩展。
/v:off
禁用延迟的环境变量扩展。
string
指定要执行的命令。
/?
在命令提示符显示帮助。
注释
使用多个命令
可以在 string 中使用由 分隔的多个命令,不过这些命令必须置于引号之中(例如,”commandcommandcommand”)。
处理引号
如果指定了 /c 或 /k,则在满足下述所有条件的情况下,cmd 会处理 string 中的其余命令而将引号保留:
未使用 /s。
正确使用一对引号。
在引号内未使用任何特殊字符(例如: ( ) @ ^ |}。
在引号内使用了一个或多个空格子符。
引号内的 string 为可执行文件的名称。
如果上述条件不能满足,则处理 string 时将首先检查它的第一个字符以验证其是否为左引号。如果第一个字符是左引号,则它会与右引号分离开。跟在右引号之后的任何文本都会得到保留。
执行注册表子项
如果在 string 中未指定 /d,Cmd.exe 会查找下述注册表子项:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun\REG_SZ
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun REG_EXPAND_SZ
如果上述的一个注册表子项或两个都存在,则会在执行其他变量之前执行它们。
警告
编辑注册表不当可能会严重损坏您的系统。在更改注册表之前,应备份计算机上任何有价值的数据。
启用和禁用命令扩展
在 Windows XP 中,命令扩展在默认情况下是启用的。对于特定过程可以使用 /e:off 将它们禁用。通过设置下述 REG_DWORD 值,可以在计算机上或用户会话中启用或禁用所有 cmd 命令行选项的扩展:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\EnableExtensions\REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\EnableExtensions\REG_DWORD
在注册表中使用 Regedit.exe 可以将 REG_DWORD 值设为 0×1(即启用)或 0×0(即禁用)。用户特定设置优先于计算机设置,并且命令行选项优先于注册表设置。
警告
编辑注册表不当可能会严重损坏您的系统。在更改注册表之前,应备份计算机上任何有价值的数据。
启用命令扩展后,会影响到下述命令:
assoc
call
chdir (cd)
color
del (erase)
endlocal
for
ftype
goto
if
mkdir (md)
popd
prompt
pushd
set
setlocal
shift
start(还包括将更改外部命令过程)
有关这些命令的详细信息,请参阅“相关主题”。
启用延迟的环境变量扩展
启用延迟的环境变量扩展,可以使用感叹号字符来替代运行时的环境变量值。
启用文件和目录名完成
默认情况下,禁用文件和目录名完成。对于特定的 cmd 命令处理,可以通过 /f:{on|off} 来启用或禁用该功能。通过设置下述 REG_DWORD 值,可以在计算机上或用户会话中启用或禁用所有 cmd 命令处理的文件和目录名完成:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\CompletionChar\REG_DWORD
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\PathCompletionChar\REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\CompletionChar\REG_DWORD
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\PathCompletionChar\REG_DWORD
要设置 REG_DWORD 值,请运行 Regedit.exe 并使用特定功能的控制字符的十六进制值(例如,用 0×9 表示 TAB 键,用 0×08 表示 BACKSPACE 键)。用户特定设置优先于计算机设置,并且命令行选项优先于注册表设置。
警告
编辑注册表不当可能会严重损坏您的系统。在更改注册表之前,应备份计算机上任何有价值的数据。
如果使用 /f:on 启用了文件和目录名完成,则对于目录名完成,可使用 CTRL+D 组合键;而对于文件名完成,可使用 CTRL+F 组合键。要禁用注册表中特定字符的完成,请使用空格值 [0×20],因为空格不是有效的控制字符。
按 CTRL+D 或 CTRL+F 组合键时,cmd 会处理文件和目录名的完成操作。这些组合键的作用是在 string 后附加通配符(如果还未使用),并创建匹配的路径列表,然后显示第一个匹配的路径。如果所有路径都不匹配,文件和目录名完成操作会发出警告声,并且不更改所显示的内容。要逐个查看匹配路径列表中的路径,请重复按 CTRL+D 或 CTRL+F 组合键。要向后查看该列表,请在按 SHIFT 的同时按 CTRL+D 或 CTRL+F 组合键。要放弃已保存的匹配路径列表并生成新列表,可以编辑 string,然后按 CTRL+D 或 CTRL+F 组合键。如果在 CTRL+D 和 CTRL+F 组合键之间切换,将会放弃已保存的匹配路径列表并生成新列表。CTRL+D 组合键与 CTRL+F 组合键之间唯一的不同在于,CTRL+D 仅匹配目录名,而 CTRL+F 既匹配文件名,又匹配目录名。如果在任何内部目录命令(CD、MD 或 RD)中使用文件和目录名的完成,将仅使用目录的完成。
如果将匹配路径置于引号之中,则文件和目录名完成会正确地处理含有空格或特殊字符的文件名。
下述特殊字符需要有引号: [ ] { } ^ = ; ! ‘ + , ` ~ [white space]
如果您提供的信息包含空格,请将文本置于引号之中(例如,”Computer Name”)。
如果从 string 中处理文件和目录名完成操作,则位于光标右侧的 [Path] 的任意部分都将放弃(即在 string 中处理完成操作的位置)。
格式化图例
格式 含义
斜体 用户必须提供的信息
粗体 用户必须像显示的一样准确键入的元素
省略号 (…) 可在命令行中重复多次的参数
在括号 ([]) 之间 可选项目
在大括号 ({}) 之间;将选项用竖线 (|) 隔开。例如:{even|odd} 用户必须从中只选择一个选项的选项组
Courier 字体 代码或程序输出