关于全局变量的使用
时间:2008-05-26 11:10:18
来源:论坛整理 作者: 编辑:chinaitzhe
今天又来问问题了.关于全局变量的使用.
我写的是一个文本编辑器的程序.
用了不少的全局变量.
比如:当前选中的文字的范围,当前是不是自动换行状态,当前的字体的长和宽...等等这些信息.
这些变量基本上都在同一个函数里面用.
这个函数基本上是被不停的调用(回调函数).
开始在函数内部用的static,后来改成全局变量.
可是老大都说不行.
郁闷......
代替全局变量有什么办法?
(我觉得我的程序用值传递似乎不怎么适用);
网友回复:类成员怎么样...
网友回复:回调函数可以传入几个参数,把类的指针传进去就可以了
网友回复:我用的是C...
网友回复:类的静态成员
网友回复:做一个全局的结构体, 传参的时候就传该结构体的指针
网友回复:
我现在就是这样做的.还是全局的东西啊.
网友回复:顺便问一句:哪位大侠做过文本编辑器之类的东西?
用的是什么样的数据结构?
网友回复:假如是c++可以用类的静态变量,但是假如是c,可以用指针的地址传递来操作该变量
试试main中定义变量,然后传地址给调用函数,通过地址传递对该变量进行操作
网友回复:向你的老大问清楚:为什么不行?(难道就是因为全局变量多了?)
还有:你的程序应该用不上几个全局变量吧,是否‘全局’的定义得太多了?
网友回复:
我现在正在改成这个样子.
总感觉没什么意义......
每有一个全局变量就需要开辟线程来保护它.
全局变量用的..我觉得不怎么多...不过也不是很少,20 个,分别在几个struct里面.
网友回复:用全局变量确实不太好,不行的话就放到一个全局结构体中
网友回复:全局变量是不好,后期维护会有很多问题,各部分耦合太紧,一旦需求变化,代码可能需要整个重写!
不过我觉得你提到的当前选中的文字的范围,当前是不是自动换行状态,当前的字体的长和宽...等等这些信息,用全局变量没什么问题,只是最好不要直接去访问全局变量本身,而是像c 的类一样用函数封装起来
网友回复:我也知道全局变量用度了不好:)
现在我的这些变量除了个别,其他的都是分类放在以各个的结构体里面的.
全局的结构体.
网友回复:up
网友回复:up
网友回复:你的那个函数既然被另一个函数频繁调用
为什么不在调用函数内定义一个结构体变量 然后传递到被调用函数?
网友回复:假如不用全局变量的话,就只能传地址了。
网友回复:......
这个一般都是设计上的问题。
重新规划你的程序模型就好了(但是可能要重写哦)。
没什么太好的办法。 全局变更一定是可以隐藏的。
程序定型了,就很难有什么办法去弥补来隐藏它们。只会越改越乱。
你要明白,你的问题不是在全局变量上,而是在设计方法上。
网友回复:
网友回复:
网友回复:
程序结构还算清楚.(也许是因为从头到尾是自己写的,所以比较清楚)
重写的难度也不大.正预备重新规划一下.
再问一个以前的问题,得到满足的答案或者提示就加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 ) ; }
网友回复:这个我以前看过.
说实话,比我现在做的简单多了.很多东西都没涉及到.
不过非常感谢!
网友回复:看过!!!!
网友回复:
你看过什么?
网友回复:学习了。顶
网友回复:我顶下18楼
网友回复:想不出更好的方法了,帮顶下吧
网友回复:谢谢各位了:)
有哪位有任何想法请说出来.
过几天加分结贴:)
关键字:全局变量,使用,
上一篇:vim 源码分析
下一篇:下面没有链接了











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