что означает "ss + 1" в scanf ("% s", ss + 1)? - PullRequest
0 голосов
/ 10 июля 2019

Я хочу знать, что значит поместить «+1» в

scanf("%s", ss+1)

где ss - строковый ввод.

Я решал вопрос о codechef, и когда я попытался прочитать некоторые другие решения, чтобы получить представление о других возможных решениях / подходах, я нашел это в коде.

Ответы [ 2 ]

3 голосов
/ 11 июля 2019

Предположим, у вас есть этот массив:

char a[10];

Мы можем представить, что это выглядит так:

   +---+---+---+---+---+---+---+---+---+---+
a: |   |   |   |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+

Предположим, вы вызываете scanf, чтобы прочитать строку в массив:

scanf("%s", a);

Предположим, вы набрали "привет".Массив заполняется так:

   +---+---+---+---+---+---+---+---+---+---+
a: | h | e | l | l | o |\0 |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+

Предположим, вы установили указатель, указывающий на массив, и передали этот указатель в scanf:

char b[10];
char *p = b;

scanf("%s", p);

Теперь точно так жепроисходит: p указывает на начало строки, поэтому scanf хранит строку, которую она читает:

       +---+---+---+---+---+---+---+---+---+---+
    b: | h | e | l | l | o |\0 |   |   |   |   |
       +---+---+---+---+---+---+---+---+---+---+
         ^
   +-----|-----+
p: |     *     |
   +-----------+

Наконец, предположим, что у нас есть другой массив и другой указатель, но вместо передачиуказатель на scanf, мы добавляем 1 к указателю перед передачей его на scanf:

char c[10];
char *ss = c;

scanf("%s", ss + 1);

Теперь scanf получает указатель на вторую ячейку в массивевот где она записывает строку:

        +---+---+---+---+---+---+---+---+---+---+
     c: |   | h | e | l | l | o |\0 |   |   |   |
        +---+---+---+---+---+---+---+---+---+---+
          ^
    +-----|-----+
ss: |     *     |
    +-----------+

Это немного сбивает с толку.Проще увидеть, если мы сделаем сложение в стороне.Также легче увидеть, если мы предварительно заполним массив некоторыми другими символами:

char d[10] = "rstuvwxyz";

Итак, изначально d выглядит так:

        +---+---+---+---+---+---+---+---+---+---+
     d: | r | s | t | u | v | w | x | y | z |\0 |
        +---+---+---+---+---+---+---+---+---+---+

Теперь, если мы сделаем это,и снова введите «привет»:

char *p1 = d;
char *p2 = p1 + 1;

scanf("%s", p2);

в итоге получается картинка, которая выглядит следующим образом:

    +-----------+
p1: |     *     |
    +-----|-----+
          |
          v
        +---+---+---+---+---+---+---+---+---+---+
     d: | r | h | e | l | l | o |\0 | y | z |\0 |
        +---+---+---+---+---+---+---+---+---+---+
              ^
        +-----|-----+
    p2: |     *     |
        +-----------+

scanf читает где p2 указывает, что является одниммимо, где p1 указывает, что находится в начале массива d.

Если вы хотите подтвердить, что происходит, вы можете сделать printf("%s\n", d).Если вы сделаете это до вызова scanf, он должен вывести rstuvwxyz, а если вы сделаете это после вызова scanf (и если вы продолжите набирать «привет»), он должен вывести rhello.

Поначалу все может показаться довольно загадочным, но это простое применение арифметики указателей .(Когда я говорю такие вещи, как p = b, где p - это указатель, а b - это массив, а указатель заканчивается указанием на первый символ массива.специальное правило в C, о котором вы захотите узнать в скором времени.)

Есть еще один большой вопрос без ответа, а именно , почему кто-то захочет написать код таким образом,Это сложнее объяснить.Одна возможность, которую я могу себе представить, состоит в том, что она была частью более крупной программы, которая по какой-то причине пыталась сохранить много строк в одном массиве, например:

              +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
longer_array: | c | a | t |\0 | d | o | g |\0 | c | o | w |\0 | b | e | a | r |\0 |
              +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

Если в более крупной программе,указатель ss указывает на \0 a конец предыдущей прочитанной строки, тогда ss + 1 - действительно правильное место для начала чтения следующей.

(Но я размышляю.Не видя большую программу, невозможно понять, почему она захотела прочитать в ss + 1. Действительно, это необычно.)

0 голосов
/ 10 июля 2019

Он просто пропускает первый символ строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...