在scanf(“%s”,ss + 1)中“ ss + 1”是什么意思?

时间:2019-07-10 18:56:21

标签: c

我想知道将“ +1”放入其中是什么意思

scanf("%s", ss+1)

其中ss是字符串输入。

我正在解决有关Codechef的问题,当我尝试阅读其他解决方案以了解有关其他可能的解决方案/方法的想法时,我在代码中对此很喜欢。

2 个答案:

答案 0 :(得分:3)

假设您有以下数组:

char a[10];

我们可以想象它看起来像这样:

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

假设您调用scanf将字符串读入数组:

scanf("%s", a);

假设您键入“ hello”。数组是这样填充的:

   +---+---+---+---+---+---+---+---+---+---+
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,而是在将指针传递给scanf之前将其添加了1:

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

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

现在scanf收到一个指向数组中 second 单元格的指针,因此它是在其中写入字符串的地方:

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

这有点令人困惑。比较容易看出我们是否在侧面进行添加。查看是否我们用其他一些字符预填充数组也更容易了:

char d[10] = "rstuvwxyz";

所以最初d看起来像这样:

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

现在,如果执行此操作,然后再次键入“ hello”:

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调用之后执行此操作(如果继续键入“ hello”),则应打印{{ 1}}。

乍一看,这看起来似乎很神秘,但这是指针算术的直接应用。 (当我说诸如rhello之类的东西时,还有一点点魔术,其中p = b是一个指针,p是一个数组,指针最终指向该指针的第一个字符数组。这是C语言中非常重要的特殊规则,您很快就会想了解它。)

还有一个未解决的大问题,即为什么有人想用这种方式编写代码。这很难解释。我可以想象的一种可能是它是一个较大程序的一部分,由于某种原因,它试图将许多字符串存储到同一数组中,如下所示:

b

如果在较大的程序中,指针 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ longer_array: | c | a | t |\0 | d | o | g |\0 | c | o | w |\0 | b | e | a | r |\0 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 指向ss的前一个字符串的末尾,那么\0确实是开始读取该字符串的正确位置。下一个。

(但是我正在猜测。在没有看到更大的程序的情况下,无法知道为什么要读到ss + 1。确实这是不寻常的事情。)

答案 1 :(得分:0)

它只是跳过字符串的第一个字符。