简体   繁体   English

C 中的增量问题(指针)

[英]Increment issue in C (pointer)

I can only change the content of the "birthday" function, the rest must stay the same.我只能更改“生日”function 的内容,rest 必须保持不变。

I am having a silly problem trying to increment the age variable...It does get incremented if I use the ++ operator but not by decimal 1, it seems to increment by 4 which is the sizeof an int.我在尝试增加年龄变量时遇到了一个愚蠢的问题......如果我使用 ++ 运算符而不是十进制 1,它确实会增加,它似乎增加了 4,这是一个 int 的大小。 What am I doing wrong here?我在这里做错了什么?

    #include <stdio.h>

typedef struct {
    int* age;
    const char* name;
} Person;

void birthday(Person* person);


int main()
{
    void(*birthday_ptr)(Person* person) = &birthday;
    Person me = {30,"foobar"};
    (*birthday_ptr)(&me);
    return 0;
    }

void birthday(Person* person)
{
    printf("%p\n", person);
    printf("%d\n", person->age);
    person->age = 31; // this works...it sets the value pointed to by the ptr to 31...
    printf("%d\n", person->age);
    person->age += 1; // this compiles, but it seems to increment by 4 the value pointed to by the ptr, not 1 (relates to int size ?!)
    printf("%d\n", person->age);
    int* silly = (int*)(person);
    (*silly)++; // this works and increments age to 36...
    (*person->age)++; // this causes an access violation...why ?! 
    printf("silly: %d\n", person->age);
}

You must dereference a pointer to change the value it's pointing to.您必须取消引用指针才能更改它指向的值。 But I reckon the age variable should not be a pointer at all.但我认为年龄变量根本不应该是一个指针。 It should be an int :它应该是一个int

typedef struct {
    int age;
    const char* name;
} Person;

This solves many of your problems, including the fact that you cast 30 to a pointer, and use %d to print the pointer, which causes undefined behavior.这解决了您的许多问题,包括您将30转换为指针,并使用%d打印指针,这会导致未定义的行为。

The correct solution is to modify your struct:正确的解决方案是修改你的结构:

typedef struct {
    int age;
    const char* name;
} Person;

indeed, it is more logical that age is an int and not an int* (age is an integer not an adress of this form 0x1F8C45 ).事实上,age 是int而不是int*更合乎逻辑(age 是 integer 而不是这种形式的地址0x1F8C45 )。

With such a change, your code:通过这样的更改,您的代码:

    (person->age)++; // this causes an access violation...why ?!
    printf("silly: %d\n", person->age);

is correct.是正确的。

If indeed, you would like to keep your struct as it currently is, you need to increment the value of member of the struct int * age but you can only change the content of the "birthday" function.如果确实,您希望保持当前struct ,则需要增加 struct int * age成员的值,但您只能更改“生日”function 的内容。

Here is my proposition.这是我的提议。

However, in my opinion, this is not a good C language nor is it a good practice.但是,在我看来,这不是一个好的 C 语言,也不是一个好的实践。 It is just a hack to bypass the problems'constraints (not to touch the structure) ==> You should be careful concerning the warning (also, your code does not compile if you use -Werror flag with gcc and consider the response of @Ayxan Haqverdili .绕过问题的约束(不要触摸结构)只是一种技巧==>您应该小心警告(此外,如果您将-Werror标志与gcc一起使用并考虑@的响应,则您的代码不会编译Ayxan Haqverdili .

Create a pointer pointing to the address of your age member创建一个指向您的age成员地址的指针

// a pointer pointing to the address of person->age
 int *p = (&person->age);
 // increment the value pointed by the pointer (which is supposed to be age)
 ++*p; // person->age is 32
 ++*p; // person->age is 33
 (*p)++; // the same -- increment to 34 etc etc

The whole birhday() function is below整个birhday() function 如下

void birthday(Person* person)
{
    printf("%d\n", person->age);
    person->age = 31; // this works...it sets the value pointed to by the ptr to 31...
    printf("%d\n", person->age);

    int *p = NULL;
    p = (int*)(&person->age);
    (*p)++; // age =32
    printf("value of p=%d\n", *p);
    printf("person->age=%d\n", person->age);

    (*p)++; // person->age is 33
    printf("value of p=%d\n", *p);
    printf("person->age=%d\n", person->age);


}

The ouput of the execution displays the following results:执行的输出显示以下结果:

30
31
value of p=32
person->age=32
value of p=33
person->age=33

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM