(*++argv)[0] 在 K&R2 的这段代码中如何工作?

How does (*++argv)[0] work in this code from K&R2?

这个问题是关于“The C Programming Language”K&R2,第 5 章第 5.10 节中某些语法的含义。 117.

在 K&R2 书本章的前面,他们解释说数组的名称是指向其第一个元素的指针;因此,我知道 argv 是指向第一个命令行参数的指针,例如./Exercise5-10.

该程序的 while 循环中的语法是如何工作的? (*++argv)[0] 我知道获取字符串的第一个字符:argv 自然指向索引 0,即程序名称,并递增到下一个 char* 或字符串,然后用 [=13= 取消引用] 并且它的第一个字符由 [0] 表示法访问。我只是不明白在内循环中,*++argv[0] 是如何解析字符串的。

前面看了书,解释的还不是很清楚。对我来说,*++argv[0] 首先转到程序名称 argv 中的第 0 个 char*。然后它递增到下一个字符串,-x 或任何情况。然后再次取消引用从而导致第一个字符。

我不明白这一点,希望得到更多说明。

#include <stdio.h>
#include <string.h>
#define MAXLINE 1000

int getinput(char s[], int lim);

/* find: print lines that match pattern from 1st arg */
int main(int argc, char *argv[])
{
    char line[MAXLINE];
    long lineno = 0;
    int c, except = 0, number = 0, found = 0;

    while (--argc > 0 && (*++argv)[0] == '-')
        while ((c = *++argv[0]))
            switch (c)
            {
                case 'x':
                    except = 1;
                    break;
                case 'n':
                    number = 1;
                    break;
                default:
                    printf("find: illegal option %c\n", c);
                    argc = 0;
                    found = -1;
                    break;
            }
    if (argc != 1)
        printf("Usage: find -x -n pattern\n");
    else
        while (getinput(line, MAXLINE) > 0)
        {
            lineno++;
            if ((strstr(line, *argv) != NULL) != except)
            {
                printf("%ld:", lineno);
                printf("%s", line);
                found++;
            }
        }
    return found;
}

/* getline: read a line into s, return length */
int getinput(char s[], int lim)
{
    int c, i;

    for (i = 0; i < lim-1 && (c = getchar()) != EOF && c != '\n'; ++i)
        s[i] = c;
    if (c == '\n')
    {
        s[i] = c;
        ++i;
    }
    s[i] = '[=10=]';
    return i;
}
 while (--argc > 0 && (*++argv)[0] == '-')

“虽然还剩下一些参数,下一个参数的第一个字符是破折号(顺便说一句,递增 argv 以指向该参数)”。这隐含地忽略了程序名称 argv[0],因为它所做的第一件事是递增 argv 以指向(以前的)argv[1].

while ((c = *++argv[0]))

”虽然在 argv[0] 指向的参数中还剩下一些字符(即我们还没有到达空终止符),顺便说一下,增加该指针,但也保存指向- 字符为 c”。同样,这通过在取消引用之前递增来忽略参数的第一个字符(我们已经知道它是 '-')。

switch (c)

对每个标志字符做一些事情。这是使用相当古老的 Unix 标志样式,其中标志具有一个字符的名称,并且 -abc-a -b -c.

相同

此代码就地修改 argcargv 每个包含标志的 argv 元素,这将是今天被认为相当草率和令人困惑,但在 1970 年 space 是非常宝贵的(C 所针对的典型机器可能有几十千字节的内存,有时甚至更少),并制作一些东西的副本当您再也不需要原件时,会被认为有点罪恶。它使程序处于一种状态,其中 argc 非标志 参数的数量,并且 argv[0] 指向第一个非标志参数。