鱼C论坛

 找回密码
 立即注册
查看: 2782|回复: 16

为什么最后一次输出时nj8812 black 而不是bj7653 yellow???

[复制链接]
发表于 2014-6-20 10:25:12 | 显示全部楼层 |阅读模式

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

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

x
#include <stdio.h>
typedef struct 
{
  char *no;
  char *color;
}CAR;
void func1(CAR *s)
{
  s->no="nj8812";
  s->color="black";
  printf("%s,%s\n",s->no,s->color);
}
void func2(CAR s)
{
  s.no="bj7653";
  s.color="yellow";
  printf("%s,%s\n",s.no,s.color);
}
main( )
{
  void func1(),func2();
static CAR car={"fj0236","red"};
printf("%s,%s\n",car.no,car.color);
func1(&car);
printf("%s,%s\n",car.no,car.color);
func2(car);
printf("%s,%s\n",car.no,car.color);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-6-20 13:48:05 | 显示全部楼层
函数传递时使用栈上的一个局部变量作为参数,但函数退出时,栈上的局部变量的生命周期结束,变量无效,所以func2函数不会改变传入的实参,它改变的是形参(栈上的变量),所以输出的是实参,自然是这个结果

另外,main中的func1和func2没有意义,因为这两个函数的作用域已经在代码开始声明为全局了

满意请采纳,不满意请追问
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-22 10:29:03 | 显示全部楼层
二楼解释得不错~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-23 09:08:15 | 显示全部楼层

还是不太明白,能说的再简单通俗一些吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-23 11:33:31 | 显示全部楼层
雪域王国 发表于 2014-6-23 09:08
还是不太明白,能说的再简单通俗一些吗?

当线程进入函数后,所有在函数中声明的变量(链接属性为外部的变量除外,下同)的建立都在栈上,即所有在函数内部声明的变量拥有函数作用域,只在函数内部有效,这个栈上变量和原来的变量是不同的,这也就是大部分情况实参和形参不同的原因。当线程退出函数时,弹栈,所有栈上函数变得无效,所以...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-23 12:42:01 | 显示全部楼层
雪域王国 发表于 2014-6-23 09:08
还是不太明白,能说的再简单通俗一些吗?

其实通俗点说就是…你就知道形参和实参不是一个“人”就行了。你调用函数的时候【只是】把实参的【值】给了形参,然后函数对形参进行操作,和实参没有半毛钱关系
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-23 12:48:55 | 显示全部楼层
雪域王国 发表于 2014-6-23 09:08
还是不太明白,能说的再简单通俗一些吗?

给你举个简单的例子
#include<stdio.h>

void fun1(int a,int b)
{
        a += 5;
        b += 5;
        printf("%d\n",a + b);
}

int main()
{
        int x = 2,y = 3;
        fun1(x,y);
        printf("%d\n",x + y);
}
[/code]
运行结果是:
15
5
形参a,b分别被实参x,y赋值,然后函数对a,b进行操作,改变了a,b的值,但是x,y的值并没有改变。这就是传值参数的特点
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-23 12:50:48 | 显示全部楼层
还不是太会贴代码。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-23 12:51:28 | 显示全部楼层
xuheng 发表于 2014-6-23 12:50
还不是太会贴代码。。。
#include<stdio.h>

void fun1(int a,int b)
{
        a += 5;
        b += 5;
        printf("%d\n",a + b);
}

int main()
{
        int x = 2,y = 3;
        fun1(x,y);
        printf("%d\n",x + y);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-23 14:16:32 | 显示全部楼层

上边的题我明白,那为什么第三个的结果和第二个是一样的,而最后一个和倒数第二个结果不一样呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-23 14:27:08 | 显示全部楼层
s->no="nj8812";
  s->color="black";

no color 没有空间怎么放东西啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-24 01:45:52 | 显示全部楼层
雪域王国 发表于 2014-6-23 14:16
上边的题我明白,那为什么第三个的结果和第二个是一样的,而最后一个和倒数第二个结果不一样呢?

最后一个和倒数第二个结果不一样你能明白了吧,和之前说的例子一样的道理。
至于第三个和第二个,这是指针参数的特点:实参是把地址传给形参指针,指针是指向实参的,所以,你用指针访问的是实参,可以通过形参指针来修改实参。要把传值参数和指针参数的特点分清楚。PS:引用参数也是可以通过形参来修改实参的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-24 01:54:42 | 显示全部楼层
#include<stdio.h>

void fun1(int *a,int *b)
{
        *a += 5;
        *b += 5;
        printf("%d\n",*a + *b);
}

int main()
{
        int x = 2,y = 3;
        fun1(&x,&y);
        printf("%d\n",x + y);
}
输出结果是:
15
15
通过形参指针来访问实参,*a和x、*b和y在内存中是在同一位置,修改*a就是在修改x,除非把指针a的指向改变。
所以你的程序中第二个和第三个输出相同,其实根本就是输出的同一个东西
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-24 07:58:02 | 显示全部楼层
xuheng 发表于 2014-6-24 01:54
输出结果是:
15
15

这个我明白了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-24 08:02:06 | 显示全部楼层
戏++ 发表于 2014-6-23 14:27
s->no="nj8812";
  s->color="black";

car不是static(静态局部变量)吗,在程序运行期间都存在的吗?而且在程序运行阶段也不会初始化啊,那为什么最后一次和上一次结果不同?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-24 08:23:48 | 显示全部楼层
雪域王国 发表于 2014-6-24 08:02
car不是static(静态局部变量)吗,在程序运行期间都存在的吗?而且在程序运行阶段也不会初始化啊,那为什 ...

给你加点料
#include <stdio.h>
#include "stdlib.h"
typedef struct
{
        char *no;
        char *color;
}CAR;
void func1(CAR *s)
{
        s->no="nj8812";
        s->color="black";
        printf("%s,%s\n",s->no,s->color);
}
void func2(CAR s)
{
        printf("调用中 s的地址0x%p\n",&s);

        s.no="bj7653";
        s.color="yellow";
        printf("%s,%s\n",s.no,s.color);

        
}
main( )
{
        void func1(),func2();
        CAR car={"fj0236","red"};
        printf("%s,%s\n",car.no,car.color);
        func1(&car);
        printf("%s,%s\n",car.no,car.color);

        printf("调用前 car的地址0x%p\n",&car);
        func2(car);
        printf("%s,%s\n",car.no,car.color);

        printf("调用后 car的地址0x%p\n",&car);


        //调用前后的CAR地址,和func2中的CAR的地址是不一样的,说明,进入函数的时候,构造了一个CAR变量,操作的内存块不一样了,所以会出现楼主说的问题
        //强烈建议不要定义这种结构
        /*
        typedef struct
        {
        char *no;
        char *color;
        }CAR;

        用数组
        typedef struct
        {
        char no[20];
        char color[20];
        }CAR;
        */        

        system("pause");
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-24 15:47:17 | 显示全部楼层
雪域王国 发表于 2014-6-24 08:02
car不是static(静态局部变量)吗,在程序运行期间都存在的吗?而且在程序运行阶段也不会初始化啊,那为什 ...

你不要static结果是一样的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-28 09:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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