LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 609|回复: 8

关于c 里面全局变量的疑惑

[复制链接]
发表于 2005-1-4 15:08:10 | 显示全部楼层 |阅读模式

  1. #define LIST_INIT_SIZE 100/*线性表存储空间初始分配量*/
  2. #define LISTINCREMENT 10/*线性表存储空间分配量增量*/
  3. #define INTSIZE sizeof(int)
  4. typedef struct{
  5.               int *elem;/*存储空间基基地址*/
  6.               int length;/*当前长度*/
  7.               int listsize;/*当前分配存储容量*/
  8. }Sqlist;

  9. Sqlist L;


  10.            
  11. Init()
  12. {
  13.    L.elem=(int *)malloc(LIST_INIT_SIZE*INTSIZE);
  14.   
  15.    L.length=0;
  16.    
  17.    L.listsize=LIST_INIT_SIZE;
  18.      return;
  19. }

  20. QInsert(Sqlist L,int a)/*插入一个元素*/
  21. { int t;
  22.    t=L.length;
  23.   L.elem[t]=a;
  24.   t=t+1;
  25.   L.length=t;
  26.   
  27.   }
  28.   
  29. Out(Sqlist L)/*输出所有元素*/
  30. {int temp;
  31. temp=0;
  32. for(;temp<L.length;temp+=1)
  33.     {
  34.       printf("L.[%d]:%d\n",temp,L.elem[temp]);
  35.      }
  36.   return;
  37. }
  38.   



  39.   
  40. main()
  41. {int t,in;
  42.   Init();
  43.   for(t=0;t<10;t++)
  44.     { in=rand();
  45.      printf("%d\n",in);
  46.       printf("ot L.length:%d\n",L.length);
  47.      QInsert(L,in);
  48.      }
  49.   Out(L);
  50. }
复制代码

声明L为全局变量,L.length也应该是全局变量啊,但是我用gdb跟踪L.length结果,发现每次QInsert没能改变L.length的值,QInsert返回后L.length总是为0, 请问这是怎么回事?
发表于 2005-1-4 15:17:46 | 显示全部楼层
因为参数里的 L 取代了全局的 L。
 楼主| 发表于 2005-1-4 15:24:15 | 显示全部楼层
是不是局部变量覆盖全局变量?
 楼主| 发表于 2005-1-4 15:28:13 | 显示全部楼层
谢谢,一直没注意这一点
但是我将QInsert函数改为一下

  1. QInsert(Sqlist p,int a)/*插入一个元素*/
  2. {  int t;
  3.    t=p.length;
  4.    
  5.   p.elem[t]=a;
  6.   t=t+1;
  7.   p.length=t;
  8.   }
复制代码

函数调用改为QInsert(L,in),仍然存在那个问题,是不是函数调用的时候,不区分传递参数是不是全局变量?
发表于 2005-1-4 17:17:35 | 显示全部楼层
void Foo(int a);
Foo(10);
这里的a叫做形式参数(parameter),简称形参;这里的10叫做实际参数(argument),简称实参。形参和式参之间是什么关系呢?他们是赋值的关系,也就是说:把实参传递给形参的过程,可以看作是把实参赋值给形参的过程。上面的例子中,实参10传递给形参a,就相当于a=10;这个赋值的过程。(因为数据类型多的很,无法举例子举全面,所以这里就不举例子了;如果觉得不好理解,就在vc中写个sample调试一下各种数据类型的情况,你就能够验证这个结论了。)

参见偶的一篇文章http://blog.vckbase.com/smileonce/archive/2004/11/05/1295.aspx
发表于 2005-1-4 17:20:12 | 显示全部楼层
补充:L虽然定义为全局变量。但是传参数的时候,全局的L传给了局部的 QInsert(Sqlist L,int a)/*插入一个元素*/中的L,函数内部的L是个局部量(也叫做自动量),你可以这么验证:
把函数改为:
QInsert(Sqlist X,int a)/*插入一个元素*/
然后用gdb跟进去看看。
 楼主| 发表于 2005-1-5 13:39:16 | 显示全部楼层
谢谢指导,你那篇文章不错,我看了,收获不小,
发现书虽然看了几遍,还是有很多地方理解的不是很清楚,在应用的时候就能发现问题,
按照你的建议,我将函数改为 QInsert(Sqlist p ,int a)/*插入一个元素*/
然后用g d b 跟踪,发现L.length仍然没有修改,在根据书上内容,函数传递参数有两种方式:1是传递数值,形参获得的是实参的拷贝;2是传地址
在QInsert(Sqlist ,int a)应该是传递数值方式,形参获得的是L的拷贝,虽然L是全局变量,但L获得的是L的拷贝,也就是局部变量,因为L..elem是一个地址,因此能够返回修改后变量,而L.length是值,也就无法返回

不知道这样的理解对不对,请大家指导!
谢谢
发表于 2005-1-5 13:44:08 | 显示全部楼层
在C中用指针传递,C++中用引用传递可以解决你的问题。

老兄,把基础的东西看清楚吧,书上都有的。
发表于 2005-1-8 09:25:55 | 显示全部楼层
形参和实参的问题,楼主先去看看这个东西吧,看了自然就明白你的问题出在什么地方了。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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