|
![]() | 作者: ljsh012 [ljsh012]
![]() |
登录 |
这是我用c写的顺序栈,我想把它改成面向对象的(原因是我想实现像vc++那样程序员在编写程序时直接可以调用push,pop函数) 当然要实现这个功能可能还要涉及编译器的内容。(比如在编译时编译系统会自动把类加载进去)。所以目前只能实现通过对象来调用入栈出栈函数。 希望大家转一分好的给出来,让我体会一下两者。谢谢。(写的英文可能有不少语法错误,望谅解,这方面得向“月之御者”学习) #include <stdio.h> #include <stdlib.h> #define datasize 100 typedef struct { char data[datasize]; int top; /*top作为数组下标,同时兼有栈点指针功能*/ }stack; void initstack(stack *s) { s->top=-1; /*top为1时表示栈空*/ } int isEmpty(stack *s) { if(s->top==-1) return(1); else return(0); } int isFull(stack *s) { if(s->top==datasize-1) return(1); else return(0); } void push(stack *s,char x) { if(isFull(s)) { printf("stack is full,you must pop the element"); } else { s->data[++s->top]=x; /*此处把形参x的值赋给data[0],因为++在前*/ } } char pop(stack *s) { if(isEmpty(s)) { printf("stack is empty,you must push the elements"); } else { return(s->data[s->top--]); /*出栈时先返回出栈的元素,然后指针自减一次,指向下一元素*/ } } char getTopStack(stack *s) { if(isEmpty(s)) { printf("no emlement"); } else { return(s->data[s->top]); } } void print(stack *s) {int i; for(i=s->top;i>=0;i--) printf("%c\n",s->data[i]); } main() { stack *p; char c,sqc,sq; initstack(p); printf("please enter any char into stack until enter '0'\n"); c=getche(); while(c!='0') { push(p,c); c=getche(); } /*print(p); getch(); pop(p); print(p); getch();*/ sqc=getTopStack(p); printf("\nNow the top element of stack is: '%c'\nplease enter any char to show all elements of the stack\n",sqc); getch(); printf("Now list the stack's elements:\n"); print(p); printf("please enter any char to pop the top element,and show the top element of stack after popstack\n"); getch(); sqc=pop(p); sq=getTopStack(p); printf("The just top element: '%c' have been poped,and now the top element is: '%c'\n",sqc,sq); getch(); } [此贴被 霜泉(ljsh012) 在 12月23日18时03分 编辑过] [此贴被 霜泉(ljsh012) 在 12月24日18时00分 编辑过] |
地主 发表时间: 04-12-23 15:08 |
![]() | 回复: 286 [unique] ![]() |
登录 |
C的程序无法使用面向对象吧。你应转成C++的。然后封装成一个类就行了。 |
B1层 发表时间: 04-12-23 19:14 |
![]() | 回复: kert_t8 [kert_t8] ![]() |
登录 |
首先声明,这个程序没法用,不过怎么没法用我实在是搞不清楚,反正再编译的时候出一大堆错,不过因为程序简单,想来大家看一看也能明白是怎么回事,再者,楼主的程序我复制粘贴也没法用,稍微修改了一下可以编译通过,但是好像运行结果还是有问题 〉。。。。我现在开始怀疑是编译器的问题了 Anyway 引用: 写得不好,可以批评,不要嘲笑 ![]() 太晚了,睡了 Merry X'mas Everyone [此贴被 月之御者(kert_t8) 在 12月23日21时38分 编辑过] |
B2层 发表时间: 04-12-23 21:33 |
![]() | 回复: ljsh012 [ljsh012] ![]() |
登录 |
首先感谢搂上的您(你)们。 真是不好意思。 我贴程序时粗心了一些。下面是编译通过并且能正确运行的。但有点警告。(错误原因在后面) #include <stdio.h> #include <stdlib.h> #define datasize 100 typedef struct { char data[datasize]; int top; /*top作为数组下标,同时兼有栈点指针功能*/ }stack; void initstack(stack *s) { s->top=-1; /*top为-1时表示栈空*/ } int isEmpty(stack *s) { if(s->top==-1) return(1); else return(0); } int isFull(stack *s) { if(s->top==datasize-1) return(1); else return(0); } void push(stack *s,char x) { if(isFull(s)) { printf("stack is full,you must pop the element"); } else { s->data[++s->top]=x;/*此处把形参x的值赋给data[0],因为++在前*/ } } char pop(stack *s) { if(isEmpty(s)) { printf("stack is empty,you must push the elements"); } else { return(s->data[s->top--]); /*出栈时先返回出栈的元素,然后指针自减一次,指向下一元素*/ } } char getTopStack(stack *s) { if(isEmpty(s)) { printf("no emlement"); } else { return(s->data[s->top]); } } void print(stack *s) {int i; for(i=s->top;i>=0;i--) printf("%c\n",s->data[i]); } main() { stack *p; char c,sqc,sq; initstack(p); printf("please enter any char into stack until enter '0'\n"); c=getche(); while(c!='0') { push(p,c); c=getche(); } /*print(p); getch(); pop(p); print(p); getch();*/ sqc=getTopStack(p); printf("\nNow the top element of stack is: '%c'\nplease enter any char to show all elements of the stack\n",sqc); getch(); printf("Now list the stack's elements:\n"); print(p); printf("please enter any char to pop the top element,and show the top element of stack after popstack\n"); getch(); sqc=pop(p); sq=getTopStack(p); printf("The just top element: '%c' have been poped,and now the top element is: '%c'\n",sqc,sq); print(p); getch(); } 原先的错误程序是在push函数中, void push(stack *s,char x) { if(isFull(s)) { printf("stack is full,you must pop the element"); } else { s->data[++s->top]=x;/*这一句有问题,我把后面的分号去了之后再打入分号就编译通过并且执行成功了我也不知道什么原因,在去掉那个分号前,自己多出来一个乱码,去掉就成功了,正在查是什么原因....*/ } } [此贴被 霜泉(ljsh012) 在 12月24日18时19分 编辑过] [此贴被 霜泉(ljsh012) 在 12月24日23时05分 编辑过] |
B3层 发表时间: 04-12-24 17:59 |
![]() | 回复: ljsh012 [ljsh012] ![]() |
登录 |
得到那个乱码了. s->data[++s->top]=x;?*此处把形参x的值赋给data[0],因为++在前*/ 从注释那里开始按向前取消键,快到分号那里那个乱码就会自动出现. 我不知道什么原因.你们看看去. |
B4层 发表时间: 04-12-24 18:28 |
![]() | 回复: ljsh012 [ljsh012] ![]() |
登录 |
再次感谢月之御者.我要的正是c++的面向对象的.我还没系统的看过一本c++的书,这次仅是想从这两者间窥出一点什么东西. 你的程序是在我的基础上改的,当然局限在我的程序下了,不好发挥了.非常感谢. |
B5层 发表时间: 04-12-24 18:38 |
![]() | 回复: kert_t8 [kert_t8] ![]() |
登录 |
还是有问题,两个程序都是,我的编译器上面就通不过,下面把错误信息贴出来,高人帮忙看一下,我实在是.......哎![]() 引用: |
B6层 发表时间: 04-12-24 19:01 |
![]() | 回复: ljsh012 [ljsh012] ![]() |
登录 |
你是linux下的gcc? 我没用过,但是初步看了看错误信息,他说getch和getche等有问题,是不是头文件没有包含进去。或者他不是用getch而是用getchar. 我是在wintc下包括其他win下的c编译器都通过了。知者赐教。 |
B7层 发表时间: 04-12-24 19:30 |
![]() | 回复: kert_t8 [kert_t8] ![]() |
登录 |
买不到盗版软件,我装不了VC啊,只有用学校的机器了,然而学校只有一个windows机房,使用的时候还要钱,只有忍了,小弟也是苦啊 不过倒是用gcc显得很高手 ![]() |
B8层 发表时间: 04-12-24 19:50 |
![]() | 回复: kert_t8 [kert_t8] ![]() |
登录 |
那个C++的,实在是不知道哪里的问题 算了,贴个java版的吧 getter.java 用于输入,代码重用而已,所以不是很适合本程序,不过凑合着用 代码: stack.java 代码: |
B9层 发表时间: 04-12-24 20:56 |
![]() | 回复: lida1818 [lida1818] ![]() |
登录 |
main() { stack *p; char c,sqc,sq; initstack(p); //这个p你给它分配了空间吗? printf("please enter any char into stack until enter '0'\n"); c=getche(); while(c!='0') { |
B10层 发表时间: 04-12-24 21:01 |
![]() | 回复: kert_t8 [kert_t8] ![]() |
登录 |
这个,我还有一点不明白 既然楼主是用数组实现的,为何还一定要用指针呢? |
B11层 发表时间: 04-12-24 21:35 |
![]() | 回复: ljsh012 [ljsh012] ![]() |
登录 |
这里因为用的是结构体,所以声明一个结构体指针方便指向结构体里的变量(变量应该可以理解成属性).当然不用结构体也行,但实现栈顶指针就有点麻烦了. 如果直接用数组下标作为当前栈顶,那么,c在初始化数组时已经分配0给每个元素了,那么判断栈空或者栈顶就不行了,比如,top为datasize-1时为栈满,光用数组下标的话这一top随时都成立,而只能把他作为单独的来统计,现在既然要分开来,就用结构体来实现了.而且方便结构体中的属性的类型的改变.更复杂的堆栈也可以进行下去. 另外,那个p是指向结构体的指针,而结构体先前已经定义了,p就有意义了。(好像声明指针都不分配空间给指针的(忘了,知者说明一下),只是把某个地址赋给它时,他才有意义。)而这里他是已经是一个前面定义的结构体的指针了。 说了这麽多,或许其中有写错误。还望见谅。而且希望大家指正。 |
B12层 发表时间: 04-12-24 23:37 |
![]() | 回复: lida1818 [lida1818] ![]() |
登录 |
从你楼上所言,反映了两个问题: 1.对指针概念及内涵、使用楼主还不是很明确。 2.对自定义数据类型的“声明”与“定义”概念混淆。 |
B13层 发表时间: 04-12-25 01:01 |
![]() | 回复: lida1818 [lida1818] ![]() |
登录 |
结构体的定义还是这样更清晰,不然象你的写法连你自己都搞不清楚是定义还是声明^_^ struct stack { char data[20]; int top; }; typedef struct stack STACK; 然后再 STACK *p; 使用指针前,必须给它一个"合法"的空间,我看你回楼下的这个关于指针问题贴子(第二个问题),你不是知道吗?怎么自己写就晕了? |
B14层 发表时间: 04-12-25 01:22 |
![]() | 回复: ljsh012 [ljsh012] ![]() |
登录 |
感谢搂上的大言无畏. 我一直以为如果是光学的话,没必要搞清声明和定义的概念,究竟谁指谁? 但是一旦要你讲个所以然的话,就傻眼了.确实,我以前我搞清过这两个概念.但是很久以后我又不知怎的又忘了这个概念. 还请搂主讲讲声明和定义的概念.再举个例子更佳.谢谢. 但是.我也想反驳你的一点点. 你完全理解typedef吗?下面是我的理解: 我们可以这样来看.typedef 某某(c中已有的类型)为某某(我们想要的一个简单好看的单词来代之前面的某某,后面这个某某完全有前面那个某某的功能,而且可以用它再来声明此类型的变量)。 以此来看的话。我上面的我决得并不像你说的那样。我反倒觉得你的分开反而麻烦了。 你看这个结构: typedef struct { char data[datasize]; int top; /*top作为数组下标,同时兼有栈点指针功能*/ }stack; 套用上面的某某到某某,那么,我现在的stack,已经是一个自定义的类型跟c中已经有的结构体类型相同的类型了。所以,我后面直接用它来声明指针(声明和定义我还是 不想的话有点混淆,但我觉得按我想的话应该还是对的,不说这个,我等你的具体的解释) 说实话。我觉得你后面的跟我的完全等价。 (今天喝了点酒,可能罗嗦了一点。本不想在这种情况下回复的,但是,看到你的直言不讳,我忍不住了。晕头中写上以上,大家不要笑阿) [此贴被 霜泉(ljsh012) 在 12月25日02时48分 编辑过] |
B15层 发表时间: 04-12-25 02:38 |
![]() | 回复: lida1818 [lida1818] ![]() |
登录 |
呵呵,你真的清楚了吗? 那你回答两个问题: 1。你的 typedef struct { char data[datasize]; int top; /*top作为数组下标,同时兼有栈点指针功能*/ }stack; 是定义了一个stack的数据类型,还是声明了一个stack类型的变量? 或者是既定义了一个stack的数据类型同时又声明了一个stack类型的变量? 怕是你自己也不知道吧? 2。什么是指针初始化?什么叫野指针?你的p指向什么空间? |
B16层 发表时间: 04-12-25 03:23 |
![]() | 回复: lida1818 [lida1818] ![]() |
登录 |
多说一句,写代码还是规范点好,如果你认为C的某些纯技巧性写法很有意思,不妨看看国际C语言混乱代码大赛作品。乱也得乱出点味道^_^ #include <stdio.h> #include <conio.h> int a,b,c,d,e,f,t;main(_){!(_-1)&&(d=(e=(f=(c=b=((a=(t=1)+t)*a+t))*a)*a)-f-c+t);_<37&&(t==1?(a+=3,a==e&&(e-=3,t=2)):t==2?(b++,b==f&&(f--,t=3)):t==3?(a-=3,a==c&&(c+=3,t=0)):t==0?(b--,b==d&&(d++,t=1)):0,gotoxy(a,b),printf("%3d",_),_++)&&main(_);} 附上我写的蛇形方程,请指教! |
B17层 发表时间: 04-12-25 03:55 |
![]() | 回复: ljsh012 [ljsh012] ![]() |
登录 |
搂上的,我现在头还在还在半晕.酒精还没全部分解. 你问我的两个问题,我回答如下,我没查任何书,(如果查下书的话可能会回答的好一些,当然等到我头脑清醒时我就会重新复习一下上面自以为懂了但实际上要究个原因时就有些含混的东东) 1: 按照我先前所说的: 我用typedef自定义了一个stack类型,而这个类型是c下已经有的struct(结构体)类型.里面的属性任意,但得符合c的变量声明的规则. 2. 第二个问题我确实忘的差不多了.也就不准备回答. 但是要用的话.我知道自己要用的指针要指向什么类型,那么就得把该指针声明为什么类型.至于野指针,我听说过,但是我不知道我是否会用,或者我曾经用过,但自己不知道这就是所谓的野指针了. 恕我直言,搂上的如果很清楚这些东西话,我上面已经诚恳的请教了.为何不答?如果仅是为了究出我的错误,那么,你有什么目的呢?(当然能究出错误已经很好了,我不会因为自己的无知而羞愧的,正因如此我才到此地)我希望的是你的见解,任何人都有自己的理解方法,我们到这里无非是寻求别人的理解方法,来提高自己.(毕竟任何人都是渺小的,局限的,我们需要大家各自的思想,来窥见自己的不足. 所以,还是诚恳向你请教.更希望你把上面所争执(这词可能用的不好)的,帖出你的思想.别人不说,我就想看.因为我自己去看书,没过多久我可能又忘记了.而你将要说的,或许会激起我的永久的记忆. 谢谢!! |
B18层 发表时间: 04-12-25 05:45 |
![]() | 回复: kert_t8 [kert_t8] ![]() |
登录 |
我说一下我的看法 小弟刚刚开始学C,说错了也属情理之中 首先: 引用: 其次: 引用: 那么从上面的例子上来看,定义一个structure只有一个办法,就是老老实实的 struct [name] { 内容 }; 然而声明则有两个方法 1: struct <name> <variable_name>; 2: struct [name] { 内容 }<variable_name>; 现在呢,由于我们觉得每一次声明的时候使用1的方式太麻烦,太长了,所以可以使用 #define <name_2> strcut <name> 的方式来简便的代替原来的那么长的一串 现在再来看 引用: 那么,按照上面的说法typedef也仅仅就是给原来的类型换了一个名字而已,并没有新的内容,既没有新的定义,也没有新的声明。看起来好像是和#define的方式差不多 好,再说楼主的程序 代码: 本来,这个一段代码看起来非常像上面给出的定义并声明,然而我们应该更仔细的分析typedef的语法,整个的struct{....}这一段实际上都是类型名,后面的stack被解释成struct的标识符,这就是#define方式和typedef方式的不同。 所以,结论就出来了,楼主定义了一个叫做stack的结构,而不是一个叫做stack的变量。楼主显然认识到了这一点,否则的话他不会使用stack *p来定义一个指针,不过好像他确实是忘了为这个指针分配空间 ![]() 真是够复杂的 而且我还是不明白,要使用这个stack,直接使用 stack instant; instant.top=number; instant.data[top]=character 不就行了吗?为什么一定要使用指针呢?(我还真是愚钝的可以 ![]() [此贴被 月之御者(kert_t8) 在 12月25日10时56分 编辑过] |
B19层 发表时间: 04-12-25 09:42 |
![]() | 回复: kert_t8 [kert_t8] ![]() |
登录 |
还有一个问题,我没有看出来使用typedef struct{} [struct_name] 的方式定义有什么不好啊? 除非,除非,除非这种方式还可以同时声明一个变量。但是事实证明是不可以的啊 |
B20层 发表时间: 04-12-25 11:02 |
![]() | 回复: ljsh012 [ljsh012] ![]() |
登录 |
回楼上的 不用指针也行.直接用结构体变量加"."的方式访问结构体的成员.但一般好像多数人都喜欢用指针然后->的方式。这就是为什么c要搞出个“p->”的原因,完全可用你说的代替。 我的实参p确实没有给他空间,没指向任何变量。(让它指向该指向的就行了)但它属于结构体类型的指针。所以编译器还能够识别他。也就有了上面我说的编译通过了但是有警告。(如此之后并无警告了) 现更正如下: main() { char c,sqc,sq; stack *p,a; p=&a; ........ ....... } 另外,如果你一定不想要指针,那么那些函数的形参都要更改。因为上面的函数都是以指针作为传递参数。所以我觉得还是指针简单一些(因为指针习惯用一个字母就行。结构体变量的话得一个英文单词 ![]() 感谢“烟雨平生” 感谢“月之御者”。 |
B21层 发表时间: 04-12-25 21:27 |
![]() | 回复: kert_t8 [kert_t8] ![]() |
登录 |
明白了 我还需补一补指针的知识啊!忘完了 |
B22层 发表时间: 04-12-25 21:38 |
![]() | 回复: lida1818 [lida1818] ![]() |
登录 |
TO:19楼 你分析得没错,#define 和 typedef可能会产生相同的效果,但是他们不是一会事,简单地说前者是“查找并替换",而后者是起一个“别名“,指针是C的一大特色,C的灵魂所在,运用妥当可以减少程序运行时间等等。 TO:楼主 看来你已经明白你的程序错误之处了,你原来的程式可能可以编译运行,那是你的运气,因为p指向一个随机的空间(地址),如果这个空间刚好是空闲的(直到你的程序运行结束还是),那么,就不会出错。如果,P指向系统已分配的地址,结果可想而知.这就是所谓的野指针! 昨天,我觉得我已经说清楚了,因为我刚好看了你回答别人的一个贴子中有类似的问题,所以觉得只指出来你就能知道。 |
B23层 发表时间: 04-12-25 22:12 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号