Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C指针通过纸张_C_Pointers - Fatal编程技术网

C指针通过纸张

C指针通过纸张,c,pointers,C,Pointers,我在大学里读一门课程,在看过去的一篇论文时,总有一个关于C指针的问题 我认为我对它们的工作原理有一个合理的把握,但这是一个让我困惑的问题: Consider running the C program fragment: int x[4] = {0,2,4,6}; int *y; y = &x[2]; *(x + 2) = y[1] + 1; What is the value of the expression *y afterwards? (a) 2 (b) 4 (c) 5 (

我在大学里读一门课程,在看过去的一篇论文时,总有一个关于C指针的问题

我认为我对它们的工作原理有一个合理的把握,但这是一个让我困惑的问题:

Consider running the C program fragment:


int x[4] = {0,2,4,6};
int *y;
y = &x[2];
*(x + 2) = y[1] + 1;

What is the value of the expression *y afterwards?
(a) 2
(b) 4
(c) 5
(d) 7
(e) 8
现在,在对上述问题的回答中,答案是
d

我非常困惑,因为:

  • x的值没有声明,所以我认为不可能计算
    x+2
  • y
    不是数组,那么如何计算
    y[1]

  • 为什么这里的
    7
    是正确答案?

    x
    是4元素数组
    *x
    引用该数组中的第一个元素,
    *(x+2)
    引用第三个元素

    *y
    指向
    x
    数组
    (y=&x[2])

    最终赋值将原始
    x
    数组(
    *(x+2)
    )的第三个元素设置为
    y[1]+1
    的值。由于
    y
    被初始化为指向第三个元素,
    y[1]
    将指向原始x数组的最后一个元素

    6+1
    被分配给
    x
    数组的第三个元素,
    *y
    引用该元素。

    需要注意的事项:

    • *(x+2)
      x[2]
      完全相同
    • &x[2]
      &(*(x+2))
      完全相同,后者与
      x+2
      相同
    知道了这一点,让我们重写这个问题:

    int x[4] = {0,2,4,6};
    int *y = &x[2];
    *(x + 2) = y[1] + 1;
    
    还有一些修改:

    int x[4] = {0,2,4,6};
    int *y = x + 2;
    x[2] = *(y + 1) + 1;
    
    现在,让我们直接将
    y
    代入最后一个等式:

    int x[4] = {0,2,4,6};
    int *y = x + 2;
    x[2] = *((x + 2) + 1) + 1;
    
    并将其清理干净:

    int x[4] = {0,2,4,6};
    int *y = x + 2;
    x[2] = x[3] + 1;
    
    现在,让我们来看看问题:

    int x[4] = {0,2,4,6};
    int *y = &x[2];
    *(x + 2) = y[1] + 1;
    
  • x[2]
    更新为
    x[3]+1
  • 所以
    x[2]
    现在是7
  • 所以
    x=={0,2,7,6}
  • y仍然指向
    x+2处的值
  • 所以
    *y==7

  • 让我们一步一步考虑代码。

    指针y由数组第三个元素的地址初始化(索引从0开始)

    所以y指向4。所以
    x[2]
    y[0]
    是等价的表达式

    y[1]
    y[0]
    之后的下一个元素,即它是6

    y[1]+1
    将等于7

    *(x+2)
    x[2]
    相同,因此
    x[2]
    将设置为7。同时y也指向
    x[2]
    。因此
    *y
    将等于7。

    让我们将其分解为:

    intx[4]={0,2,4,6}

    x [0] = 0
    x [1] = 2
    x [2] = 4
    x [3] = 6
    
    x [0] = 0
    x [1] = 2
    x [2] = 4       // <-- x[2]  
    x [3] = 6       // <-- y[1] 
    
    int*y指向整数的指针,以便y可以指向x中的任何位置

    x [0] = 0       // <-- y ?
    x [1] = 2       // <-- y ?
    x [2] = 4       // <-- y ?
    x [3] = 6       // <-- y ?
    

    x[0]=0/这里的关键组件是索引运算符返回y一个实际的int,而不是地址。对于解引用运算符*(x+2)也是如此

    我在这里添加了一个表格,希望有助于澄清:

    *(x+2)和x[2]对于编译器是相同的。y[1]与*(y+1)相同。因为y是与x+2相同的内存位置,所以(x+2)+1指向6或x[3]。加上一个就变成了7。它分配给x[2],其中y指的是它。很好的解释@jcjunction!
    x [0] = 0
    x [1] = 2
    x [2] = 4       // <-- x[2]  
    x [3] = 6       // <-- y[1] 
    
    int a = y[1]; // a = the value of the int after y[0]
    int b = *(x + 2); // b = the value of x[2] note that the index operator is just shorthand, y[1] just means *(y + 1)
    // int* c = y[1]; NOT LEGAL assignment of an int to an int*
    // int* d = *(x + 2); NOT LEGAL assignment of an int to an int*