p是一个结构的指针,所有这些代码段都做什么? [英] p is a pointer to a structure, what do all these code snippets do?

查看:65
本文介绍了p是一个结构的指针,所有这些代码段都做什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

++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使其指向Winteri.
  • 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 pointer p->i so it points to the i of Winter.
  • p++->i: inter — post-increments the pointer p (to point to "Bash"), but the result is the same as before because the increment takes effect after p->i is used.
  • *p->i++: 66 — post-increments the pointer p->i (so it points to the a in Bash) and reports the value pointed at before the increment, which is B (66 in ASCII).
  • *p->i++: 97 — same expression, but the pointer points at a (97) before the increment and at the s after the increment.
  • (*p->i)++: 115 — post-increments the letter that p->i points at, reporting s but changing it to t.
  • *p++->i: 116 — post-increments p so it points to the string "In", while reporting t (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是一个结构的指针,所有这些代码段都做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆