关于全局变量的使用

时间:2008-05-26 11:10:18   来源:论坛整理  作者:  编辑:chinaitzhe
以前问过几个问题,得到了大家的帮助.
今天又来问问题了.关于全局变量的使用.
我写的是一个文本编辑器的程序.
用了不少的全局变量.
比如:当前选中的文字的范围,当前是不是自动换行状态,当前的字体的长和宽...等等这些信息.
这些变量基本上都在同一个函数里面用.
这个函数基本上是被不停的调用(回调函数).
开始在函数内部用的static,后来改成全局变量.
可是老大都说不行.
郁闷......
代替全局变量有什么办法?
(我觉得我的程序用值传递似乎不怎么适用);
网友回复:类成员怎么样...
网友回复:回调函数可以传入几个参数,把类的指针传进去就可以了
网友回复:我用的是C...
网友回复:类的静态成员
网友回复:做一个全局的结构体, 传参的时候就传该结构体的指针
网友回复:
引用 5 楼 xkyx_cn 的回复:
做一个全局的结构体, 传参的时候就传该结构体的指针

我现在就是这样做的.还是全局的东西啊.

网友回复:顺便问一句:哪位大侠做过文本编辑器之类的东西?
用的是什么样的数据结构?

网友回复:假如是c++可以用类的静态变量,但是假如是c,可以用指针的地址传递来操作该变量

试试main中定义变量,然后传地址给调用函数,通过地址传递对该变量进行操作
网友回复:向你的老大问清楚:为什么不行?(难道就是因为全局变量多了?)

还有:你的程序应该用不上几个全局变量吧,是否‘全局’的定义得太多了?

网友回复:
引用 8 楼 zhoujie99 的回复:
假如是c++可以用类的静态变量,但是假如是c,可以用指针的地址传递来操作该变量

试试main中定义变量,然后传地址给调用函数,通过地址传递对该变量进行操作

我现在正在改成这个样子.
总感觉没什么意义......


引用 9 楼 Chen8013 的回复:
向你的老大问清楚:为什么不行?(难道就是因为全局变量多了?)

还有:你的程序应该用不上几个全局变量吧,是否‘全局’的定义得太多了?

每有一个全局变量就需要开辟线程来保护它.
全局变量用的..我觉得不怎么多...不过也不是很少,20 个,分别在几个struct里面.
网友回复:用全局变量确实不太好,不行的话就放到一个全局结构体中
网友回复:全局变量是不好,后期维护会有很多问题,各部分耦合太紧,一旦需求变化,代码可能需要整个重写!

不过我觉得你提到的当前选中的文字的范围,当前是不是自动换行状态,当前的字体的长和宽...等等这些信息,用全局变量没什么问题,只是最好不要直接去访问全局变量本身,而是像c 的类一样用函数封装起来
网友回复:我也知道全局变量用度了不好:)

现在我的这些变量除了个别,其他的都是分类放在以各个的结构体里面的.
全局的结构体.
网友回复:up
网友回复:up
网友回复:你的那个函数既然被另一个函数频繁调用
为什么不在调用函数内定义一个结构体变量 然后传递到被调用函数?
网友回复:假如不用全局变量的话,就只能传地址了。
网友回复:......

这个一般都是设计上的问题。
重新规划你的程序模型就好了(但是可能要重写哦)。

没什么太好的办法。 全局变更一定是可以隐藏的。
程序定型了,就很难有什么办法去弥补来隐藏它们。只会越改越乱。

你要明白,你的问题不是在全局变量上,而是在设计方法上。
网友回复:
引用 1 楼 dahua010 的回复:
类成员怎么样...

网友回复:
引用 2 楼 ouyh12345 的回复:
回调函数可以传入几个参数,把类的指针传进去就可以了

网友回复:
引用 18 楼 cuibo1123 的回复:
......

这个一般都是设计上的问题。
重新规划你的程序模型就好了(但是可能要重写哦)。

没什么太好的办法。 全局变更一定是可以隐藏的。
程序定型了,就很难有什么办法去弥补来隐藏它们。只会越改越乱。

你要明白,你的问题不是在全局变量上,而是在设计方法上。


程序结构还算清楚.(也许是因为从头到尾是自己写的,所以比较清楚)
重写的难度也不大.正预备重新规划一下.

再问一个以前的问题,得到满足的答案或者提示就加100分.
有谁写过文本编辑器,纯C,不用任何控件,用的什么数据结构来存储数据?
谢谢!
网友回复:......

一般也就是链表。当然,不一定每次分配一个字符。
可以一次分配一行,或者一页等等,来节省指针浪费的空间。

文本编辑器 可以去google找的
建议去看linux上开源编辑器代码。 很多的。
比如vim(有点大).都有源代,看看别人怎么写的就明白了。

http://www.vim.org/
http://www.vim.org/sources.php

网友回复:我现在用的就是链表,双链表
一次分配一行的数据.
在google上没找到什么合适的.
vim看过~有点大......
网友回复:~~~
这个如何?
________________________________________________

C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



#include<stdio.h>  

  #include<malloc.h>  

  #include<string.h>  

  #include<stdlib.h>  

  #include<ctype.h>  

  #define     NULL   0  

  #define   MAX   100  

   

  typedef   struct   lnode{  

   

   

  char   date[MAX];             //存放数据  

  struct   lnode   *   prior   ;         //前驱  

  struct   lnode   *   next   ;           //后继  

  int   number   ;                           //记录一个节点的字符数!假如是头节点就记录他的节点个数  

  int   quese   ;                             //记录节点在链表中的位置  

   

   

   

  }lnodetype;  

   

  lnodetype   *   l   ;   //设置两个全局变量,分别是头节点指针和尾节点指针  

  lnodetype   *   end   ;  

   

   

  //**********这个函数是用来初始化的**********//  

  int   iniatelist   (lnodetype   **   l   ,   lnodetype   **   end)  

  {  

   

  (*l)   =   (lnodetype   *)malloc   (sizeof   (lnodetype)   )   ;  

  if   (   (*l)   ==   NULL   )  

  {  

   

  printf   ("没有只够的内存空间!程序即将退出!");  

  return   0   ;  

   

  }  

   

  (*l)->prior   =(*l)->next   =   NULL   ;   //这是双链表  

  (*l)->number   =   (*l)->quese   =   0;  

  (*end)   =   (*l)   ;  

   

  printf   ("程序初始化完毕!");  

  return   0;  

   

  }  

   

   

   

  //**********这个函数是用来建立节点,并且插入元素的**********//  

  int   link(lnodetype   **   l,   lnodetype   **   end)  

  {  

   

  lnodetype   *s   ;  

  s   =   (lnodetype   *)malloc   (   sizeof   (lnodetype)   )   ;  

  if   (   s   ==   NULL   ){  

   

  printf   ("内存空间不够,程序即将退出!")   ;  

  return   0   ;  

   

  }  

   

   

  (*end)->next   =   s   ;  

  s->prior   =   (*end)   ;  

  (*end)   =   (*end)->next   ;  

  (*l)->number     ;   //增加一个节点,头节点的number就加1  

  s->quese   =   (*l)->number   ;   //这个是记录节点在链表中的位置  

   

  printf   ("%d行",   s->quese   )   ;   //这个是节点在整个链表中的位置  

  gets(s->date)   ;  

  s   ->   number   =   strlen(s->date)   ;  

  return   0   ;  

   

   

  }  

   

   

   

  //**********这个是打印链表的函数**********//  

  int   prin   (lnodetype   **   l,   lnodetype   **   end)  

  {  

   

  lnodetype   *   p   ;  

  int   i   ;  

  int   j   =   0;  

  int   couter   =   (*l)->number   ;  

  p   =   (*l)->next   ;  

   

  for   (i=0;   i   <   couter;   i  ){  

   

  printf   (   "%d行"   ,   i 1   )   ;  

  j   =   0;  

  while   (   (   p->date[j]>='a'   &&   p->date[j]<='z')   ||  

  (p->date[j]>='A'   &&   p->date[j]<='z')   ||  

    p->date[j]>='0'   &&   p->date[j]<='9')  

  {  

   

  printf   (   "%c"   ,   p->date[j]   )   ;  

  j     ;  

   

  }  

  printf   ("n")   ;  

  p   =   p->next   ;  

   

  }  

   

  return   0   ;  

   

  }  

   

   

   

  //*********这个查找和编辑相应行的函数**********//  

  int   search   (lnodetype   **   l,   lnodetype   **   end   )  

  {  

   

   

  int   number   ;  

  scanf   ("%d"   ,   &number)   ;  

  int   i   ;  

  lnodetype   *   p   ;  

  p   =   (*l)->next   ;  

   

  for   (   i=0;   i<number-1;   i     )  

  p   =   p->next   ;  

   

  printf   ("%d行"   ,   number   )   ;  

  gets   (p->date)   ;  

  return   0   ;  

   

   

   

  }  

   

   

  //**********这个是在文本文件里搜索字符串的函数**********//  

  int   searchstr(lnodetype   **   l   ,   lnodetype   **   end)  

  {  

   

   

  char   ptr[100]   ;  

  int   arrycouter   ;  

  int   mystrcmp(   char   *,   char   *   ,   int   )   ;  

   

  printf   (   "ok!现在输入你查找的字符串!"   )   ;  

  scanf   (   "%s"   ,   ptr   )   ;  

  arrycouter   =   strlen   (ptr)   ;  

  lnodetype   *   s   ;  

  s   =   (*l)->next   ;  

  char   *   p   ;  

   

  int   i   =   1   ;  

  int   couter   =   0   ;  

  int   number   =   (*l)->number   ;  

  p   =   (char   *)s->date   ;  

   

   

  while   (   i   &&   number   ){  

   

                                          //   i=1是,证实没有找到,向第二个节点继续寻找  

   

  while   (   i   &&   (   (   (*p   >=   'a')   &&   (*p   <=   'z')   )   ||   (   (*p   >=   'A')   &&   (*p   <=   'Z')   )   )   ){  

   

   

  i   =   mystrcmp   (   p   ,   ptr   ,   arrycouter   );  

   

   

  if   (   i   ==   1   ){  

   

  printf   ("字符串已经在第%d行,第%d个字符开始,",s->quese,   couter 1   );  

  i   =   0   ;  

  }  

  else  

  {  

  p     ;  

  couter  ;  

  i   =   1   ;  

  }  

   

  }  

   

  s   =   s->next   ;  

  p   =   (char   *)s->date   ;  

  number   --   ;  

   

  }  

   

  if   (   i   ==   1   )  

  printf   ("字符串在本文档中不存在!");  

  return   0   ;  

   

   

  }  

   

   

  //**********(1)这个函数是用来实现退出不保存功能的**********//  

  int   exitunsave(lnodetype   **   l,   lnodetype   **   end)  

  {  

   

  lnodetype   *   s   ;  

  while(   (*l)   !=   (*end)   ){   //假如不保存的话,最好是把节点的空间都释放,节省空间  

   

  s   =   (*end)   ;  

  (*end)   =   (*end)->prior   ;  

  free(   s   )   ;  

   

  }  

   

  return   0   ;  

   

   

  }  

   

   

  //**********(2)这个函数是用来实现退出但保存功能的**********//  

  int   quitandsave(   lnodetype   **   l   ,   lnodetype   **   end   )  

  {  

   

  FILE   *   fp   ;  

  char   ch   ;  

  char   filename[20]   ;  

  lnodetype   *   p;  

  int   i   ;  

  int   j   ;  

  int   couter   =   (*l)->number   ;  

   

  p   =   (*l)->next   ;  

   

  printf   ("请输入文件名:")   ;  

  scanf   ("%s"   ,   filename   )   ;  

   

  if   (   (fp   =   fopen(   filename   ,   "w"   ))   ==   NULL   ){  

   

  printf   ("文件不能打开!n");  

  return   0   ;  

   

  }  

   

   

  for   (   i=0;   i<couter;   i     ){   //有几个节点就进行多少次的存贮  

   

  ch   =   p->date[0]   ;  

  j   =   1   ;  

   

  while   (ch   !=   '\0'){  

   

  fputc   (ch   ,   fp)   ;  

  ch   =   p->date[j]   ;  

  j     ;  

   

  }  

   

  p   =   p->next   ;  

  fputc   (   '#'   ,   fp   )   ;   //注重在每个节点的后面加上结束的符号  

   

  }  

   

   

  fputc   (   '@'   ,   fp   )   ;   //整个文件关闭的标志  

  fclose   (   fp   )   ;   //注重关闭文件,  

  return   0   ;  

   

  }  

  //**********由于库函数比较字符串提供的功能不满足要求,故自己写了一个**********/  

  int   mystrcmp(   char   *   p   ,char   *   sour   ,int   number   )  

  {  

   

  while   (   number   &&   (*p)   ==   (*sour)   &&  

  (   (   (*p   >=   'a')   &&   (*p   <=   'z')   )   ||   (   (*p   >=   'A')   &&   (*p   <=   'Z')   )   )){  

   

  p     ;  

  sour     ;  

  number--   ;  

   

  }  

   

   

  if   (   number   ==   0   )  

  return   1   ;  

  else  

  return   0   ;  

   

   

  }  

  


网友回复:
C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



//**********这个函数是用来实现统计字符串功能的**********//  

  int   coutword(lnodetype   **   l   ,   lnodetype   **   end)  

  {   //考虑到只统计一行的单词没有意义,故统计整个文本  

   

  int   yes   =   1   ;   //这个是进入单词的标志  

  int   no   =   0   ;   //在单词外面的时候的标志  

  int   i   ,   j   ,inaword   ,count   =   0   ;  

  inaword   =   no   ;  

  lnodetype   *   s   =   (*l)->next   ;  

   

  for   (j=0;   j<(*l)->number;   j  ){  

   

  for   (   i=0;     (s->date[i]>='a'   &&   s->date[i]<='z')   ||  

  (s->date[i]>='A'   &&   s->date[i]<='z')   ||  

  (s->date[i]>='0'   &&   s->date[i]<='9'   )   ||  

  (s->date[i]=='   ');     i       )  

  {  

   

  if   (   s->date[i]   ==   '   '   )  

  inaword   =   no   ;  

  else  

  if   (   inaword   ==   no   )  

  {  

  inaword   =   yes   ;  

  count     ;   //计算单词  

  }  

   

   

  }  

   

  s   =   s->next   ;  

  inaword   =   0   ;   //注重这里,把标志置为0了!  

   

  }  

   

  printf   (   "n文本一共有   %d   行"   ,   (*l)->number   )   ;  

  printf   ("n此文本一共有   %d   个单词!"   ,   count   )   ;  

   

  return   count   ;  

   

   

  }   



//**********这个函数是用来实现计算文本行数功能的**********//  

  int   linecouter(lnodetype   **   l   ,   lnodetype   **   end   )  

  {  

   

  int   couter   ;  

  couter   =   (*l)->number   ;  

  return   couter   ;  

   

  }  

   

  //**********这个函数是整和一上所有功能的菜单函数**********//  

  int   editmenu(lnodetype   **   l   ,   lnodetype   **   end   )  

  {  

   

   

  char   choice   ;  

  char   *   p   =   "cls"   ;  

  int   i   =   1   ;   //这两个变量是用来控制循环的  

  int   j=   1   ;  

  system   (p)   ;  

  prin   (&(*l)   ,   &(*end))   ;  

   

  while   (j){  

   

  printf   ("***********************************   e:   编辑相应行     *************************************n")   ;  

  printf   ("***********************************   s:   搜索字符串     *************************************n")   ;  

  printf   ("***********************************   t:   统计单词个数     ***********************************n")   ;  

  printf   ("***********************************   q:   退出编辑     ***************************************n")   ;  

   

  scanf("%c",&choice);  

  scanf("%c"   ,   &choice)   ;   //????莫名其妙的问题,非要两个请求输入语句才肯停下来!  

  switch   (choice)  

  {  

  case   'e'   :   {  

  i   =   1   ;  

  while   (i)  

  {  

  search(   &(*l)   ,   &(*end)   );  

  system   (p)   ;  

  prin(   &(*l)   ,   &(*end)   )   ;  

  printf   ("n1   继续编辑     0   结束编辑n")   ;  

  scanf   ("%d"   ,   &i)   ;  

   

  }  

   

  }  

   

  break;  

  case   's'   :   {  

   

  i   =   1   ;  

  while   (i)  

  {  

  searchstr(   &(*l)   ,   &(*end)   );  

  getchar();  

  getchar();  

  system   (p)   ;  

  prin(   &(*l)   ,   &(*end)   )   ;  

  printf   ("n1   继续搜索     0   结束搜索n")   ;  

  scanf   ("%d"   ,   &i)   ;  

   

  }  

   

   

          }  

  break;  

  case   't'   :   {  

   

  coutword   (   &(*l)   ,   &(*end)   )   ;  

  getchar()   ;  

   

   

  }break;  

   

  default   :   return   0   ;  

   

   

  }  

   

  system   (p)   ;  

  prin(   &(*l)   ,   &(*end)   )   ;  

  printf   ("n1   回到编辑菜单     0   结束编辑n")   ;  

  scanf   ("%d"   ,   &j)   ;  

  if   (j   ==   1)  

  system   (p)   ;  

  else  

  return   0   ;  

   

  }  

   

   

  return   0   ;  

  }  

   

   

  //**********实现第一个模块:新建空白文档**********//  

  int   newtext(   lnodetype   **   l   ,lnodetype   **   end   )  

  {  

   

  printf   (   "新文本文件:n"   )   ;  

  int   i   =   1   ;  

  char   judstr[MAX]   ;  

  lnodetype   *   temp   ;  

  char   jud   ;  

  char   *   p   =   "cls"   ;  

   

  while   (   1   ){  

   

  link(   &(*l)   ,   &(*end)   )   ;  

  jud   =   (*end)->date[0]   ;  

   

  if   (   jud   ==   '5'   ){   //输入‘5’结束一切  

   

  temp   =   (*end)   ;  

  (*end)   =   (*end)->prior   ;  

  free   (temp)   ;  

   

  while   (1){  

   

  printf   (   "*******************************     out     :退出不保存     ****************************n")   ;  

  printf   (   "*******************************     edit   :编辑信息       *****************************n")   ;  

  printf   (   "*******************************     quit   :退出而不存盘     **************************n")   ;  

  printf   (   "*******************************     qas     :退出且存盘     ****************************n")   ;  

  printf   (   "*******************************     con     :继续输入!     *****************************n")   ;  

   

  gets(judstr)   ;  

   

  if   (   !strcmp(judstr   ,   "out")   )  

  {  

  exitunsave(   &(*l)   ,   &(*end)   )   ;  

  return   0   ;  

  }  

  else  

  if   (   !strcmp(judstr   ,   "qas")   )  

  {  

  quitandsave(   &(*l)   ,   &(*end)   )   ;  

  return   0   ;  

  }  

  else  

   

  if   (   !strcmp(judstr   ,   "edit")   )  

  {  

   

  editmenu   (l   ,   end)   ;  

  return   0;  

   

  }  

   

   

  system   (p)   ;  

   

   

   

   

   

  }  

  return   0   ;  

   

  }  

   

  }  

   

  return   0   ;  

   

   

  }  

   






网友回复:
C/C code





Code highlighting produced by Actipro CodeHighlighter (freeware)

http://www.CodeHighlighter.com/



   

  //**********这个是装入文件的函数**********//  

  int   loadtaxt(   char   *   filename   )  

  {  

   

  FILE   *   fp   ;  

  lnodetype   *   l   ;  

  char   ch   ;  

  int   i   =   0   ;  

  char   *   p   =   "cls"   ;  

  char   judstr[MAX]   ;  

  lnodetype   *   head   ;  

  lnodetype   *   end   ;  

   

  iniatelist   (   &head   ,   &end)   ;  

  l   =   end   =   head   ;  

   

  if   (   (fp   =   fopen(   filename,   "r "))   ==   NULL   ){  

   

  printf   ("文件不能打开!n")   ;  

  return   0   ;  

   

  }  

   

  ch   =   fgetc   (   fp   )   ;  

  while   (   ch   !=   '@'   ){  

   

  lnodetype   *s   ;  

  s   =   (lnodetype   *)malloc   (   sizeof   (lnodetype)   )   ;  

  if   (   s   ==   NULL   ){  

   

  printf   ("内存空间不够,程序即将退出!")   ;  

  return   0   ;  

   

  }  

   

   

  end->next   =   s   ;  

  s->prior   =   end   ;  

  end   =   end->next   ;  

  l->number     ;  

  s->quese   =   l->number   ;  

  printf   ("%d行",   s->quese   )   ;  

   

   

  while   (   ch   !=   '#'){  

   

   

  s->date[i]   =   ch   ;  

  ch   =   fgetc   (fp)   ;  

  i     ;  

   

   

  }  

  i   =   0;  

  while   (   (end->date[i]>='a'   &&   end->date[i]<='z')   ||  

  (end->date[i]>='A'   &&   end->date[i]<='z')   ||  

  (end->date[i]>='0'   &&   end->date[i]<='9'   )   ||  

  (end->date[i]=='   ')   )  

  {  

   

  printf   (   "%c"   ,   end->date[i]   )   ;  

  i     ;  

   

   

  }  

  end->date[i]   =   '\0'   ;   //注重在节点的最好加上这个,以让退出保存功能函数知道此节点已结束  

   

  printf   (   "n"   )   ;  

  i   =   0;  

  ch   =   fgetc   (   fp   )   ;  

   

  }  

   

  fclose   (fp)   ;  

   

   

  printf   ("n文件成功装入!n")   ;  

  while   (1){  

   

  printf   (   "*******************************     out     :退出不保存     ****************************n")   ;  

  printf   (   "*******************************     edit   :编辑信息       *****************************n")   ;  

  printf   (   "*******************************     qas     :退出且存盘     ****************************n")   ;  

  printf   (   "*******************************     con     :继续输入!     *****************************n")   ;  

   

  scanf("%s",judstr);  

   

  if   (   !strcmp(judstr   ,   "out")   )  

  {  

  exitunsave(   &l   ,   &end   )   ;  

  return   0   ;  

  }  

  else  

  if   (   !strcmp(judstr   ,   "qas")   )  

  {  

  quitandsave(   &l   ,   &end   )   ;  

  return   0   ;  

  }  

  else  

   

  if   (   !strcmp(judstr   ,   "edit")   )  

  {  

   

  editmenu   (&l   ,   &end)   ;  

  return   0   ;  

   

  }  

   

  system   (p)   ;  

   

   

   

   

   

  }  

   

   

   

  return   0   ;  

   

  }  

   

  //**********主函数**********//  

   

  void   main   (   void   )  

  {  

   

  //iniatelist   (&l   ,   &end)   ;  

  //newtext(&l   ,   &end)   ;  

   

  char   filename[MAX]   ;  

  scanf   (   "%s"   ,   filename   )   ;  

  loadtaxt(   filename   )   ;  

   

   

  }  


网友回复:这个我以前看过.
说实话,比我现在做的简单多了.很多东西都没涉及到.
不过非常感谢!
网友回复:看过!!!!
网友回复:
引用 28 楼 xiaopei1982 的回复:
看过!!!!

你看过什么?
网友回复:学习了。顶
网友回复:我顶下18楼
网友回复:想不出更好的方法了,帮顶下吧
网友回复:谢谢各位了:)
有哪位有任何想法请说出来.
过几天加分结贴:)
关键字:全局变量,使用,
上一篇:vim 源码分析

相关文章

文章评论

共有 0 位网友发表了评论 此处只显示部分留言 点击查看完整评论页面