Как (* argv)[0] работает в этом коде из K

#c #pointers #argv #kernighan-and-ritchie

Вопрос:

Этот вопрос касается значения некоторого синтаксиса из Главы 5, раздел 5.10 «Язык программирования C» Kamp;R2, стр. 117.

Ранее в этой главе книги Kamp;R2 они объясняли, что имя массива является указателем на его первый элемент; поэтому я знаю, что argv является указателем на первый аргумент командной строки, например ./Exercise5-10 .

Как работает синтаксис в циклах while этой программы? (* argv)[0] Я знаю, что получает первый символ строки: argv, естественно, указывает на индекс 0, который является именем программы, и увеличивается до следующего символа* или строки, затем на него снимается ссылка, * и его первый символ доступен с помощью обозначения [0]. Я просто не понимаю во внутреннем цикле, как * argv[0] происходит разбор строки.

Я даже заглянул в книгу заранее, и объяснение все еще неясно. Для меня * argv[0] сначала идет 0-й char* в argv, название программы. Затем он увеличивается до следующей строки -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 amp;amp; (*  argv)[0] == '-')
        while ((c = *  argv[0]))
            switch (c)
            {
                case 'x':
                    except = 1;
                    break;
                case 'n':
                    number = 1;
                    break;
                default:
                    printf("find: illegal option %cn", c);
                    argc = 0;
                    found = -1;
                    break;
            }
    if (argc != 1)
        printf("Usage: find -x -n patternn");
    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 amp;amp; (c = getchar()) != EOF amp;amp; c != 'n';   i)
        s[i] = c;
    if (c == 'n')
    {
        s[i] = c;
          i;
    }
    s[i] = '';
    return i;
}
 

Комментарии:

1. Это может помочь узнать, что [] имеет более высокий приоритет, чем . Поэтому argv[0] увеличивает и возвращает то, что argv[0] удерживается, а не argv .

2. Примечание: argv представляет собой массив указателей на строки. Поэтому приращение argv указывает на следующую полосу. Разыменование argv возвращает указатель на «текущий» строковый параметр

Ответ №1:

  while (--argc > 0 amp;amp; (*  argv)[0] == '-')
 

«пока осталось несколько аргументов, и первый символ следующего аргумента-это тире (и, кстати, приращение argv , указывающее на этот аргумент)». Это неявно игнорирует argv[0] , что является именем программы, так как первое, что она делает, — это увеличивает argv , чтобы указать на (то, что было раньше) argv[1] .

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

«хотя в аргументе, на который указывает argv[0] (т. Е. Мы не достигли нулевого терминатора), осталось несколько символов, и, кстати, увеличьте этот указатель, но также сохраните указанный символ как c «. Опять же, это игнорирует первый символ аргумента (который, как мы уже знаем, является a '-' ) путем увеличения перед разыменованием.

 switch (c)
 

сделайте что — нибудь с каждым символом флага. Это использует довольно старый стиль флага Unix, где флаги имеют односимвольные имена, и -abc это то же самое, -a -b -c что .

Это код в место, изменяет argc , argv , и каждый элемент argv , который содержит флаг, который будет рассмотрен довольно небрежно и запутанным сегодня, но в 1970 пространства был на вес золота (типичный машины, с целью, вероятно, есть несколько десятков килобайт памяти, и иногда даже меньше), и делая копию чего-нибудь, когда будет не нужен оригинальный снова сочли бы немного грешной. Он оставляет программу в состоянии, в котором argc указано количество аргументов без флага, и argv[0] указывает на первый аргумент без флага.