我正在看过去一篇关于我在大学里做的课程的论文,而且总会有一个关于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+2
y
不是数组,那么如何评估y[1]
?为什么7
在这里是正确答案?
答案 0 :(得分:2)
x
是4元素数组。 *x
引用该数组中的第一个元素,*(x + 2)
引用第3个元素。
*y
指向x
数组(y = &x[2])
最终作业将原始x
数组(*(x + 2)
)的第3个元素设置为y[1] + 1
的值。由于y
被初始化为指向第3个元素,y[1]
将指向原始x数组的最后一个元素。
6 + 1
被分配给x
数组的第3个元素,*y
引用。
答案 1 :(得分:1)
注意事项:
*(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;
现在,让我们来看看问题:
x[2]
使用x[3] + 1
x[2]
现在是7。x == {0, 2, 7, 6}
x + 2
的值。*y == 7
答案 2 :(得分:0)
让我们一步一步考虑代码。
指针y由数组的第三个元素的地址初始化(索引从0开始)
y = &x[2];
所以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。
答案 3 :(得分:0)
让我们分解:
int x [4] = {0,2,4,6};
x [0] = 0
x [1] = 2
x [2] = 4
x [3] = 6
int * y; 指向整数的指针,因此y可以指向x中的任何位置
x [0] = 0 // <-- y ?
x [1] = 2 // <-- y ?
x [2] = 4 // <-- y ?
x [3] = 6 // <-- y ?
y =&amp; x [2]; 现在我们已经指定y指向x [2]
x [0] = 0
x [1] = 2
x [2] = 4 // <-- y (or y[0])
x [3] = 6
*(x + 2)这与x [2]相同,所以: x [2] = y [1] + 1;
x [0] = 0
x [1] = 2
x [2] = 4 // <-- x[2]
x [3] = 6 // <-- y[1]
y [1]为6,所以y [1] + 1 = 7
注意y [1]与*(y + 1)相同。我们也取地址y点,加上一个整数的大小,得到它现在指向的内容。
答案 4 :(得分:0)
这里的关键组件是索引运算符返回y 1实际的int而不是地址。取消引用运算符*(x + 2)也是如此。
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*
我在这里添加了一张表,希望有助于澄清: