问题描述
++p->i
p++->i
*p->i
*p->i++
(*p->i)++
*p++->i
我不理解上面的这些陈述,我编写了一个小型测试程序来理解它们.
I don't understand these statements above, I wrote a small test program to understand them.
#include <stdio.h>
struct my_structure {
int i;
};
void main() {
struct my_structure variable = {20};
struct my_structure *p = &variable;
printf("NAME: %d\n", ++p->i);
printf("NUMBER: %d\n", p++->i);
printf("RANK: %d", *p->i++);
printf("name: %d\n", *p->i++);
printf("number: %d\n", (*p->i)++);
printf("rank: %d", *p++->i);
}
这是我评论了最后四个print
语句后得到的输出:
Here's what the output I got after I commented the last four print
statements:
NAME: 21
NUMBER: 21
在取消注释代码并编译后,我得到:
And after uncommenting the code and compiling I get:
test.c: In function 'main':
test.c:14:24: error: invalid type argument of unary '*' (have 'int')
printf("RANK: %d", *p->i++);
^~~~~~~
test.c:15:26: error: invalid type argument of unary '*' (have 'int')
printf("name: %d\n", *p->i++);
^~~~~~~
test.c:16:29: error: invalid type argument of unary '*' (have 'int')
printf("number: %d\n", (*p->i)++);
^~~~~
test.c:17:24: error: invalid type argument of unary '*' (have 'int')
printf("rank: %d", *p++->i);
推荐答案
可以使代码正常工作(编译,运行而不会崩溃,并产生一致的,可解释的答案),但是您需要与所选的结构不同的结构.例如:
It's possible to make the code work (compile, run without crashing, and produce a coherent, explicable answer), but you need a different structure from the one chosen. For example:
#include <stdio.h>
struct my_structure
{
char *i;
};
#define EXPR(x) #x, x
int main(void)
{
char strings[][10] = { { "Winter" }, { "Bash" }, { "Is" }, { "Here" } };
struct my_structure variables[] = { { strings[0] }, { strings[1] }, { strings[2] }, { strings[3] } };
struct my_structure *p = variables;
printf("%10s: %s\n", EXPR(++p->i));
printf("%10s: %s\n", EXPR(p++->i));
printf("%10s: %d\n", EXPR(*p->i++));
printf("%10s: %d\n", EXPR(*p->i++));
printf("%10s: %d\n", EXPR((*p->i)++));
printf("%10s: %d\n", EXPR(*p++->i));
return 0;
}
哪个生成输出:
++p->i: inter
p++->i: inter
*p->i++: 66
*p->i++: 97
(*p->i)++: 115
*p++->i: 116
宏EXPR
只是允许我不重复代码中的表达式,而没有将字符串形式和值都包含在对printf()
的调用中.
The macro EXPR
simply allows me not to repeat the expressions in the code, and yet to get both the string form and the value into the call to printf()
.
开始时,p->i
指向字符串"Winter"
.
-
++p->i: inter
-预增加指针p->i
使其指向Winter
的i
. -
p++->i: inter
—在指针p
后递增(以指向"Bash"
),但结果与之前相同,因为使用p->i
后该增量生效. -
*p->i++: 66
—在指针p->i
之后递增(因此它指向Bash
中的a
)并报告递增之前所指向的值,即B
(ASCII中为66). -
*p->i++: 97
—相同的表达式,但是指针指向增量前的a
(97)和增量后的s
. -
(*p->i)++: 115
—将p->i
指向的字母后递增,报告s
,但将其更改为t
. -
*p++->i: 116
—后递增p
,因此在报告t
(116)时它指向字符串"In".
++p->i: inter
— pre-increments the pointerp->i
so it points to thei
ofWinter
.p++->i: inter
— post-increments the pointerp
(to point to"Bash"
), but the result is the same as before because the increment takes effect afterp->i
is used.*p->i++: 66
— post-increments the pointerp->i
(so it points to thea
inBash
) and reports the value pointed at before the increment, which isB
(66 in ASCII).*p->i++: 97
— same expression, but the pointer points ata
(97) before the increment and at thes
after the increment.(*p->i)++: 115
— post-increments the letter thatp->i
points at, reportings
but changing it tot
.*p++->i: 116
— post-incrementsp
so it points to the string "In", while reportingt
(116).
这是具有更多工具的替代方法:
Here's an alternative with more instrumentation:
#include <stdio.h>
struct my_structure
{
char *i;
};
#define EXPR(x) #x, x
int main(void)
{
char strings[][10] = { { "Winter" }, { "Bash" }, { "Is" }, { "Here" } };
struct my_structure variables[] = { { strings[0] }, { strings[1] }, { strings[2] }, { strings[3] } };
struct my_structure *p = variables;
for (size_t i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
printf("strings[%zu] = [%s]\n", i, strings[i]);
for (size_t i = 0; i < sizeof(variables)/sizeof(variables[0]); i++)
printf("variables[%zu].i = [%s]\n", i, variables[i].i);
printf("%10s: %s\n", EXPR(p->i));
printf("%10s: %s\n", EXPR(++p->i));
printf("%10s: %s\n", EXPR(p->i));
printf("%10s: %s\n", EXPR(p++->i));
printf("%10s: %s\n", EXPR(p->i));
printf("%10s: %d\n", EXPR(*p->i++));
printf("%10s: %s\n", EXPR(p->i));
printf("%10s: %d\n", EXPR(*p->i++));
printf("%10s: %s\n", EXPR(p->i));
printf("%10s: %d\n", EXPR((*p->i)++));
printf("%10s: %s\n", EXPR(p->i));
printf("%10s: %d\n", EXPR(*p++->i));
printf("%10s: %s\n", EXPR(p->i));
for (size_t i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
printf("strings[%zu] = [%s]\n", i, strings[i]);
for (size_t i = 0; i < sizeof(variables)/sizeof(variables[0]); i++)
printf("variables[%zu].i = [%s]\n", i, variables[i].i);
return 0;
}
及其输出:
strings[0] = [Winter]
strings[1] = [Bash]
strings[2] = [Is]
strings[3] = [Here]
variables[0].i = [Winter]
variables[1].i = [Bash]
variables[2].i = [Is]
variables[3].i = [Here]
p->i: Winter
++p->i: inter
p->i: inter
p++->i: inter
p->i: Bash
*p->i++: 66
p->i: ash
*p->i++: 97
p->i: sh
(*p->i)++: 115
p->i: th
*p++->i: 116
p->i: Is
strings[0] = [Winter]
strings[1] = [Bath]
strings[2] = [Is]
strings[3] = [Here]
variables[0].i = [inter]
variables[1].i = [th]
variables[2].i = [Is]
variables[3].i = [Here]
使用此方案的变体(例如,加括号)以确保您了解正在发生的事情.
Play with variants of this scheme (extra parentheses, for example) to ensure you understand what's going on.
这篇关于p是一个结构的指针,所有这些代码段都做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!