鱼C论坛

 找回密码
 立即注册
查看: 1773|回复: 12

[已解决]结构体指针函数的使用问题

[复制链接]
发表于 2019-8-11 15:57:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

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

struct programer {
        char name[16];
        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-13 14:25:36
四十不环 发表于 2019-8-13 14:08
怎么说呢,还是要看编译器,在gcc g++编译器,我试了一下,在函数的形参加入static是会报错的,
在vc2 ...

我一直都是用的VS最新版,GCC很少用。那看来结论就是:gcc形参加static报错,vs不报错但没用。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-8-11 16:10:57 | 显示全部楼层
本帖最后由 迷雾少年 于 2019-8-11 16:12 编辑

问题出现在add_salary4
  1. struct programer* add_salary4(static struct programer p, int num) {
  2.         static struct programer *p1;
  3.         p1 = &p;
  4.         p1->salary += num;
  5.         
  6.         printf("被调用函数内部 -> 姓名:%s, 年龄:%d, 薪水:%d\n",  p1 -> name, p1 -> age, p1 -> salary);
  7.         
  8.         return p1;
  9. }
复制代码


你这函数返回的是一个指针,指向 static struct programer p
在这个函数里面还没返回的时候 p的数据是正常的  此时是你这个函数在用这个栈的内存
但是这个函数返回之后static struct programer p的数据就会在你调用别的函数的时候被重写,因为p是放在栈里的,每一次函数调用都会不断重写栈里的数据。所以你返回的这个指针指向的这个栈的内存区域的数据被重写成不知道什么鬼的值了。所以数据都乱了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-11 16:36:59 | 显示全部楼层
       如果想在函数中修改结构体成员变量的值,那么,输入参数必须是这个结构体的指针
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <windows.h>


  4. struct programer {
  5.         char name[16] ;
  6.         int age       ;
  7.         int salary    ;
  8. }                     ;

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

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

  15. int main(void) {
  16.         struct programer xiaoniu                                                                              ;
  17.         strcpy(xiaoniu . name , "小牛")                                                                       ;
  18.         xiaoniu . age = 28                                                                                    ;
  19.         xiaoniu . salary = 20000                                                                              ;
  20.         printf("main函数 -> 姓名:%s, 年龄:%d, 薪水:%d\n", xiaoniu . name, xiaoniu . age, xiaoniu . salary) ;
  21.         age_t(& xiaoniu)                                                                                      ;
  22.         add_salary4(& xiaoniu , 10000)                                                                        ;
  23.         printf("main函数 -> 姓名:%s, 年龄:%d, 薪水:%d\n", xiaoniu . name, xiaoniu . age, xiaoniu . salary) ;
  24.         system("pause")                                                                                       ;
  25. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-11 20:40:12 | 显示全部楼层
终于找出问题了,函数的形参是不允许带static的,static只能用在函数体的局部变量中。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

你确定跟static有关?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-11 21:51:08 | 显示全部楼层
迷雾少年 发表于 2019-8-11 21:38
你确定跟static有关?


带了static的变量是静态变量,它的值一旦决定就不在变化,且它的寿命是整个程序运行的时间
相当于全局常量
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-11 22:04:35 | 显示全部楼层
IDE:VS2019
直接拷贝你的源代码

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

  4. struct programer {
  5.         char name[16];
  6.         int age;
  7.         int salary;
  8. };



  9. struct programer* add_salary4( static struct programer  p, int num) {
  10.         static struct programer* p1;
  11.         p1 = &p;
  12.         p1->salary += num;

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

  14.         return p1;
  15. }

  16. void age_t(int* p) {
  17.         *p = 29;
  18. }


  19. int main(void) {
  20.         struct programer xiaoniu;
  21.         struct programer* p2;

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


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

  28.         system("pause");
  29.         return 0;
  30. }
复制代码

运行乱码

add_salary4里下断点
&p:0x10ffbc8
&num:0x10ffbe0

所以这个加了static的static struct programer  p和没加的int num一样都是在栈里的

代码2
  1. struct programer* add_salary4( [b]static struct programer & p[/b], int num) {
  2.         static struct programer* p1;
  3.         p1 = &p;
  4.         p1->salary += num;

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

  6.         return p1;
  7. }
复制代码


把p改为引用,结果正确。
不知道你的结论怎么得出的,可能是编译器差别 ?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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[16];
        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中不会出现乱码,所以我才得出那个结论
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-13 14:25:36 | 显示全部楼层    本楼为最佳答案   
四十不环 发表于 2019-8-13 14:08
怎么说呢,还是要看编译器,在gcc g++编译器,我试了一下,在函数的形参加入static是会报错的,
在vc2 ...

我一直都是用的VS最新版,GCC很少用。那看来结论就是:gcc形参加static报错,vs不报错但没用。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

恩,我测试的结果就是样
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-13 14:50:05 | 显示全部楼层
四十不环 发表于 2019-8-13 14:39
恩,我测试的结果就是样

既然没问题了,那结贴吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-13 15:07:19 | 显示全部楼层
迷雾少年 发表于 2019-8-13 14:50
既然没问题了,那结贴吧

在哪结贴来着,好像没办法结贴
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-13 15:18:51 | 显示全部楼层
四十不环 发表于 2019-8-13 15:07
在哪结贴来着,好像没办法结贴

随便选个最佳答案就行了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-26 19:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表