鱼C论坛

 找回密码
 立即注册
查看: 3151|回复: 14

两道c语言编程,能不能帮忙分析一下结果为什么不同?

[复制链接]
发表于 2014-9-9 23:51:13 | 显示全部楼层 |阅读模式
1鱼币
第一道
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct stu{
        char *name,gender;
        int score;
}STU;
void f(char *p)
{
        p=(char *)malloc(10);
        strcpy(p,"Qian");
}
main()
{
        STU a={NULL,'m',290},b;
        a.name=(char *)malloc(10);
        strcpy(a.name,"Zhao");
        b=a;
        f(b.name);
        b.gender='f';b.score=350;
        printf("%s,%c,%d,",a.name,a.gender,a.score);
        printf("%s,%c,%d\n",b.name,b.gender,b.score);
}
第二道
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct stu{
        char name[10],gender;
        int score;
}STU;
void f(char *p)
{
        strcpy(p,"Qian");
}
main()
{
        STU a={"Zhao",'m',290},b;
        b=a;
        f(b.name);
        b.gender='f';b.score=350;
        printf("%s,%c,%d,",a.name,a.gender,a.score);
        printf("%s,%c,%d\n",b.name,b.gender,b.score);
}
能不能具体说一下这里面的值传递和址传递到底是怎么进行的??
谢谢了!

最佳答案

查看完整内容

很简单。开启调试器,你会发现,如果是立即数值传递,他居然有地址。本来你明明传给他的是一个常量一个确定的数值比如f(1,2...)为什么会有地址呢?很简单,你看,你定义一个函数是不是 函数类型 函数名(参数列表){。。。。。。},其中参数列表是不是都是些 int template啊double template啊什么的,你觉得这像什么,是不是想你普通的定义一个变量,所以他的意思就是定义一个变量,只不过是临时的(template)。所以你传递给 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-9 23:51:14 | 显示全部楼层
很简单。开启调试器,你会发现,如果是立即数值传递,他居然有地址。本来你明明传给他的是一个常量一个确定的数值比如f(1,2...)为什么会有地址呢?很简单,你看,你定义一个函数是不是   
函数类型   函数名(参数列表){。。。。。。},其中参数列表是不是都是些 int template啊double template啊什么的,你觉得这像什么,是不是想你普通的定义一个变量,所以他的意思就是定义一个变量,只不过是临时的(template)。所以你传递给函数的实参的数值就是最后储存在这个临时变量里面,到了函数结束,因为这个临时变量(template)会释放掉,所以比如你传递给函数的是一个变量,比如f( a, b, c,.........)你发现在函数内部是无法改变函数外部的变量a,b,c......的,为什么呢,你在开启调试器,发现函数的参数的地址和你传给他的变量a,b,c的地址居然不一样,这说明什么,说明在计算机看来函数内的参数a,b,c和外部的本地变量a,b,c不是同一个东西,学过汇编我们知道的,CPU判断某两个数据是不是物理上,逻辑上都是同一个数据,是看地址的,不是看数值和名字什么的,所以你换做C语言也一样,地址不同就不是同一个东西,所以你改变的只是根据本地变量a,b,c复制的数据而不是a,b,c本身。
而传递指针呢,其实也有一个复制的过程,但是我们知道,指针是指向内存单元的地址的,你定义两个指针变量有相同的值,即两个指针指向相同地址,这是完全合法的嘛,所以你复制地址没关系啊,我们又不是对地址本身进行操作,我们要的是对应地址上的数据进行操作,所以你用哪几个指针指向同一个地址,然后对对应的数据进行操作其实是没什么差的,所以你改变的是数据而不是地址,如果你试着把指针变量自加一试试,你会发现本地变量的对应的指针变量的值没改变,至于这是为什么,你回到上一段慢慢体会
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-10 01:59:14 | 显示全部楼层
MyOrange 发表于 2014-9-10 01:44
很简单。开启调试器,你会发现,如果是立即数值传递,他居然有地址。本来你明明传给他的是一个常量一个确定 ...

我觉得我还要在加一句,你传递指针变量,其实还是复制的值,并不是本地变量,而且复制的临时变量在函数结束以后会释放掉
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-10 09:10:39 | 显示全部楼层
{:1_1:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-10 10:09:30 | 显示全部楼层
传递值和传递地址好好体会
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-10 11:25:14 From FishC Mobile | 显示全部楼层
值传递是拷贝变量的值,而不是变量的值,会生成临时变量,调研结束后就会释放,不会对原来的变量有任何影响,对原变量没有副作用。传递地址是把变量的地址传给调用的对象,如果对地址指向的内容进行操作,就会影响该变量的值,也就是有副作用。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-9-10 17:17:06 | 显示全部楼层
MyOrange 发表于 2014-9-10 01:44
很简单。开启调试器,你会发现,如果是立即数值传递,他居然有地址。本来你明明传给他的是一个常量一个确定 ...

我发现把第一道题的  p=(char *)malloc(10);语句删去后运行,b.name的值会变成Qian,请问那个malloc函数到底在址传递中发生了什么作用,使第一道题的b.name 的值没有改变???
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-10 21:20:02 | 显示全部楼层
紫樱蜜柑 发表于 2014-9-10 17:17
我发现把第一道题的  p=(char *)malloc(10);语句删去后运行,b.name的值会变成Qian,请问那个malloc函数到 ...

malloc你给他动态分配了一块内存,地址已经改变了,就不是原先你传递的地址了,malloc返回的是一块连续内存的首地址,有谁规定说你动态分配的内存地址一定和你原来的地址相同,没有吧,那不是就把原来的地址覆盖掉,变成新的地址了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-10 21:28:40 | 显示全部楼层
紫樱蜜柑 发表于 2014-9-10 17:17
我发现把第一道题的  p=(char *)malloc(10);语句删去后运行,b.name的值会变成Qian,请问那个malloc函数到 ...

赞以德服人
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct stu{
        char *name,gender;
        int score;
}STU;
void f(char *p)
{
        printf("%p\n", p);   //你运行一下,看看输出的两个地址会不会一样
        p=(char *)malloc(10);
        printf("%p\n", p);   //反正我试过,不一样
        strcpy(p,"Qian");
}
int main()
{
        STU a={NULL,'m',290},b;
        a.name=(char *)malloc(10);
        strcpy(a.name,"Zhao");
        b=a;
        f(b.name);
        b.gender='f';b.score=350;
        printf("%s,%c,%d,",a.name,a.gender,a.score);
        printf("%s,%c,%d\n",b.name,b.gender,b.score);
        return 0;
}

QQ图片20140910212420.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-11 19:24:34 | 显示全部楼层
强烈支持楼主ing……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-9-11 19:51:52 | 显示全部楼层
MyOrange 发表于 2014-9-10 21:28
赞以德服人
#include
#include

1.所以说,导致这两道题的b.name最终指向的字符串不同的原因就在于第一道题中形参p虽然最开始是接收了实参传过来的地址,但是后来通过malloc函数使p指向了与之前不同的地址单元,所以后来用strcpy函数改变p指向的字符串是不会影响b.name 指向的字符串的。
而在第二道题中,用strcpy函数改变p指向的字符串也会改变b.name指向的字符串。
我可以这样理解吗?
2.假设把第一道题中的 p=(char *)malloc(10);语句删除,结果b.name和a.name 输出都为Qian,这是因为b.name和a.name指向同一个地址,所以改变b.name所指向的地址的内容就等于改变了a.name所指向的地址的内容。可以这样理解吗?
3。第二道题中的b.name 所指向的地址的内容改变了,但是不影响a.name,这是因为一开始定义的时候两个的地址就不一样,可以这样理解吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-11 22:55:56 | 显示全部楼层
紫樱蜜柑 发表于 2014-9-11 19:51
1.所以说,导致这两道题的b.name最终指向的字符串不同的原因就在于第一道题中形参p虽然最开始是接收了实 ...

对。。。。。。我发现。。。。。。你叫赵茜?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-11 22:56:48 | 显示全部楼层
紫樱蜜柑 发表于 2014-9-11 19:51
1.所以说,导致这两道题的b.name最终指向的字符串不同的原因就在于第一道题中形参p虽然最开始是接收了实 ...

跟你说,你这么写代码很不规范的,看着都吃力
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-17 19:41:52 | 显示全部楼层
建议看看高质量C/C++编程 你所遇到的问题还不止这些,有野指针问题等。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-9-22 23:26:17 | 显示全部楼层
为什么新成员不能提问啊~~~~纠结
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-25 02:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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