C中指针的解释(也是操纵数组)

时间:2013-10-25 10:54:42

标签: c arrays pointers

我最近得到了这段代码作为家庭作业分析(最近我的意思是大约3周前)。我们应该逐行检查代码并确定打印语句(不编译/运行)。

我大约一半通过它,然后指针开始操纵一组int,我只是无法跟踪它了。任何人都可以帮助解释被操纵的值和原因吗?

我想这个代码和一个很好的解释对于我来说是巨大的帮助,而不是那些来自没有指针的语言的人。

以下是代码(注意,评论是我自己的,而不是教师的):

int main() {
  // Pointers (* var_name) point to an address in memory. They can be
  // dereferenced by using (* var_name) during assignment. The operator (&)
  // gives the address in memory of a variable, which is useful for assigning
  // pointers to (point) to that location in memory (a type of assignment).

  int i = 50, j = 100;
  int k[] = {10, 20, 30, 40, 50};

  // Declare a pointer to p, and a pointer to q
  int *p, *q;

  // Declare a pointer to a pointer s
  int **s;

  // Declare a pointer to a pointer to a pointer t
  int ***t;

  // Since p points to an address in memory, and & gives the address in memory,
  // assign p to be the same memory location as i
  p = &i;

  printf("%d %d\n", i, *p);

  // Since q points to an address in memory, and & gives the address in memory,
  // assign q to be the same memory location as j
  q = &j;

  printf("%d %d\n", j, *q);

  // Since s points to a pointer to an address in memory, and & gives the address 
  // in memory, assign s to be the same memory location as p
  s = &p;

  printf("%d %d\n", *p, **s);

  // Since t points to a pointer to a pointer to an address in memory, and & gives 
  // the address in memory, assign t to be the same memory location as s. Since s
  // points to the same location as p, t now points to the same location as t.
  t = &s;

  printf("%d %d %d %d\n", *p, *q, **s, ***t);

  // The pointer p now has the same reference (in memory) as the pointer q
  p = q;

  printf("%d %d %d %d\n", *p, *q, **s, ***t);

  // Since s points to a pointer to an address in memory, and & gives the address 
  // in memory, assign s to be the same memory location as q. Since p and q point
  // to the same location, an equivalent statement is (s = &p)
  s = &q;

  printf("%d %d %d %d\n", *p, *q, **s, ***t);

  /*
   * This is where I get seriously lost, and I really have no clue.
   */
  // p now points to the first element of k, because the first element of k is
  // equivalent to *k (they are both pointers)
  p = k;
  *p = *q;
  p++;
  s = &p;
  **s = 500;
  q = p + 2;
  *q = 1000;
  p = q - 1;
  *p = 750;
  q ++;
  *q = *q * 100;

  printf("%d %d %d %d %d\n", k[0], k[1], k[2], k[3], k[4]);

  **s = -100;
  ***t = -200;

  printf("%d %d %d %d %d\n", k[0], k[1], k[2], k[3], k[4]);

  printf("%d %d %d %d %d %d\n", i, j, *p, *q, **s, ***t);

  return 0;
}

编译并运行时,它会提供以下输出(供参考):

50 50

100 100

50 50

50 100 50 50

100 100 100 100

100 100 100 100

100 500 750 1000 5000

100 500 -200 1000 5000

50 100 -200 5000 -200 -200

所以我想知道,在大约10次操纵的巨大块中会发生什么?我无法遵循它。另外,如果我在代码中的评论是错误的,请告诉我,这只是我对它的理解。

PS - 我知道语句p = k指定指针p指向int[] k的第一个元素,但我不知道关于k ......

的那一点会发生什么

3 个答案:

答案 0 :(得分:5)

所以,让我们一步一步来。我只会向您展示记忆操作并让您找出正在打印的内容。每个内存位置(方框)上方是其各自的地址,内部是其内容。

请注意,变量上方的内存地址是指示性的。无法保证变量将以这种方式放置在堆栈中(很可能是他们赢了)。

int *p, *q;

在这里,您不要声明指向pq",而是指向int的2个指针,称为pq

int **s;
int ***t;

相同,指向int的指针,指向s,指针指向指向int t的指针。

所以,让我们来'''到目前为止的记忆。

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |
    +------+     +------+

  k: 0x1008       0x100C 0x1010 0x1014 0x1018 0x101C
    +------+     +------+------+------+------+------+
    |0x100C|---->|  10  |  20  |  30  |  40  |  50  |
    +------+     +------+------+------+------+------+

  p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C
    +------+     +------+     +------+     +------+
    |XXXXXX|     |XXXXXX|     |XXXXXX|     |XXXXXX|
    +------+     +------+     +------+     +------+

现在,让我们运行代码:

p = &i;

现在p指向i

  i: 0x1000    j: 0x1004
    +------+     +------+
+-->|  50  |     |  100 |
|   +------+     +------+
|
| k: 0x1008       0x100C 0x1010 0x1014 0x1018 0x101C
|   +------+     +------+------+------+------+------+
|   |0x100C|---->|  10  |  20  |  30  |  40  |  50  |
|   +------+     +------+------+------+------+------+
|
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C
|   +------+     +------+     +------+     +------+
+---|0x1000|     |XXXXXX|     |XXXXXX|     |XXXXXX|
    +------+     +------+     +------+     +------+

下一个命令是:

q = &j;

现在q指向j

  i: 0x1000    j: 0x1004
    +------+     +------+
+-->|  50  |     |  100 |<------------------------------------+
|   +------+     +------+                                     |
|                                                             |
| k: 0x1008       0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+     +------+------+------+------+------+         |
|   |0x100C|---->|  10  |  20  |  30  |  40  |  50  |         |
|   +------+     +------+------+------+------+------+         |
|                                                             |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1000|     |0x1004|-+   |XXXXXX|     |XXXXXX|           |
    +------+     +------+ |   +------+     +------+           |
                          |                                   |
                          +-----------------------------------+

接下来我们有:

s = &p;

s是指向int指针的指针,而p是指向int的指针。现在s指向p

  i: 0x1000    j: 0x1004
    +------+     +------+
+-->|  50  |     |  100 |<------------------------------------+
|   +------+     +------+                                     |
|                                                             |
| k: 0x1008       0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+     +------+------+------+------+------+         |
|   |0x100C|---->|  10  |  20  |  30  |  40  |  50  |         |
|   +------+     +------+------+------+------+------+         |
|                                                             |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1000|     |0x1004|-+   |0x1020|     |XXXXXX|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

接下来:

t = &s;

t是指向int指针的指针,s是指向int的指针。现在t指向s

  i: 0x1000    j: 0x1004
    +------+     +------+
+-->|  50  |     |  100 |<------------------------------------+
|   +------+     +------+                                     |
|                                                             |
| k: 0x1008       0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+     +------+------+------+------+------+         |
|   |0x100C|---->|  10  |  20  |  30  |  40  |  50  |         |
|   +------+     +------+------+------+------+------+         |
|                                                             |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1000|     |0x1004|-+   |0x1020|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

下一步:

p = q;

我们将q的内容分配给p。这意味着p不再指向i,但它现在指向q指向的位置,即j

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |  +->|  100 |<------------------------------------+
    +------+  |  +------+                                     |
+-------------+                                               |
| k: 0x1008       0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+     +------+------+------+------+------+         |
|   |0x100C|---->|  10  |  20  |  30  |  40  |  50  |         |
|   +------+     +------+------+------+------+------+         |
|                                                             |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1004|     |0x1004|-+   |0x1020|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

下一步:

s = &q;

我们指定s指向q的地址。因此,现在s不再指向p,而是指向q

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |  +->|  100 |<------------------------------------+
    +------+  |  +------+                                     |
+-------------+                                               |
| k: 0x1008       0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+     +------+------+------+------+------+         |
|   |0x100C|---->|  10  |  20  |  30  |  40  |  50  |         |
|   +------+     +------+------+------+------+------+         |
|                                                             |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1004|     |0x1004|-+   |0x1024|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
                     ^    |      |                            |
                     |    +------+----------------------------+
                     |           |
                     +-----------+

下一步:

p = k;

我们将k的内容分配给p。所以现在p指向k指向的位置,这是数组的第一个元素:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |<------------------------------------+
    +------+     +------+                                     |
+-------------+                                               |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  +->+------+------+------+------+------+         |
|   |0x100C|---->|  10  |  20  |  30  |  40  |  50  |         |
|   +------+     +------+------+------+------+------+         |
|                                                             |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x100C|     |0x1004|-+   |0x1024|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
                     ^    |      |                            |
                     |    +------+----------------------------+
                     |           |
                     +-----------+

下一步:

*p = *q;

此命令说:&#34;获取q指向的位置的内容,并将其分配到p指向的位置&#34;。 q指向j,等于100,p指向数组的第一个元素:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |<------------------------------------+
    +------+     +------+                                     |
+-------------+                                               |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  +->+------+------+------+------+------+         |
|   |0x100C|---->|  100 |  20  |  30  |  40  |  50  |         |
|   +------+     +------+------+------+------+------+         |
|                                                             |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x100C|     |0x1004|-+   |0x1024|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
                     ^    |      |                            |
                     |    +------+----------------------------+
                     |           |
                     +-----------+

下一步:

p++;

这是&#34;棘手&#34;命令(虽然当你意识到正在发生的事情时并不那么棘手)。在正常情况下,这会将p变量增加1.但因为p是一个指针,它将增加它(应该)所指向的变量类型的大小,以便p指向下一个内存位置。在这种情况下,sizeof(int)即{4}(这不一定是真的)。所以现在p指向数组的下一个单元格:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |<------------------------------------+
    +------+     +------+                                     |
+-------------+                                               |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  |  +------+------+------+------+------+         |
|   |0x100C|--+->|  100 |  20  |  30  |  40  |  50  |         |
|   +------+  |  +------+------+------+------+------+         |
|             +-------------^                                 |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1010|     |0x1004|-+   |0x1024|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
                     ^    |      |                            |
                     |    +------+----------------------------+
                     |           |
                     +-----------+

下一步:

s = &p

s指向p的位置:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |<------------------------------------+
    +------+     +------+                                     |
+-------------+                                               |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  |  +------+------+------+------+------+         |
|   |0x100C|--+->|  100 |  20  |  30  |  40  |  50  |         |
|   +------+  |  +------+------+------+------+------+         |
|             +-------------^                                 |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1010|     |0x1004|-+   |0x1020|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

下一步:

**s = 500;

此命令显示:&#34;转到s指向的位置并获取其内容,让我们将其称为*s,然后转到{{1}的位置}指向并指定值500. *s指向sp指向第二个数组单元格:

p

下一步:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |<------------------------------------+
    +------+     +------+                                     |
+-------------+                                               |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  |  +------+------+------+------+------+         |
|   |0x100C|--+->|  100 |  500 |  30  |  40  |  50  |         |
|   +------+  |  +------+------+------+------+------+         |
|             +-------------^                                 |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1010|     |0x1004|-+   |0x1020|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

此处,如上所述,由于q = p + 2; q是指针,因此此命令会将pq的内容分配给p2 * sizeof(int)指向第二个数组单元格,所以现在p指向第4个数组单元格:

q

下一步:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |                 +-------------------+
    +------+     +------+                 |                   |
+-------------+                           v                   |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  |  +------+------+------+------+------+         |
|   |0x100C|--+->|  100 |  500 |  30  |  40  |  50  |         |
|   +------+  |  +------+------+------+------+------+         |
|             +-------------^                                 |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1010|     |0x1018|-+   |0x1020|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

转到*q = 1000; 指向的位置并指定1000:

q

下一步:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |                 +-------------------+
    +------+     +------+                 |                   |
+-------------+                           v                   |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  |  +------+------+------+------+------+         |
|   |0x100C|--+->|  100 |  500 |  30  | 1000 |  50  |         |
|   +------+  |  +------+------+------+------+------+         |
|             +-------------^                                 |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1010|     |0x1018|-+   |0x1020|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

p = q - 1; 现在将指向p指向的上一个位置,即第三个数组单元格:

p

下一步:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |                 +-------------------+
    +------+     +------+                 |                   |
+-------------+                           v                   |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  |  +------+------+------+------+------+         |
|   |0x100C|--+->|  100 |  500 |  30  | 1000 |  50  |         |
|   +------+  |  +------+------+------+------+------+         |
|             +-------------------^                           |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1014|     |0x1018|-+   |0x1020|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

转到*p = 750; 指向的位置并指定750:

p

下一步:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |                 +-------------------+
    +------+     +------+                 |                   |
+-------------+                           v                   |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  |  +------+------+------+------+------+         |
|   |0x100C|--+->|  100 |  500 |  750 | 1000 |  50  |         |
|   +------+  |  +------+------+------+------+------+         |
|             +-------------------^                           |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1014|     |0x1018|-+   |0x1020|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

与上面相同,将q++; 移动到指向它指向的下一个内存位置,即数组的第5个单元格:

q

下一步:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |                        +------------+
    +------+     +------+                        |            |
+-------------+                                  v            |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  |  +------+------+------+------+------+         |
|   |0x100C|--+->|  100 |  500 |  750 | 1000 |  50  |         |
|   +------+  |  +------+------+------+------+------+         |
|             +-------------------^                           |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1014|     |0x101C|-+   |0x1020|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

转到*q = *q * 100; 指向的位置并获取其内容(50)。乘以100(= 5000)。最后将此值指定给q指向的位置:

q

下一步:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |                        +------------+
    +------+     +------+                        |            |
+-------------+                                  v            |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  |  +------+------+------+------+------+         |
|   |0x100C|--+->|  100 |  500 |  750 | 1000 | 5000 |         |
|   +------+  |  +------+------+------+------+------+         |
|             +-------------------^                           |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1014|     |0x101C|-+   |0x1020|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

转到**s = -100; 指向(s)的位置并获取其内容,我们将其称为p。现在转到*s指向的位置(第3个数组单元格)并指定-100:

*s

下一步:

  i: 0x1000    j: 0x1004
    +------+     +------+
    |  50  |     |  100 |                        +------------+
    +------+     +------+                        |            |
+-------------+                                  v            |
| k: 0x1008   |   0x100C 0x1010 0x1014 0x1018 0x101C          |
|   +------+  |  +------+------+------+------+------+         |
|   |0x100C|--+->|  100 |  500 | -100 | 1000 | 5000 |         |
|   +------+  |  +------+------+------+------+------+         |
|             +-------------------^                           |
| p: 0x1020    q: 0x1024    s: 0x1028    t: 0x102C            |
|   +------+     +------+     +------+     +------+           |
+---|0x1014|     |0x101C|-+   |0x1020|<----|0x1028|           |
    +------+     +------+ |   +------+     +------+           |
        ^                 |      |                            |
        |                 +------+----------------------------+
        |                        |
        +------------------------+

转到***t = -200; 指向(t)的位置并获取其内容,让我们调用此s。现在转到*t指向(*t)的位置并获取其内容,让我们调用此q。现在转到**t指向的位置(再次指向数组的第3个单元格)并指定-200:

**t

我希望这个答案可以为你和他人澄清一些事情。在学习和玩指针时总是记忆,它会让你的生活变得更轻松。

问候。

答案 1 :(得分:1)

绘制图形以显示事物是有帮助的。我在下面添加了解决方案,但要想出来,只需在图表中绘制所有关系。

p = k;  // p now points at the first element of k (value=10)
*p = *q;  // replace first element in k with *q (value=100) -> array now 100, 20, 30, ..
p++;  // p now points to the second element of k
s = &p; // s points at p, p points at second element of k
**s = 500; // replace second element of k with 500 -> 100, 500, 30,..
q = p + 2; // q now points at 4th element of k (value=40)
*q = 1000;  // set value to 1000 -> 100, 500, 30, 1000, 50
p = q - 1; // p now points to 3rd element
*p = 750; // set to 750 -> 100, 500, 750, 1000, 50
q++; // increase q, now points at 5th element
*q = *q * 100; // multiply value of 5th element by 100 -> 100, 500, 750, 1000, 5000

**s = -100;  // s points to p, which points to 3rd element -> 100, 500, -100, 1000, 5000
***t = -200; // t points to s, so replace same value -> 100, 500, -200, 1000, 5000

答案 2 :(得分:0)

int main() {
  int i = 50, j = 100;
  int k[] = {10, 20, 30, 40, 50};
  int *p, *q;
  int **s;
  int ***t;
  p = &i;
  printf("%d %d\n", i, *p); //50 50
  q = &j;
  printf("%d %d\n", j, *q); //100 100
  s = &p;
  printf("%d %d\n", *p, **s); // 50 50
  t = &s;
  printf("%d %d %d %d\n", *p, *q, **s, ***t);
  p = q;
  printf("%d %d %d %d\n", *p, *q, **s, ***t);
  s = &q;
  printf("%d %d %d %d\n", *p, *q, **s, ***t);

  // k is a pointer to a memory where the array is stored
  // in this case a memory with values [10,20,30,40,50]
  // p will also point to this memory address
  p = k;
  // *q is j , p is pointing to the array => *p will be the first element of the array
  // *p = *q => firts element of array will be j 
  // the new array will be [100,20,30,40,50]
  *p = *q;

  //in case of pointers, the ++ oprtator will act like this : p = p + sizeof(*p) wich means next int at that memory location, in our case, next element in array
  //if we have p+2 , it will be translated as p + 2*sizeof(*p) which means the 3rd element of the array (k[2])
  p++;
  //s is pointer to p, p is pointer to 2nd element of array (k[1])
  s = &p;
  // **s = *p = k[1], our array will be [100,500,30,40,50]
  **s = 500;
  //now, we move p, 2 elements forwards, that means p = &k[3]
  //q will point to k[3]
  q = p + 2;
  //k[3] will be 1000=> [100,500,30,1000,50]
  *q = 1000;
  //p will be &k[3] -1 => &k[2]
  p = q - 1;
  // k[2] = 750 => [100,500,750,1000,50]
  *p = 750;
  // q is &k[3], q++ will be next element , &k[4]
  q ++;
  // *(&k[4]) = *(&k[4]) * 100 => k[4] = k[4] * 100 => [100.500,750,1000,5000]
  *q = *q * 100;

  printf("%d %d %d %d %d\n", k[0], k[1], k[2], k[3], k[4]);

  //s is &p (from line 33), p is k[2] => **s => *(*(&p)) =>*(*(&(&k[2])) => k[2]
  // k[2] = -100
  **s = -100;
  //t is &s => *(*(*(*(&s)))) => *(*(*(&(&(&k[2]))))) => k[2]
  // k[2] = -200
  ***t = -200;

  printf("%d %d %d %d %d\n", k[0], k[1], k[2], k[3], k[4]);

  //i is 50
  //j is 100
  //*p = *(&k[2]) = k[2] = -200
  //*q = *(&k[4]) = k[4] = 5000
  //**s = *(*(&p)) = **&&k[2] = -200
  //***t = ***&s = **s = -200
  printf("%d %d %d %d %d %d\n", i, j, *p, *q, **s, ***t);

  return 0;
}