gpt4 book ai didi

c - 我对这个 C 程序如何工作的理解正确吗?

转载 作者:行者123 更新时间:2023-12-03 23:03:28 25 4
gpt4 key购买 nike

在以下程序中:

#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
char *delivery = "";
int thick = 0;
int count = 0;
char ch;

for (int i = 0; i < argc; i++) {
fprintf(stdout, "Argv[%i] = %s\n", i, argv[i]); /* printing to understand (ptu) */
}
while ((ch = getopt(argc, argv, "d:t")) != -1)
switch (ch) {
case 'd':
fprintf(stdout, "Optind in case 'd': %i\n", optind);
delivery = optarg;
break;
case 't':
fprintf(stdout, "Optind in case 't': %i\n", optind);
thick = 1;
break;
default:
fprintf(stderr, "Unknown option: '%s'\n", optarg);
return 1;
}
fprintf(stdout, "Argc: %i\n", argc); /* ptu */
fprintf(stdout, "Argv: %p\n", argv); /* ptu */
argc -= optind;
argv += optind;
fprintf(stdout, "Optind: %i. Argc after subtraction: %i, Argv after increment: %p\n", optind, argc, argv);
if (thick)
fprintf(stdout, "Thick crust!\n");
if (delivery[0])
fprintf(stdout, "To be delivered %s\n", delivery);
fprintf(stdout, "Ingredients:\n");
for (count = 0; count < argc; count++)
fprintf(stdout, "%s\n", argv[count]);
return 0;
}
当我使用下面显示的参数运行上述程序时,我得到以下输出:
[u@h c]$ ./prog -t -d yesterday anchovies goatcheese pepperoni
Argv[0] = ./prog
Argv[1] = -t
Argv[2] = -d
Argv[3] = yesterday
Argv[4] = anchovies
Argv[5] = goatcheese
Argv[6] = pepperoni
Optind in case 't': 2
Optind in case 'd': 4
Argc: 7
Argv: 0x7ffebee8e498
Optind: 4. Argc after subtraction: 3, Argv index: 0x7ffebee8e4b8
Thick crust!
To be delivered yesterday
Ingredients:
anchovies
goatcheese
pepperoni
我想知道我对幕后发生的事情的理解是否准确,特别是对于程序中的参数解析步骤。很抱歉没有分享一个更小的代表,但在这种情况下我可能不能。如果我能把这个展示给理解 C 的 friend ,我就不会向 stackoverflow 发送垃圾邮件。所以,请多多包涵。这里什么都没有:
  • 定义 main 以接受命令行 (cl) 参数。这需要两个参数:
  • 整数 argc 将包含 cl 参数的数量,包括程序的名称,在本例中为 7
  • 字符串数组(即 char 指针数组),其中每个元素将指向作为 cl 参数传递给程序的每个字符串文字(存储在 CONSTANT 内存块中)的第一个元素的内存地址。

  • for 循环(不言自明)
  • 在 while 循环的每次运行中,getopt() 将解析 argv[] 数组并分配 optstring "d:t" 中的下一个匹配字符。到字符变量ch , 直到它用完选项(没有双关语),这就是它返回 -1 的时间。并且控件将退出while循环。
  • 在每一次这样的传球optind (大概是从 1 开始,因为 argv[0] 是程序名称)将递增以包含 argv 中要处理的下一个元素的索引...所以在 case 't', optind = <index of "-d" i.e. 2> ,并在 case 'd', optind = <index of "anchovies" i.e. 4> (这是因为 getopt(): 中的“d ”之后的“optstring ”实现,-d 后面将跟随其 optarg 在命令行上,因此 optind 递增为这里是“4”而不是“3”)
  • -t 之后和 -d yesterday正在处理 getopt()argv[] 中找不到其他内容匹配 optstring 中的元素;因此它返回 -1我们跳出while循环。 optind仍然设置为 4,因为 getopt 在 optstring 中的“-d”之后没有找到任何其他内容。

  • 我们现在递减 optind的值“4”来自 argc以确保我们跳过 option arguments (我们已经解析)到剩下的三个 non-option论据。我们还增加 argv — 最初指向 argv[0] 的内存位置即"./prog" ——作者 <optind * sizeof(char pointer on a 64-bit machine); i.e. 4 * 8>这就是为什么 argv 现在在内存中指向 32 个字节:0x7ffebee8e4b8 - 0x7ffebee8e498 == 0x20 .换句话说,argv[0] 指向“anchovies”
  • 然后我们根据 thick 的值打印内容, delivery并循环遍历剩余的非选项参数以打印它们......
  • 最佳答案

    是的,你的理解是正确的。
    我会提供两个注意事项:

  • “字符串文字”是指在程序中实际定义的字符串,作为 "" 之间的字符。分隔符。 “常量 block ”不是标准概念,但我想您的意思是从二进制文件加载的只读内存块,因为这是字符串文字通常所在的位置。 argv 的字符串指向的指针不是这种;它们不可能,因为在创建二进制文件时不知道它们。相反,它们位于某个未指定的内存区域中,如果您愿意,您可以就地修改它们(尽管这可能会使您的代码困惑);例如argv[0][3] = 'x'将是合法的。 (C17 标准 5.1.2.2.1 (2))。
  • 有些人可能同样会发现修改 argc 的值令人困惑。和 argvmain 内,并建议您将修改后的值分配给其他一些变量:
  • int remaining_argc = argc - optind;
    char **remaining_argv = argv + optind;

    关于c - 我对这个 C 程序如何工作的理解正确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64092854/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com