四十不环 发表于 2019-8-11 15:57:50

结构体指针函数的使用问题

本帖最后由 四十不环 于 2019-8-11 15:59 编辑

#include <stdio.h>
#include <string.h>
#include <Windows.h>

struct programer {
        char name;
        int age;
        int salary;
};



struct programer* add_salary4(static struct programer p, int num) {
        static struct programer *p1;
        p1 = &p;
        p1->salary += num;
       
        printf("被调用函数内部 -> 姓名:%s, 年龄:%d, 薪水:%d\n",p1 -> name, p1 -> age, p1 -> salary);
       
        return p1;
}

void age_t(int *p) {
        *p = 29;
}


int main(void) {
        struct programer xiaoniu;
        struct programer *p2;
       
        strcpy_s(xiaoniu.name, "小牛");
        xiaoniu.age = 28;
        xiaoniu.salary = 20000;
        age_t(&xiaoniu.age);
        p2 = add_salary4(xiaoniu, 10000);
       
       
        printf("main函数 -> 姓名:%s, 年龄:%d, 薪水:%d\n", p2 -> name, p2 -> age, p2 -> salary);
       
        system("pause");
        return 0;
}


为什么我段代码,执行的结果是乱码,求大神能帮忙指出问题出在哪里了,谢谢各位了!

迷雾少年 发表于 2019-8-11 16:10:57

本帖最后由 迷雾少年 于 2019-8-11 16:12 编辑

问题出现在add_salary4
struct programer* add_salary4(static struct programer p, int num) {
      static struct programer *p1;
      p1 = &p;
      p1->salary += num;
      
      printf("被调用函数内部 -> 姓名:%s, 年龄:%d, 薪水:%d\n",p1 -> name, p1 -> age, p1 -> salary);
      
      return p1;
}

你这函数返回的是一个指针,指向 static struct programer p
在这个函数里面还没返回的时候 p的数据是正常的此时是你这个函数在用这个栈的内存
但是这个函数返回之后static struct programer p的数据就会在你调用别的函数的时候被重写,因为p是放在栈里的,每一次函数调用都会不断重写栈里的数据。所以你返回的这个指针指向的这个栈的内存区域的数据被重写成不知道什么鬼的值了。所以数据都乱了。

jackz007 发表于 2019-8-11 16:36:59

       如果想在函数中修改结构体成员变量的值,那么,输入参数必须是这个结构体的指针
#include <stdio.h>
#include <string.h>
#include <windows.h>


struct programer {
      char name ;
      int age       ;
      int salary    ;
}                     ;

void add_salary4(struct programer * p , int num) {
      p -> salary += num ;
}

void age_t(struct programer * p) {
      p -> age = 29      ;
}

int main(void) {
      struct programer xiaoniu                                                                              ;
      strcpy(xiaoniu . name , "小牛")                                                                     ;
      xiaoniu . age = 28                                                                                    ;
      xiaoniu . salary = 20000                                                                              ;
      printf("main函数 -> 姓名:%s, 年龄:%d, 薪水:%d\n", xiaoniu . name, xiaoniu . age, xiaoniu . salary) ;
      age_t(& xiaoniu)                                                                                    ;
      add_salary4(& xiaoniu , 10000)                                                                        ;
      printf("main函数 -> 姓名:%s, 年龄:%d, 薪水:%d\n", xiaoniu . name, xiaoniu . age, xiaoniu . salary) ;
      system("pause")                                                                                       ;
}

四十不环 发表于 2019-8-11 20:40:12

终于找出问题了,函数的形参是不允许带static的,static只能用在函数体的局部变量中。

迷雾少年 发表于 2019-8-11 21:38:39

四十不环 发表于 2019-8-11 20:40
终于找出问题了,函数的形参是不允许带static的,static只能用在函数体的局部变量中。

你确定跟static有关?

bin554385863 发表于 2019-8-11 21:51:08

迷雾少年 发表于 2019-8-11 21:38
你确定跟static有关?

带了static的变量是静态变量,它的值一旦决定就不在变化,且它的寿命是整个程序运行的时间
相当于全局常量

迷雾少年 发表于 2019-8-11 22:04:35

IDE:VS2019
直接拷贝你的源代码

代码1
#include <stdio.h>
#include <string.h>
#include <Windows.h>

struct programer {
        char name;
        int age;
        int salary;
};



struct programer* add_salary4( static struct programerp, int num) {
        static struct programer* p1;
        p1 = &p;
        p1->salary += num;

        printf("被调用函数内部 -> 姓名:%s, 年龄:%d, 薪水:%d\n", p1->name, p1->age, p1->salary);

        return p1;
}

void age_t(int* p) {
        *p = 29;
}


int main(void) {
        struct programer xiaoniu;
        struct programer* p2;

        strcpy_s(xiaoniu.name, "小牛");
        xiaoniu.age = 28;
        xiaoniu.salary = 20000;
        age_t(&xiaoniu.age);
        p2 = add_salary4(xiaoniu, 10000);


        printf("main函数 -> 姓名:%s, 年龄:%d, 薪水:%d\n", p2->name, p2->age, p2->salary);

        system("pause");
        return 0;
}
运行乱码

在add_salary4里下断点
&p:0x10ffbc8
&num:0x10ffbe0
所以这个加了static的static struct programerp和没加的int num一样都是在栈里的

代码2
struct programer* add_salary4( static struct programer & p, int num) {
        static struct programer* p1;
        p1 = &p;
        p1->salary += num;

        printf("被调用函数内部 -> 姓名:%s, 年龄:%d, 薪水:%d\n", p1->name, p1->age, p1->salary);

        return p1;
}

把p改为引用,结果正确。
不知道你的结论怎么得出的,可能是编译器差别 ?

四十不环 发表于 2019-8-13 14:08:20

本帖最后由 四十不环 于 2019-8-13 14:18 编辑

迷雾少年 发表于 2019-8-11 22:04
IDE:VS2019
直接拷贝你的源代码



怎么说呢,还是要看编译器,在gcc g++编译器,我试了一下,在函数的形参加入static是会报错的,
在vc2010中虽然能通过编译就会出现上述我说的情况
#include <stdio.h>
#include <string.h>
#include <Windows.h>

struct programer {
        char name;
        int age;
        int salary;
};

struct programer* add_salary4(struct programer p, int num) {
        static struct programer *p1;
        static struct programer p2;
        p2 = p;
        p1 = &p2;
        p2.salary += num;

        printf("p = %p, p2 = %p\n", p2, p2);
        printf("被调用函数内部 -> 姓名:%s, 年龄:%d, 薪水:%d\n", p1->name, p1->age, p1->salary);

        return p1;
}
/*
//函数的形参不允许使用static,static只能使用在函数体的局部变量中
struct programer* add_salary4(static struct programer p, int num) {
        static struct programer *p1;
        p1 = &p;
        p1->salary += num;
       
        printf("被调用函数内部 -> 姓名:%s, 年龄:%d, 薪水:%d\n",p1 -> name, p1 -> age, p1 -> salary);
       
        return p1;
}
*/
void age_t(int *p) {
        *p = 29;
}


int main(void) {
        struct programer xiaoniu;
        struct programer *p2;

        strcpy_s(xiaoniu.name, "小牛");
        xiaoniu.age = 28;
        xiaoniu.salary = 20000;
        age_t(&xiaoniu.age);
        p2 = add_salary4(xiaoniu, 10000);


        printf("main函数 -> 姓名:%s, 年龄:%d, 薪水:%d\n", p2->name, p2->age, p2->salary);

        system("pause");
        return 0;
}
这个是我调整后的代码,在gcc g++上能通达编译,并且在VC VS中不会出现乱码,所以我才得出那个结论

迷雾少年 发表于 2019-8-13 14:25:36

四十不环 发表于 2019-8-13 14:08
怎么说呢,还是要看编译器,在gcc g++编译器,我试了一下,在函数的形参加入static是会报错的,
在vc2 ...

我一直都是用的VS最新版,GCC很少用。那看来结论就是:gcc形参加static报错,vs不报错但没用。

四十不环 发表于 2019-8-13 14:39:59

迷雾少年 发表于 2019-8-13 14:25
我一直都是用的VS最新版,GCC很少用。那看来结论就是:gcc形参加static报错,vs不报错但没用。

恩,我测试的结果就是样

迷雾少年 发表于 2019-8-13 14:50:05

四十不环 发表于 2019-8-13 14:39
恩,我测试的结果就是样

既然没问题了,那结贴吧{:5_109:}

四十不环 发表于 2019-8-13 15:07:19

迷雾少年 发表于 2019-8-13 14:50
既然没问题了,那结贴吧

在哪结贴来着,好像没办法结贴

迷雾少年 发表于 2019-8-13 15:18:51

四十不环 发表于 2019-8-13 15:07
在哪结贴来着,好像没办法结贴

随便选个最佳答案就行了{:10_256:}
页: [1]
查看完整版本: 结构体指针函数的使用问题