LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: jeffshia

一道c语言的改错题目,请大家考虑考虑

[复制链接]
发表于 2004-12-20 11:42:02 | 显示全部楼层
Post by herberteuler
呵呵,罚什么啊,我认罚

嘿嘿,玩笑话,咱们接着讨论,挺有意思的问题:)
发表于 2004-12-20 17:56:55 | 显示全部楼层
Post by suowei1979
不知我这样修改大家有什么不同的观点:)

#include<stdio.h>
#include<malloc.h>

void foo(int a,char **b)
{
    sprintf(*b,"you are %d years old!\n",a);
}

int main(void)
{
   char *f = (char *)malloc(64);
   foo(23,&f);
   printf("%s\n",f);
   free(f);
}


这样做岂不是多搞了一级指针吗?没有什么特别的意义吧。
 楼主| 发表于 2004-12-20 18:53:57 | 显示全部楼层
  1. char *f = (char *)malloc(64);
复制代码

似乎不用这样就可以的!
呵呵!
大家关键是把道理说明白!
 楼主| 发表于 2004-12-20 18:54:43 | 显示全部楼层
这个问题是很有意思的!
谁能说的能明白点儿呢?
发表于 2004-12-20 21:09:37 | 显示全部楼层
看这个程序:

  1. void foo(int a,char b)  {
  2.     b = 'b';
  3. }

  4. int main(void)  {
  5.     char f = 'a';
  6.     foo(23,f);
  7.     printf("%c\n",b);
  8. }
复制代码

你说最后大印的是a还是b?

再看:

  1. void foo(int a,char *b)  {
  2.     b = (char *)malloc(64);
  3.     snprintf(b,64, "you are %d years old!\n",a);
  4. }

  5. int main(void)  {
  6.     char *f = NULL;
  7.     foo(23,f);
  8.     printf("%s\n",b);
  9. }
复制代码

最后得到的是null还是"you are %d years old!"呢?

虽然malloc是分配在堆中了,但b却在栈中,调用foo时,仅仅把f的值,也就是null传递给b。当函数结束时,释放栈,这样b就释放了,但f的值并没有受到影响。

如果改char *f="I 'm 23 years old.",在foo中不使用malloc,而是直接snprintf,值就会改变。
发表于 2004-12-20 23:13:17 | 显示全部楼层
Post by suowei1979
不知我这样修改大家有什么不同的观点:)

  1. #include<stdio.h>
  2. #include<malloc.h>

  3. void foo(int a,char **b)
  4. {
  5.     sprintf(*b,"you are %d years old!\n",a);
  6. }

  7. int main(void)
  8. {
  9.    char *f = (char *)malloc(64);
  10.    foo(23,&f);
  11.    printf("%s\n",f);
  12.    free(f);
  13. }
复制代码

如果你在函数调用前分配内存,那么传双指针是多此一举,


  1. #include<stdio.h>
  2. #include<malloc.h>

  3. void foo(int a,char *b)
  4. {
  5.     sprintf(b,"you are %d years old!\n",a);
  6. }

  7. int main(void)
  8. {
  9.    char *f = (char *)malloc(64);
  10.    foo(23,f);
  11.    printf("%s\n",f);
  12.    free(f);
  13. }
复制代码


跟正解是同样结果,但偏离了题意,该题就是考双指针.当形参是单指针时,如果作为指针的实参没显式赋值(没分配地址),函数调用时,编译器仍当它为自动变量,函数返回后,啥都没变改,但如果调用前有给实参显式赋值(分配了地址),那就当成地址传递,地址里的值就会被调用函数改变.
而双指针编译器当它就是地址,任何地方改变它的值,它都会随之改变,包括当函数参数.

可以说得再明白一点:

  1. char* a;
  2. int   b;
复制代码

这两句,a是一个指针变量,b是一个整形变量,a如果不分配地址,它永远不叫"地址",只叫指针变量.你把它当参数传递,没有任何意义.;


  1. char** a;
  2. int   b[];
复制代码

这两句,a可以叫作指针数组,b是一个整形数组,这两个变量在任何地方出现都是地址;只不过在应用中,a和b都要指定大小:如

  1. char** a=(char*) malloc(10)...;
  2. int   b[10]=...;
复制代码


你可以把


  1. char** a=(char* )malloc(10);同
  2. char* a=(char* )malloc(10);
复制代码

作两种理解
 楼主| 发表于 2004-12-21 00:02:25 | 显示全部楼层
chowroc&yunjizi两位大侠分析得很透彻!
 楼主| 发表于 2004-12-21 11:34:12 | 显示全部楼层
  1. void foo(int a,char b)  {
  2.     b = 'b';
  3. }

  4. int main(void)  {
  5.     char f = 'a';
  6.     foo(23,f);
  7.     printf("%c\n",b);
  8. }
复制代码


这段代码是不是应该这样写呢?

  1. void foo(int a,char b)  {
  2.     b = 'b';
  3. }

  4. int main(void)  {
  5.     char f = 'a';
  6.     foo(23,f);
  7.     printf("%c\n",f);//这里测试的是f的值吧
  8. }
复制代码


可能是笔下之误
发表于 2004-12-21 18:44:44 | 显示全部楼层
对,应该写成:printf("%c\n",f);
发表于 2004-12-22 10:11:17 | 显示全部楼层
yunjizi兄
你说了这么多也不明白你到底想说什么,干脆把改正后的结果帖出来把
让我们看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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