栈的输出的c语言代码。。

c语言中栈的栈顶元素为什么有时候用L->top,有时候用L.top这两个有什么区别,栈的元素从栈底到栈顶输出的c语言代码怎么写,谢谢各位大神了

4个回答

用“->”还是“.”这个要看L是指针还是结构体了,栈是“先进后出,后进先出”。你是不是说,你要自己定一个“栈”其实呢就是自己做个链表,实现能从“栈底”到“栈顶”方向输出?

栈的元素从栈底到栈顶输出:最直接的方法是先将栈元素出栈,建立一个新的栈。这样就是将本来的栈中元素的顺序颠倒了,然后对新的栈出栈就获取到想要的结果。

这个要看 L 的定义是指针,还是非指针变量。

要看L的类型,比如说有如下的栈结构体:

struct Stack{
    int top() {
    //do somethng
    }
    //还有其他的一些东西
};

使用的时候:

// 直接创建Stack类型的数据
Stack stack;
//调用stack的top函数
stack.top();

//另外一种
//创建Stack类型的指针,并让其指向新建的具有Stack结构的内存空间(相当于对象)
Stack *stackPoint = new Stack();
//调用stackPoint的top函数
stackPoint->top();

也就是说,如果是指针变量的话那么就用 -> 访问内部的函数 ,如果是一般的变量的话,直接用 . 就可以访问内部函数了

leilba
林深 你要从栈底到栈顶输出的话,有多种方案,一种是自己来重写一个栈,这个用数组或是链表来实现,给这个自定义的栈增加一个从栈底访问的方法,比如说数组的话0的位置作为栈底,链表的话第一个根节点作为栈底,然后依次访问到栈顶。
接近 4 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
规划一个路线,使得路线上的价值总和最大,本题可能栈溢出,怎么用C语言实现
Problem Description 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通。每个零食机都有一个值v,表示为小度熊提供零食的价值。 由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化。小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次。另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机。 为小度熊规划一个路线,使得路线上的价值总和最大。 Input 输入数据第一行是一个整数T(T≤10),表示有T组测试数据。 对于每组数据,包含两个整数n,m(1≤n,m≤100000),表示有n个零食机,m次操作。 接下来n−1行,每行两个整数x和y(0≤x,y<n),表示编号为x的零食机与编号为y的零食机相连。 接下来一行由n个数组成,表示从编号为0到编号为n−1的零食机的初始价值v(|v|<100000)。 接下来m行,有两种操作:0 x y,表示编号为x的零食机的价值变为y;1 x,表示询问从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。 本题可能栈溢出,辛苦同学们提交语言选择c++,并在代码的第一行加上: `#pragma comment(linker, "/STACK:1024000000,1024000000") ` Output 对于每组数据,首先输出一行”Case #?:”,在问号处应填入当前数据的组数,组数从1开始计算。 对于每次询问,输出从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。 Sample Input 1 6 5 0 1 1 2 0 3 3 4 5 3 7 -5 100 20 -5 -7 1 1 1 3 0 2 -1 1 1 1 5 Sample Output Case #1: 102 27 2 20
栈 数据结构 四则运算
2. 利用栈的数据结构实现一个简单的4则运算计算器(不需要支持括号)。例如, 分析5 * 2 + 3 * 4的执行过程,输出进出栈的顺序(提示:中间结果得到后可继续push到栈中)。 最好能写出代码 并加注释 c语言 不是c++
求二叉树宽度 大佬帮忙看看我的代码哪里是错在哪里
题目描述 我们定义:二叉树每一层中,节点最多的那层的节点数为二叉树的宽度。 请编写一个程序计算二叉树的宽度。 输入 每行是一棵二叉树的带虚结点(#)表示的前序遍历序串,长度不超过2000。每个结点为一个小写字母或一个数字。 输出 对于每行输入的二叉树,输出该二叉树的宽度,每个结果占一行。 样例输入 # a#bc##f## 样例输出 0 2 提示 第一行输入的为空二叉树,其宽度为零。 #include < stdio.h> #include < stdlib.h> #define OK 1 #define error 0 #define overflow 0 typedef int Status; typedef struct BiTNode{ char data; struct BiTNode *leftchild; struct BiTNode *rightchild; }BiTNode,*BiTree; void InitTree(BiTree *T){ *T=NULL; } int z=0; Status CreateBiTree(BiTree *T,char s[]){ char ch; ch=s[z]; z++; if(ch=='#') *T=NULL; else{ (*T)=(BiTree)malloc(sizeof(BiTNode)); if(!(*T)) exit(overflow); (*T)->data=ch; CreateBiTree(&(*T)->leftchild,s); CreateBiTree(&(*T)->rightchild,s); } return OK; }///这里是建立树 typedef BiTree QElemType; typedef struct QNode{ QElemType content; struct QNode *next; }QNode,*QueuePtr; typedef struct{ QueuePtr front; QueuePtr rear; }LinkQueue; Status InitQueue(LinkQueue *q){ q->front=q->rear=(QueuePtr)malloc(sizeof(QNode)); if(!(q->front)) exit(overflow); q->front->next=NULL; return OK; }//初始化 Status EnQueue(LinkQueue *q,QElemType *T){ QueuePtr p,s; p=(QueuePtr)malloc(sizeof(QNode)); if(!p) exit(overflow); p->content=*T; p->next=NULL; q->rear->next=p; q->rear=p; s=q->front->next; return OK; } Status DeQueue(LinkQueue *q, QElemType *e){ QueuePtr p; if(q->front==q->rear) return error; p=q->front->next; *e=p->content; q->front->next=p->next; if(q->rear==p) q->rear=q->front; free(p); return OK; }//出队 Status GetTop(LinkQueue *q, QElemType *e){ QueuePtr p; if(q->front==q->rear) return error; p=q->front->next; *e=p->content; return OK; }//取栈顶元素 Status IsEmpty(LinkQueue *q){ if(q->front==q->rear) return OK; else return error; }////这里是链式队列的库 Status WidthBiTree(BiTree T){ LinkQueue q; QElemType tmp,p; p=T; int a[20]={0}; a[0]=1; int pre=0,pos=1,end=0; int level=1; EnQueue(&q,&p); end++; while(!IsEmpty(&q)){ DeQueue(&q,&tmp); pre++; if(tmp->leftchild){ EnQueue(&q,&tmp->leftchild); end++; } if(tmp->rightchild){ EnQueue(&q,&tmp->rightchild); end++; } if(pre==pos){ a[level]=end-pos; level++; pos=end; } } int i,max; max=0; for(i=0;i< level;i++){ if(a[i]>max) max=a[i]; } return max; }///求宽度 void PreOrder(BiTree T){ if(T){ printf("%c",T->data); PreOrder(T->leftchild); PreOrder(T->rightchild); } } char s[2000]; int main() { BiTree T; int width,n; scanf("%d",&n); while(n--){ z=0; scanf("%s",s); InitTree(&T); CreateBiTree(&T,s); if(T==NULL) width=0; else{ width=WidthBiTree(T); } printf("%d\n",width); } return 0; } 我的代码调试之后就停在出队函数那里,电脑报错如下 ![图片说明](https://img-ask.csdn.net/upload/201912/28/1577539940_272569.png) 求求大佬帮忙看看
数据结构顺序栈代码,老是报错,求大神帮忙看一下哪里有问题。
``` /* 实验内容: 1.利用数组建立并初始化一个顺序栈,并将此栈中各元素的值依次输出; 2.当栈不满时将一个新元素入栈,并依次输出此时栈中各元素的值。 3.当栈不空时将栈顶元素出栈,并输出此时栈中各元素的值。 实验要求: 栈的最大空间为10个元素单元,栈中已有部分元素,栈中元素值的类型为字符型。 要求新入栈的元素可以从键盘输入。 当操作不合理或不能完成时,程序应能处理并输出相应信息。 带星号的第3项实验内容为选作内容。 */ #include<stdio.h> #include<stdlib.h> //需要的头文件 typedef char StackData; typedef struct { StackData *base; StackData *top; int stacksize; } SeqStack; //说明顺序栈的结构体变量类型 void main() { Create_Stack(S); printf("顺序栈中已有的元素值为:\n"); Print_Stack(S); printf("\n请输入要入栈的新元素值:\n"); scanf("%c",&x); Push(S,x); //将新元素x入栈 printf("新元素入栈后栈中元素的值为:\n"); Print_Stack(S); } void Create_Stack(S)//初始化建立顺序栈 { S.base=(StackData*)malloc(10*sizeof(StackData)); S.top=S.base; S.stacksize=10; char a[10]={'a','b','c','d','e','f','g','h'}; int i; for(i=0;i<=9;i++) { *S.top=a[i]; S.top++; } } void Print_Stack(S)//依次输出栈中各元素的值 { StackNode *p; p=S.base; while(p<S.top) { printf("%c ",*p); p++; } } void Push(SeqStack S,StackData x) //将新元素x入栈 { if(StackFull(S)) { S.base=(StackData*)realloc(S.base,(S.stacksize+10)*sizeof(StackData)); if(!S.base) exit(overflow);//追加存储空间失败 S.top=S.base+S.stacksize; S.stacksize+=10; } *S.top=x; S.top++; } ```
qt 很简单的一段代码 利用Qsetting 完成,但是在读取配置文件的时候,出问题
``` #include "widget.h" #include "ui_widget.h" #include<QTime> #include<iostream> #include<QString> #include<QSettings> #include<QDebug> #include<QFile> #include <QMessageBox> #include <QDir> #include<QFileDialog> #define CONFIG_FILE "config.ini" using namespace std; Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); QSettings *configIniRead = new QSettings("config.ini", QSettings::IniFormat); //在堆里面开辟了一块区域,然后把地址赋给栈中的某个地址 dir_src = configIniRead->value("main/bak_src").toString();// value 是Qsetting里面的公开方法 cout << "当前目录为:" <<dir_src.toLocal8Bit().data(); dir_dest = configIniRead->value("main/bak_dest").toString(); // 配置文件里面有目标地址 gpg_key = configIniRead->value("main/gpg_key").toString(); exclude_from = configIniRead->value("exclude/exclude").toString(); delete configIniRead; // 与初始化的对象成对出现,会造成内存泄漏 ui->lineEdit->setText(dir_src); } Widget::~Widget() { delete ui; } ``` 上面是cpp里面的 ``` #ifndef WIDGET_H #define WIDGET_H #include <QWidget> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private: Ui::Widget *ui; QString dir_src; QString dir_dest; QString dir_restore; QString gpg_key; QString arc_user; QString arc_path; QString exclude_from; }; #endif // WIDGET_H ``` 上面是h文件里面的 ``` [exclude] exclude=--exclude *.iso --exclude .gvfs/** --exclude .thumbnails/** --exclude .trash/** --exclude .Trash/** --exclude *-gitsvn/** --exclude *-cvs/** --exclude *-svn/** --exclude *-git/** --exclude *-sf/** --exclude *.vc --exclude *.tc --exclude .cache/** --exclude .ccache/** --exclude ./Downloads/** --exclude ./.wine/** --exclude ./Documents/Dropbox/** [main] arc_path=bak_lg arc_user=testuser bak_dest=/home/hu/backup bak_src=/home/hu/retore gpg_key=xujing113221@hotmail.com last_time=1572976195 ``` 上面是配置文件 我在读取配置文件下面做了一个输出,但是就是没有任何输出,我之后在后面加了字符串,发现有了输出,说明是配置文件没有被读出来 于是我改了配置文件的权限是 777,但是还是没有输出 最后我实在受不了,就重新建立一个项目尝试了一下,还是一点反应都没有 配置文件所在目录 就是h文件和cpp文件所在的目录
C语言中main调用一个接口函数问题。
有一个字符串符合以下特征(” "abcd11111abcd2222abcdqqqqq"”),要求写一个函数(接口),输出以下结果 1) 求字符串字串(“abcd”)出现的次数,并把结果传出; 我昨天晚上写了半天,图片是昨天晚上写的代码。 ![图片说明](https://img-ask.csdn.net/upload/201602/11/1455159066_651029.png) 应该打印3,可是每次都打印0. 于是接见了一下其他人的代码,使用了指针。 ![图片说明](https://img-ask.csdn.net/upload/201602/11/1455159118_374779.png) 还是原来的接口,现在就能打印3了。 调用c接口的话,是不是放在了栈区,然后调用完了,系统就直接丢弃变为0了? 假设设置一个指针,然后指针指向i的地址,再把 main函数里面的i修改了,这样就打印3了。 我说的对吗? 我希望有人能够从内存四区模型详细给我讲讲。 感激不尽。
数据结构C语言版10道实习题目求解答!!
除有特别说明外,每个题目请以自然语言、形式化表述(伪码、流程图等)、程序代码三种方式描述。 1. 顺序结构线性表LA与LB的节点关键字为整数。LA与LB的元素按非递减有序,线性表空间足够大。试给出一种高效算法,将LB中的元素合并到LA中,使新的LA元素仍保持非递减有序。高效是指最大限度的避免移动元素。 2. 请写一个算法将线性表(a1,a2,…,an)逆置为(an,an-1,…,a1)。 3. 在一个递增有序的线性表中,有数值相同的元素存在。若存储方式为单链表,请设计算法去掉数值相同的元素,使表中不再有重复的元素。 4. 设带有头节点的单链表中存储的数据元素为整数,试写算法,按递增次序输出单链表中各节点的数据元素,并释放节点所占的存储空间。 5. 设计算法将中缀表达式转换为后缀表达式,并对后缀表达式求值。 6. 请利用两个栈S1和S2来模拟一个队列。 7. 离散事件模拟。 a) 利用伪随机数生成顾客到达事件; b) 使用队列模拟业务窗口的处理,设计算法将顾客分配到不同队列; c) 计算顾客平均停留时间 8. 以顺序结构表示串,设计算法,求串S中出现的最长重复子串及其位置。重复子串的含义是由一个或多个连续相等的字符组成的子串。 9. 写一个递归算法来实现字符串逆序存储,要求不另设串存储空间。 10. 给定mxn矩阵A[m,n],并设A[i,j]<=A[i,j+1](0<=i<=m-1,0<=j<=n-2)和A[i,j]<=A[i+1,j] (0<=i<=m-2,0<=j<=n-1)。设计一个算法,判定x是否在A中,要求时间复杂度为O(m+n)。
Catch the cow(POJ3278) 编译器上没问题, OJ上一直runtime error?
[原题网址](http://poj.org/problem?id=3278 "Catch the cow") 下面是我已经在编译器上通过的代码,但是OJ上始终会RE (使用的是广度优先搜索的方法) ``` #include <stdio.h> #include <stdlib.h> #define MAX_N 100000 int n, k, ans; int que[MAX_N+10][2]; int vis[MAX_N+10]; int head, tail; void bfs( int x); void enqueue ( int x, int time); int main(void) { scanf("%d %d", &n, &k); if( n>k) { ans = n-k; } else { bfs(n); } printf("%d\n", ans); return 0; } void bfs( int x) { enqueue(x, 0); vis[x] = 1; while(head<tail) { int i, nowx, nowtime; nowx = que[head][0]; nowtime = que[head][1]; head ++; if( nowx == k) { ans = nowtime; break; } for( i=1; i<=3; i++) { if( i==1 && vis[nowx-1]!=1 && nowx-1>=0 && nowx-1 <= MAX_N) { enqueue( nowx-1, nowtime+1); vis[nowx-1] = 1; } if( i==2 && vis[nowx+1]!=1 && nowx+1>=0 && nowx+1 <= MAX_N) { enqueue( nowx+1, nowtime+1); vis[nowx+1] = 1; } if( i==3 && vis[nowx*2]!=1 && nowx*2>=0 && nowx*2 <= MAX_N) { enqueue( nowx*2, nowtime+1); vis[nowx*2] = 1; } } } } void enqueue( int x, int time) { que[tail][0] = x; que[tail][1] = time; tail ++; } ``` 一开始查了之后说可能是什么栈空间不够,就尝试了一下动态分配空间 (萌新还没学指针,就在网上照猫画虎贴了进去), 但是数字只要大一点程序就无法输出结果 更改后的代码如下: ``` #include <stdio.h> #include <stdlib.h> #define MAX_N 100001 int n, k, ans; //int que[MAX_N+10][2]; /*之前的方案,但同样RE了,可能是空间不足(?),所以尝试如下动态分配的方法*/ //int vis[MAX_N+10]; int head, tail; void bfs( int x, int **que, int *vis); void enqueue ( int x, int time, int **que); int main(void) { int **que; int i, j; int *vis; que = (int**)malloc(sizeof(int*)*MAX_N); //为两个数组分配空间 for( i=0; i<MAX_N; i++) { que[i] = (int*)malloc(sizeof(int)*2); } vis = (int*)malloc(sizeof(int)*MAX_N); scanf("%d %d", &n, &k); if( n>k) { ans = n-k; } else { bfs(n, que, vis); //进入深搜 } printf("%d\n", ans); return 0; } void bfs( int x, int **que, int *vis) { enqueue(x, 0, que); vis[x] = 1; while(head<tail) { int i, nowx, nowtime; nowx = que[head][0]; //队列数据的取出 nowtime = que[head][1]; head ++; if( nowx == k) //结束条件 { ans = nowtime; break; } for( i=1; i<=3; i++) //对三种可能进行遍历 { if( i==1 && vis[nowx-1]!=1 && nowx-1>=0 && nowx-1 <= MAX_N) { enqueue( nowx-1, nowtime+1, que); vis[nowx-1] = 1; } if( i==2 && vis[nowx+1]!=1 && nowx+1>=0 && nowx+1 <= MAX_N) { enqueue( nowx+1, nowtime+1, que); vis[nowx+1] = 1; } if( i==3 && vis[nowx*2]!=1 && nowx*2>=0 && nowx*2 <= MAX_N) { enqueue( nowx*2, nowtime+1, que); vis[nowx*2] = 1; } } } } void enqueue( int x, int time, int **que) //队列数据的写入 { que[tail][0] = x; que[tail][1] = time; tail ++; } ``` 请教一下大佬们上面RE的原因到底是什么, 还有下面的动态分配有什么问题,感激不尽
c语言数据结构 表达式求值
**目的:1)掌握栈的概念与基本操作; 2)掌握文本文件的读写操作。 要求:实现任意加、减、乘、除与括号的表达式求值; 输入输出格式要求如下: 输入文件input.txt内容: 2*(4-100)= 3*5+9/3= 100-20*(4*6/3)= 输出文件output.txt内容(output.txt文件为自动生成,若已存在则覆盖): 2*(4-100)=-192 3*5+9/3=18 100-20*(4*6/3)=-60** 求大神帮帮咯 代码如下,就是不会写文件那部分: #include <stdio.h> #include <stdlib.h> #define MAX 20 //定义第一个栈---作为存放运算数的操作符 struct SNode_Num { int datas[MAX]; int top; }; typedef struct SNode_Num OperateNum; //定义第二个栈---作为存放运算符号的栈 struct SNode_Symbol { char symbol[MAX]; int top; }; typedef struct SNode_Symbol OperateSymbol; /******************************************************************** 描述:定义函数:InitOperandNum,并且初始化运算数栈顶 参数:OperateNum *StackNum 返回值:void ********************************************************************/ void InitOperateNum(OperateNum *StackNum) { StackNum->top = -1; } /******************************************************************** 描述:定义函数: InitOperateSymbol,并且初始化运算符栈顶 参数:OperateSymbol *StackSymbol 返回值:void ********************************************************************/ void InitOperateSymbol(OperateSymbol *StackSymbol) { StackSymbol->top = -1; } /******************************************************************** 描述:定义函数:PushOperateNum, 压一个数到栈顶 参数:OperateNum *StackNum, int x 返回值:void ********************************************************************/ void PushOperateNum(OperateNum *StackNum, int x) { StackNum->top++; StackNum->datas[StackNum->top] = x; } /******************************************************************** 描述:定义函数:PushOperateSymbol,压一个运算符到栈顶 参数:OperateSymbol *StackSymbol, char ch 返回值:void ********************************************************************/ void PushOperateSymbol(OperateSymbol *StackSymbol, char ch) { StackSymbol->top++; StackSymbol->symbol[StackSymbol->top] = ch; } /******************************************************************** 描述:定义函数:PopOperateNum,将运算数从栈中读取出来 参数:OperateNum *StackNum 返回值:返回取出来的数 ********************************************************************/ int PopOperateNum(OperateNum *StackNum) { int num; num = StackNum->datas[StackNum->top]; StackNum->top--; return num; } /******************************************************************** 描述:定义函数:PopOperateSymbol,将运算符从栈中取出来 参数:OperateSymbol *StackSymbol 返回值:返回取出来的符号 ********************************************************************/ char PopOperateSymbol(OperateSymbol *StackSymbol) { char ch; ch = StackSymbol->symbol[StackSymbol->top]; StackSymbol->top--; return ch; } //取出相应的数 int GetOperateNum(OperateNum *StackNum) { return StackNum->datas[StackNum->top]; } //取出相应运算符 char GetOperateSymbol(OperateSymbol *StackSymbol) { return StackSymbol->symbol[StackSymbol->top]; } /******************************************************************** 描述:定义函数, IsOperateSymbolOrNum,判断输入的符号是那些符号 参数:char ch 返回值:有符号返回1,无符号返回0 ********************************************************************/ short IsOperateSymbolOrNum(char ch) { //判断所有需要用的操作符 包括 + - * / ( ) \n if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '\n') return 1; else return 0; } /******************************************************************** 描述:定义函数: Priority,用于判断符号优先级运算 参数:char inputnum, char ch 返回值:符号的大小的字符 ********************************************************************/ char Priority(char inputnum, char ch) { switch(inputnum) { //加减在同一个优先级上 case '+': case '-': { if(ch == '+' || ch == '-') return '>'; else if(ch == '*' || ch == '/') return '<'; else if(ch == '(') return '<'; else if(ch == ')') return '>'; else return '>'; } break; //乘除在同一优先级 case '*': case '/': { if(ch == '+' || ch == '-') return '>'; else if(ch == '*' || ch == '/') return '>'; else if(ch == '(') return '<'; else if(ch == ')') return '>'; else return '>'; } break; //括号在所有优先级以上 case '(': { if(ch == ')') return '='; else return '<'; } break; case ')': { return '>'; } break; case '\n': { if(ch == '\n') return '='; else return '<'; } break; } } /******************************************************************** 描述:定义函数: Calculate,计算结果 参数:int num1, char ch, int num2 返回值:返回两个数计算的结果result ********************************************************************/ int Calculate(int num1, char ch, int num2) { int result; switch(ch) { case '+': result = num1 + num2; break; case '-': result = num1 - num2; break; case '*': result = num1 * num2; break; case '/': result = num1 / num2; } return result; } /******************************************************************** 描述:定义函数:MainCalc,主要用于获取用户输入,并且进行计算 参数:void 返回值:result ********************************************************************/ int MainCalc() { //主函数进行计算 OperateNum datas; OperateSymbol symbol; int num1, num2, result, num; char ch, sign; InitOperateNum(&datas); InitOperateSymbol(&symbol); //把回车计算的操作符放在栈中 PushOperateSymbol(&symbol, '\n'); ch = getchar(); while((ch != '\n') || (GetOperateSymbol(&symbol) != '\n')) { if(!IsOperateSymbolOrNum(ch)) { num = atoi(&ch); //将字符转换为整数 ch = getchar(); //获取输入 while(!IsOperateSymbolOrNum(ch)) { num = num * 10 + atoi(&ch); ch = getchar(); //当没有输入回车时,继续获取输入 } PushOperateNum(&datas, num); } else { switch(Priority(GetOperateSymbol(&symbol), ch)) { //判断优先级后进行计算 case '<': PushOperateSymbol(&symbol, ch); ch = getchar(); break; case '=': sign = PopOperateSymbol(&symbol); ch = getchar(); //获取输入 break; case '>': sign = PopOperateSymbol(&symbol); num2 = PopOperateNum(&datas); num1 = PopOperateNum(&datas); result = Calculate(num1, sign, num2); PushOperateNum(&datas, result); break; } } } result = GetOperateNum(&datas); return result; } int main(int argc, char *argv[]) { int result; printf("请输入运算式:\n"); result = MainCalc(); printf("结果为:\n"); printf("%d\n", result); //输出结果 return 0; }
函数传递时,若为f(x=1,x=2,x=3)形式,得到的形参均为一,为什么会这样?
写了如下的c语言代码: ``` #include<stdio.h> void f(int a,int b,int c) { printf("%d %d %d",a,b,c); } int main() { int x=0; f(x=1,x=2,x=3); return 0; } ``` 运行后输出 1 1 1。我知道传参时进栈顺序是从右至左。但是,为什么后两个参数明明已经算出结果了,却还是被x=1覆盖,是不是算出结果3和2后没有直接进栈?对这其中的细节有疑问,希望各位不吝赐教,谢谢!
数据结构相关问题,一直没有找到错误。代码哪里出错了呢?
■问题描述: 建立一棵二叉树,编程实现从根结点到给定结点之间的路径。 ■基本要求: 建立一棵以二叉链表存储的二叉树,以bt指向根节点、 p指向任一给定结点, 编程实现“以字符形式输出从根结点到给定结点之间的路径”。 ■测试数据: 自行建立一棵以序列{A, B, C, D, E, F, G, H, I, J}中的英文字母为结点 的任意一棵二叉树。 ■实现提示: (1)以某种遍历方式建立二叉树的二叉链表存储结构; (2)以非递归的后序方式遍历二叉树bt,并将访问过的结点依次存储到一个 顺序栈S中; (3)当后序遍历访问到结点*p时,此时栈S中存放的所有结点均为给定结点*p 的祖先,而由这些祖先,便构成了一条从根结点到结点*p之间的路径。 错误提示 :[Error] expected ';', ',' or ')' before '&' token 代码如下: #include <stdio.h> #include <stdlib.h> #define MAXLEN 100 typedef struct BiTNode // 定义二叉树结点结构 { char data; // 数据域 struct BiTNode *LChild,*RChild; // 左右孩子指针域 }BiTNode,*BiTree; int found=0; BiTree p=NULL; //临时结点 //1.建立二叉树 void CreateBiTree(BiTree &bt) {//按照先序序列建立二叉树的二叉链表 char ch; printf("请输入结点:\n"); scanf("%c",&ch); if(ch=='#') bt=NULL; else { bt=(BiTNode*)malloc(sizeof(BiTNode));//生成一个新结点 bt->data=ch; //生成根结点 CreateBiTree(bt->LChild); //生成左子树 CreateBiTree(bt->RChild); //生成子树 } } //2.后序遍历使结点入栈并求结点路径 void NodePath(BiTree bt,BiTNode*ch) { BiTNode*stack[MAXLEN]; //定义栈 int tag[MAXLEN]; // int i,top=0,find=0; BiTNode *s=bt; //临时指针 do{ while(s!=NULL) { //扫描左子树 top++; stack[top]=s; tag[top]=0; s=s->LChild; } if(top>0) { //栈非空 s=stack[top]; if(tag[top]==1) { if(s==ch) {//遇到给定结点输出路径 for(i=1;i<=top;i++) printf("-%c",stack[i]->data); find=1; } else top--; s=stack[top]; } if(top>0&&!find) { if(tag[top]!=1) {//扫描右子树 s=s->RChild; tag[top]=1; } else s=NULL; } } } while(!find&&top!=0); } BiTNode *FindBT(BiTree bt,char x) { if((bt!=NULL)&&!found) { if(bt->data==x) { p=bt; found=1; } else { FindBT(bt->LChild,x);//遍历查找左子树 遍历查找左子树 FindBT(bt->RChild,x);//遍历查找右子树 遍历查找右子树 } } return(p); } int main() {//主程序界面函数 BiTree bt; char s; system("color 1f"); system("mode con:cols=78 lines=35"); printf("\t 求二叉树上给定结点的路径\n"); printf("\n***********************************************\n"); printf("\t 1.建立二叉树\n"); printf("\t 2.求结点路径\n"); printf("\t 3.退出系统\n"); printf("\t 欢迎使用系统!\n"); printf("\n***********************************************\n"); printf("请选择您想要的服务:"); scanf("%s",&s); switch(s) { case '1': printf("请输入二叉树的结点序列 \n"); CreateBiTree(bt); printf("二叉树建立成功\n"); break; case '2': printf("输入求路径的结点:"); s=getchar(); p=NULL; found=0; FindBT(bt,s); if(p!=NULL) { NodePath(bt,p); printf("\n"); } else printf("没有该结点! \n"); break; case '3':exit(0); default:printf("输入有误");break; } return 0; }
问一个很愚蠢的基础问题,p=p->next链表循环里,为什么这样不会覆盖掉链表的值啊
链表循环里 比如L是带头节点的单链表 循环单链表一般都是 ``` list p=(list)malloc(sizeof(link)); p=L->next; while(p) { printf("%d ",p->data); p=p->next; } ``` 为什么节点值没有一个一个被覆盖掉,下一次遍历还存在啊。 比如L 这个链表里面值分别是 1,2,3,4,5,按照p=p->next不应该是1这里的节点被2代替,2被3代替了么,求解求解,以前写代码就只是写写没有思考过。。。 还有 ``` 单链表构建栈反向输出链表节点值 void print(list p) if(p->next!=0) print(p->next); printf("%d",p->data);} 它为什么可以输出最后一个节点以外值不应该输出了最后一个节点值就跳出程序么 ```
为什么到最后一直无法输出迷宫路径?
#include<stdio.h> #include<malloc.h> #include<stdlib.h> typedef struct { int x; int y; }PosType; typedef struct { int ord; PosType seat; int di; }DataType; #include "SeqStack.h" #define MAXLENGTH 40 typedef int MazeType[MAXLENGTH][MAXLENGTH]; MazeType m; int x,y; PosType begin,end; int curstep = 1; void Print() { int i,j; for(i=0;i<x;i++) { for(j=0;j<y;j++) printf("%3d",m[i][j]); printf("\n"); } } void Init(int k) { int i,j,x1,y1; printf("请输入迷宫的行数,列数(包括外墙):"); scanf("%d,%d",&x,&y); for(i=0;i<x;i++) { m[0][i]=0; m[x-1][0]=0; } for(i=0;i<y-1;i++) { m[i][0]=0; m[i][y-1]=0; } for(i=1;i<x-1;i++) for(j=1;j<y-1;j++) m[i][j]=k; printf("请输入迷宫内墙单元数:"); scanf("%d",&j); printf("请依次输入迷宫内墙每个单元的行数,列数:\n"); for(i=1;i<=j;i++) { scanf("%d,%d",&x1,&y1); m[x1][y1]=0; } printf("迷宫结构如下:\n"); Print(); printf("请输入入口的行数,列数:"); scanf("%d,%d",&begin.x,&begin.y); printf("请输入出口的行数,列数:"); scanf("%d,%d",&end.x,&end.y); } int Pass(PosType b) { if(m[b.x][b.y]==1) return 1; else return 0; } void FootPrint(PosType a) { m[a.x][a.y]=curstep; } void NextPos(PosType *c,int di) { PosType direc[4]={{0,1}, {1,0},{0,-1},{-1,0}}; (*c).x+=direc[4].x; (*c).y+=direc[di].y; } void MarkPrint(PosType b){ m[b.x][b.y]=-1; } int MazePath(PosType start,PosType end) { SeqStack S; PosType curpos; DataType e; InitStack(&S); curpos=start; do { if(Pass(curpos)) { FootPrint(curpos); e.ord = curstep; e.seat = curpos; e.di = 0; PushStack(&S,e); curstep++; if(curpos.x==end.x&&curpos.y==end.y) return 1; NextPos(&curpos,e.di); } else { if(!StackEmpty(S)) { if(!StackEmpty(S)) { PopStack(&S,&e); curstep--; while(e.di==3&&!StackEmpty(S)) { MarkPrint(e.seat); PopStack(&S,&e); curstep; } if(e.di<3) { e.di++; PushStack(&S,e); curstep++; curpos=e.seat; NextPos(&curpos,e.di); } } } } }while(!StackEmpty(S)); return 0; } int main() { Init(1); if(MazePath(begin,end)) { printf("此迷宫从入口到出口的一条路径如下:\n"); Print(); } else printf("此迷宫没有从入口到出口的路径\n"); } //下面是seeqstack文件中的代码 #define StackSize 100 typedef struct { DataType stack[StackSize]; int top; }SeqStack; void InitStack(SeqStack *S) { S->top = 0; } int StackEmpty(SeqStack S) { if(S.top == 0) return 1; else return 0; } int GetTop(SeqStack S, DataType *e) { if(S.top<= 0) { printf("栈已经空!\n"); return 0; } else { *e = S.stack[S.top-1]; return 1; } } int PushStack(SeqStack *S, DataType e) { if(S->top>=StackSize) { printf("栈已满,不能将元素进栈!\n"); return 0; } else { S->stack[S->top]=e; S->top++; return 1; } } int PopStack(SeqStack *S, DataType *e) { if(S->top == 0) { printf("栈中已经没有元素,不能进行出栈操作!\n"); return 0; } else { S->top--; *e=S->stack[S->top]; return 1; } } int StackLength(SeqStack S) { return S.top; } void ClearStack(SeqStack *S) { S->top = 0; }
关于创建进程,到底是如何看待这个
本人感觉小白一个,刚学完操作系统原理,可是进程和线程总是很难理解啊,从编程的角度来讲:这都是面向对象的东西,实际编程时感觉很难下手,从理论到实践真的是差别很大,感觉用先前的c语言的知识很难理解执行顺序。如下代码 #include<unistd.h> #include<stdio.h> int main(int argc, char ** argv ) { int pid = fork(); if (pid < 0) { printf("error!"); } else if( pid == 0 ) { printf("This is the child process!"); } else{ printf("This is the parent process! child process id = %d", pid); } return 0; } 1 运行时为什么先输出This is the parent process! child process id = %d"后输出This is the child process!,从程序的执行角度真的很难理解啊。 2 应该说创建一个进程就是运行一个程序,比如vc下的createProcess()启动了一个程序,比如说可以启动记事本程序,而linux下的调用fork()是做了什么,比如上面的程序好像感觉是启动了一个线程(书上说线程是一个执行代码,有自己的入口函数地址) 3 创建进程是父进程的一个副本,它将获得父进程数据空间、堆、栈等资源的副本,但是不共享,操作系统为他开辟与父进程不同的地址空间,我能否理解为子进程重新运行上面的程序,或者说执行一次运行了两个程序。 我也有点头大了,暂时想到这些,真心请教!!!!
汇编语言的代码在dosboxs上出了点问题,有大神帮忙解决一下吗?
初学汇编,小白一枚,不知道错在哪里了,求大神带飞,代码是在源码中国下载的,在dosbox显示这样, ``` ;*********************************************************************************************************************** ;程序功能: ;完成小车的自动和手动沿轨道行驶的过程,并具有计时功能 ;*********************************************************************************************************************** ;运行说明: ;程序运行之后,即显示出轨道和小车; ;按键‘a’或‘m’选择自动还是手动(a为自动,m为手动),按‘s’键启动小车; ;手动时,按方向键控制小车方向,撞到轨道时,小车会停止并闪动; ;小车到达终点后会自动停车,之后按‘r’键可使小车回到起点,然后重新选择小车的运行得方式; ;小车行驶过程中,计时器计时,到达终点则停止计时; ;手动时,按‘t’暂停,‘c’键继续,此间计时不停止; ;小车回到起点位置后,按下‘s’键计时清零,并重新进行下一次的计时; ;小车处于未选定模式和手动运行时可按Esc键退出运行。 ;*********************************************************************************************************************** stack segment 'stack' db 256 dup(0) stack ends data segment count dw 0 sec dw 0 min dw 0 save_lc dw 2 dup(?) car db 0,7,0,0,0,0,0,0,7,0 ;车的图案,10行10列 db 7,0,7,0,0,0,0,7,0,7 db 0,7,9,9,9,9,9,9,7,0 db 0,0,9,0,0,0,0,9,0,0 db 0,0,9,0,0,0,0,9,0,0 db 0,0,9,0,0,0,0,9,0,0 db 0,0,9,0,0,0,0,9,0,0 db 0,7,9,9,9,9,9,9,7,0 db 7,0,7,0,0,0,0,7,0,7 db 0,7,0,0,0,0,0,0,7,0 x dw 180 ;起始位置 y dw 83 start_flag_1 db 0 ;启动标志1 start_flag_2 db 0 ;启动标志2 direc_flag db 0 ;方向标志 touch_flag db 0 ;触轨标志 arrive_flag db 0 ;到达标志 turn_x1 dw 138 ;拐弯点 turn_y1 dw 28 turn_x2 dw 203 turn_y2 dw 133 turn_x3 dw 135 es_save dw 0 ;用于保存图形缓冲区的首地址 mode db ? ;用于保存显示之前显示器的模式 x1 dw ? ;9型轨道的坐标 y1 dw ? x2 dw ? y2 dw ? x3 dw ? y3 dw ? x4 dw ? x_d dw 15 ;轨道的宽度 data ends code segment ;段设置 assume cs:code,ds:data start: mov ax,data mov ds,ax mov es,ax mov ax,0a000h ;图形缓冲区的首地址 mov es,ax mov es_save,ax ;把图形缓冲区的首地址保存在es_save mov ah,0fh int 10h ;获取显示器显示图形之前的显示模式 mov mode,al ;把显示模式保存在mode中 mov ah,35h mov al,1ch int 21h ;取中段号为1ch(定时中断)的中段向量(即中断程序的入口地址),并把它放在ES:BX中 mov save_lc,bx mov save_lc+2,es ;保存中断向量 push ds ;保存ds mov dx,seg clint ;定时中断服务程序的段地址 mov ds,dx mov dx,offset clint ;定时中断的中断服务程序的偏移地址 mov al,1ch mov ah,25h int 21h ;设置中断向量,入口:DS:DX=中断向量,al=中断类型号。 ;即把定时中断的中断服务程序的入口地址放在4*n(其中n为中断类型号)中 pop ds ;ds出栈 in al,21h ;允许键盘和定时器中断 and al,11111100b out 21h,al sti ;开中断 mov ax,13h int 10h ;设置显示器的模式为13h,320×200,256色 call guidao_9 ;画轨道 call picture ;显示小车 input: mov ah,0 int 16h ;等待按键输入 cmp ax,011bh ;Esc键退出 jz b4 cmp ax,326dh ;选m,则为手动 jne b1 call xiaoche_shou jmp b2 b1: cmp ax,1e61h ;选a,则为自动 jne input ;都没有选,则重新选择输入 call xiaoche_move b2: mov ah,0 ;等待按下r键 int 16h cmp ax,1372h ;r键的扫描码 jnz b2 ;不是r键,则等待至按下r mov start_flag_1,0 ;是r键,则将起始标志位清零 mov start_flag_2,0 mov arrive_flag,0 b3: call clearpicture ;擦除终点的小车 mov x,180 ;小车回到起始位置 mov y,83 call picture ;显示小车 jmp input b4: push ds mov dx,save_lc mov ax,save_lc+2 mov ds,ax mov al,1ch mov ah,25h int 21h ;重置之前的中断向量,调用lch pop ds mov ah,0 mov al,mode int 10h ;把显示器的模式设置为显示图形之前的模式 mov ax,4c00h ;返回dos int 21h ;*********************************************************************************************************************** ;显示9字型轨道 ;*********************************************************************************************************************** guidao_9 proc mov x1,190 mov y1,95 mov x2,135 mov y2,25 mov x3,215 mov y3,145 mov x4,135 call draw_9_line ;外轨道 mov x1,190 mov y1,80 ;轨道的入口 mov x2,150 mov y2,40 mov x3,200 mov y3,130 mov x4,135 ;轨道的出口 call draw_9_line ;内轨道 ret guidao_9 endp ;******************************画9字********************************** draw_9_line proc mov cx,x1 mov dx,y1 mov di,y2 mov si,x2 call hline call sline mov di,y3 mov si,x3 call hline call sline mov si,x4 call hline draw_9_line endp ;*********************画竖线********************** sline proc mov al,03h ;设置直线的颜色为青 mov bh,0 ;0页 mov ah,0ch cmp dx,di jg a1line aline: int 10h ;写图形象素,AL=01h象素值,BH=0页码,(CX、DX)=(0,0)图形坐标列(X)、行(Y) inc dx cmp dx,di ;判断是否到di行 jng aline ;没到,则画线 dec dx ;使下一个点与这一个点重合 jmp e3 a1line: int 10h dec dx cmp dx,di jnl a1line inc dx e3: ret ;到了,则退出 sline endp ;*********************画横线********************** hline proc mov al,03h ;设置直线的颜色为青 mov bh,0 ;0页 mov ah,0ch cmp cx,si jg b1line bline: int 10h ;写图形象素,AL=01h象素值,BH=0页码,(CX、DX)=(0,0)图形坐标列(X)、行(Y) inc cx ;画第一点,并让横坐标加一 cmp cx,si ;判断是否到si列 jng bline ;没到,则画线 dec cx ;使下一条线的起点与这一个点重合 jmp e2 b1line: int 10h ;写图形象素,AL=01h象素值,BH=0页码,(CX、DX)=(0,0)图形坐标列(X)、行(Y) dec cx cmp cx,si jnl b1line ;没到,则画线 inc cx ;使下一条线的起点与这一个点重合 e2: ret ;到了,则退出 hline endp ;*********************************************************************************************************************** ;显示小车(通过向图形显示缓冲区写点) ;*********************************************************************************************************************** picture proc near mov ax,es_save mov es,ax mov dx,y mov bx,0 again: cmp dx,0 je over add bx,320 dec dx jmp again ;找到小车第一个点所在行 over: mov dx,10 lea si,car next1: mov cx,10 mov di,x ;找到小车第一个点 next: mov al,[si] mov es:[bx+di],al ;往空位填写数据 inc si ;指向下一个待填入的数据 inc di ;指向下一个等待填写的空位 loop next add bx,320 ;转到下一行 dec dx jne next1 ret picture endp ;*********************************************************************************************************************** ;计时器(中断号为1ch的中断为计时器中断,每55ms中断一次,每秒发生18.2次中断) ;*********************************************************************************************************************** clint proc far push ax ;保护寄存器 push bx push cx push dx push si push di push bp push sp push ds push es mov bx,data mov ds,bx ;设置数据段 assume ds:data cmp arrive_flag,1 ;判断小车是否到达终点 jne e6 ;没到,则跳至e7 call disptime ;到达,则显示时间 jmp return ;返回 e6: lea bx,count inc word ptr[bx] ;每产生一次定时中断,count加1 cmp word ptr[bx],18 ;判断是否到1秒 jne e7 ;没到,则跳至e6 call inct ;调整时间 e7: mov al,start_flag_1 and al,start_flag_2 jnz e8 mov al,start_flag_1 or al,start_flag_2 jz return jmp e9 e8: mov count,0 mov sec,0 mov min,0 mov start_flag_2,0 e9: call disptime ;显示小车 return: pop es pop ds pop sp pop bp pop di pop si pop dx pop cx pop bx pop ax iret clint endp ;******************判断是否进位******************* inct proc near mov word ptr[bx],0 add bx,2 inc word ptr[bx] cmp word ptr[bx],60 jne exit call inct exit: ret inct endp ;*****************************显示时间******************************** disptime proc near mov ax,min call bindec mov dl,':' mov ah,02h int 21h mov ax,sec call bindec mov dl,':' mov ah,02h int 21h mov bx,count mov al,55d mul bl call bindec mov dl,0dh ;输出回车,让光标回到起点 mov ah,02h int 21h ret disptime endp ;************把一个三位十进制数显示出来*********** bindec proc near mov cx,100d call decdiv mov cx,10d call decdiv mov cx,1 call decdiv ret bindec endp ;********************显示高位********************* decdiv proc near mov dx,0 div cx push dx mov dl,al add dl,30h mov ah,02h int 21h ;显示一位 pop ax ret decdiv endp ;************************************************************************************************************************ ;擦除 ;************************************************************************************************************************ clearpicture proc near mov dx,y mov bx,0 again2: cmp dx,0 je over2 add bx,320 dec dx jmp again2 over2: mov dx,10 next12: mov cx,10 mov di,x next2: mov al,0 ;把该点置为0,即用黑色擦除该点 mov es:[bx+di],al inc di loop next2 add bx,320 dec dx jne next12 ret clearpicture endp ;*********************************************************************************************************************** ;延时程序 ;*********************************************************************************************************************** delay proc near push bx push cx mov bx,1234 back: mov cx,66 push ax wait1: in al,61h and al,10h cmp al,ah je wait1 mov ah,al loop wait1 pop ax dec bx jne back pop cx pop bx ret delay endp ;*********************************************************************************************************************** ;小车自动运行 ;*********************************************************************************************************************** xiaoche_move proc call picture ;转移至picture程序段 ag: mov ah,7 ;中断 int 21h cmp al,'s' ;设置开始键s jne ag ;判断是否为s,不是则转至ag中断 mov start_flag_1,1 mov start_flag_2,1 start1: call clearpicture dec x call picture call delay mov si,x cmp si,turn_x1 ;遇到第一个拐弯 jg start1 start2: call clearpicture dec y call picture call delay mov si,y cmp si,turn_y1 ;遇到第二个拐弯 jg start2 start3: call clearpicture inc x call picture call delay mov si,x cmp si,turn_x2 ;遇到第三个拐弯 jl start3 start4: call clearpicture inc y call picture call delay mov si,y cmp si,turn_y2 ;遇到第四个拐弯 jl start4 start5: call clearpicture dec x call picture call delay mov si,x cmp si,turn_x3 ;遇到第五个拐弯,即终点 jg start5 mov arrive_flag,1 ret xiaoche_move endp ;*********************************************************************************************************************** ;小车手动运行 ;*********************************************************************************************************************** xiaoche_shou proc j0: call clearpicture ;擦除小车 call saomiao ;键盘扫描 cmp start_flag_1,1 ;判断小车是否启动 jne a8 ;没有,则呆在原地不动 ;判断小车运动的方向 cmp direc_flag,1 ;上 jne a1 dec y a1: cmp direc_flag,2 ;下 jne a2 inc y a2: cmp direc_flag,3 ;左 jne a3 dec x a3: cmp direc_flag,4 ;右 jne a4 inc x a4: call ya_line_do ;检测是否碰到轨道 cmp touch_flag,1 jne a8 ;没有碰到轨道,则继续前进 call guidao_9 ;碰到则重新显示轨道 mov touch_flag,0 ;将触轨标志清零 call back_step ;小车后退一步,回到轨道 a8: call picture call delay cmp arrive_flag,1 ;判断小车是否到达终点,到了则退出 jne j0 a9: ret xiaoche_shou endp ;*********************************************************************************************************************** ;键盘扫描程序 ;*********************************************************************************************************************** saomiao proc near mov ah,01h ;从键盘读一个字符,读到的结果为键的扫描码,存放在AH中 int 16h jz f ;如果无键按下,则退出 mov ah,00h ;若有键按下则中断当前 int 16h cmp ax,1f73h ;s的扫描码 jne h mov start_flag_1,1 mov start_flag_2,1 mov direc_flag,0 mov arrive_flag,0 h: cmp ax,1474h ;t的扫描码 jne j mov start_flag_1,0 mov start_flag_2,1 k: call picture mov ah,0 int 16h cmp ax, 2e63h ;c的扫描码 jne k mov start_flag_1,1 mov start_flag_2,0 call clearpicture j: cmp ax,4800h ;上键的扫描码 jne a mov direc_flag,1 a: cmp ax,5000h ;下键的扫描码 jne b mov direc_flag,2 b: cmp ax,4b00h ;左键的扫描码 jne g mov direc_flag,3 g: cmp ax,4d00h ;右键的扫描码 jne f mov direc_flag,4 jmp f e1: mov al,mode ;一旦有按键输入,则把显示器的模式设置为画直线之前的模式 mov ah,0 int 10h mov ax,4c00h int 21h f: ret saomiao endp ;*********************************************************************************************************************** ;小车触轨判断及处理 ;*********************************************************************************************************************** ya_line_do proc mov ax,y2 mov bx,y1 mov cx,x2 call ya_y_line sub ax,x_d add bx,x_d sub cx,x_d call ya_y_line mov ax,y2 mov bx,y3 mov cx,x3 call ya_y_line sub ax,x_d add bx,x_d add cx,x_d call ya_y_line mov ax,x2 mov bx,x1 mov cx,y1 call ya_x_line sub ax,x_d add cx,x_d call ya_x_line mov ax,x2 mov bx,x3 mov cx,y2 call ya_x_line sub ax,x_d add bx,x_d sub cx,x_d call ya_x_line mov ax,x4 mov bx,x3 mov cx,y3 call ya_x_line add bx,x_d add cx,x_d call ya_x_line cmp touch_flag,1 je e4 mov ax,y3 ;判断是否到终点 mov bx,ax add bx,x_d mov cx,x4 call ya_y_line mov al,touch_flag mov arrive_flag,al e4: ret ya_line_do endp ;*****************判断是否触到y线***************** ya_y_line proc ;ax为y1(起点),bx为y2(终点),cx为x1 cmp x,cx je n3 mov dx,cx ;注意cx不能变化 sub dx,9 cmp x,dx jnz n1 n3: mov dx,ax sub dx,9 cmp y,dx jl n1 cmp y,bx jg n1 mov touch_flag,1 n1: ret ya_y_line endp ;*****************判断是否触到x线***************** ya_x_line proc ;ax为x1(起点),bx为x2(终点),cx为y1 cmp y,cx je n5 mov dx,cx ;注意cx不能变化 sub dx,9 cmp y,dx jnz n2 n5: mov dx,ax sub dx,9 cmp x,dx jl n2 cmp x,bx jg n2 mov touch_flag,1 n2: ret ya_x_line endp ;************************小车触轨则后退一步*************************** back_step proc cmp direc_flag,1 ;如果碰到轨道,则后退一步 jne a5 inc y a5: cmp direc_flag,2 jne a6 dec y a6: cmp direc_flag,3 jne a7 inc x a7: cmp direc_flag,4 jne a8 dec x ret back_step endp ;*********************************************************************************************************************** ;*********************************************************************************************************************** code ends end start ```
做了一个小时的面试题(没有过 希望大家帮忙答下 虽然很幼稚 毕竟每个人都是这么过来的吗 感激了!)
XX软件工程师笔试试题 注:1、请参考人员将答案写在答题纸上,勿将答案写在此卷上。 2、请参考人员将编号与姓名填写在答题纸上。 1、 以下数据结构中不属于线性数据结构的是()。 A、队列 B、线性表 C、二叉树 D、栈 我的答案:C 2、 在结构化方法中,用数据流程图(DFD)作为描述工具的软件开发阶段是()。 A、 可行性分析 B、需求分析 C、详细设计 D、程序编码 我的答案:B 3、 结构化程序设计主要强调的是()。 A、 程序的规模 B、程序的易读性 C、程序的执行效率 D、程序的可移植性 我的答案:C 4、 在软件生命周期中,能准确地确定软件系统必须做什么和必须具备哪些功能的阶段()。 A、 概要设计 B、详细设计 C、可行性分析 D、需求分析 我的答案:B 5、 下列关于栈的叙述中正确的是()。 A、 在栈中只能插入数据 B、在栈中只能删除数据 B、 栈是先进先出的线性表 D、栈是先进后出的线性表 我的答案:D 6、 下面不属于软件设计原则的是()。 A、 抽象 B、模块化 C、自底向上 D、信息隐蔽 我的答案:C 7、 对长度为N的线性表进行顺序查找,在最坏情况下所需要的比较次数为()。 A、 N+1 B、N C、(N+1)/2 D、N/2 我的答案:C 8、 视图设计一般有3种设计次序,下列不属于视图设计的是()。 A、 自顶向下 B、由外向内 C、由内向外 D、自底向上 我的答案:C 9、下列有关数据库的描述,正确的是()。 A、数据库是一个DBF文件 B、数据库是一个关系 C、数据库是一个结构化的数据集合 D、数据库是一组文件 我的答案:C 10、下列说法中,不属于数据模型所描述的内容的是()。 A、数据结构 B、数据操作 C、数据查询 D、数据约束 我的答案:A 11、若按功能划分,软件测试的方法通常分为白盒测试方法和(黑盒测试方法)。 12、数据库系统的三级模式分别为(级联)模式、内部级模式与外部级模式。 13、在最坏情况下,冒泡排序的时间复杂度为(N+1/2)。 14、在面向对象方法中,信息隐蔽是通过对象的(封装)性来实现的。 15、关系模型的数据操纵既是建立在关系上的数据操纵,一般有(插入)、增加、删除、和修改四种操作。 16、TIME()的返回值的数据类型是(String)类型。 17、编写SQL语句 1)、创建一张学生表,包含以下信息,学号,姓名,年龄,性别,家庭住址,联系电话 我的答案: create table student( studentCardNo number(2) primary key, name char(10), age number(2), sex char(2) check(sex in (‘男’,’女’)), address varchar2(100), tel number(2) ) 2)、修改学生表的结构,添加一列信息,学历 我的答案: alter table student add(xueli varchar2(20)); 3)、修改学生表的结构,删除一列信息,家庭住址 我的答案: alter table student drop column address; 4)、向学生表添加如下信息: 学号 姓名 年龄 性别 联系电话 学历 1 A 22 男 123456 小学 2 B 21 男 119 中学 3 C 23 男 110 高中 4 D 18 女 114 大学 我的答案: insert into student values(‘&1’,’&2’,’&3’); 一次一次添加 5)修改学生表的数据,将电话号码以11开头的学员的学历改为“大专” 我的答案: update student set xueli=”大专” where tel like 11%; 6)删除学生表的数据,姓名以C开头,性别为‘男’的记录删除 我的答案: delete student where name like C% or sex=”男”; 7)查询学生表的数据,将所有年龄小于22岁的,学历为“大专”的,学生的姓名和学号显示出来 我的答案: select name,studentCardNo from student where age<22 and xueli=”大专”; 8)查询学生表的数据,查询所有信息,列出前25%的记录 我的答案: select top*0.25 from student; 9)查询出所有学生的姓名,性别,年龄降序排列 我的答案: select name,sex,age from student where age desc; 10)按照性别分组查询所有的平均年龄 我的答案: select avg(age) from student group by sex; 18、什么是存储过程?为什么存储过程要比单纯的SQL语句执行起来要快? 我的答案: 存储过程算是一种优化查询需要比单存SQL语句执行的要快 19、两张关联表,删除主表中已经在副表中没有的信息 我的答案 delete from fubiao a where a.fid not in(select id from zhubiao) 20、程序题: 用1、2、2、3、4、5这六个数字,用java或你熟悉的语言,打印出所有不同的排列,如:512234、412345等,要求:“4”不能再第三位,“3”与“5”不能相连。并将这些数据按从小到大输出。 我的答案 我的写的不好 没贴下 笔试的时候没写全 21、String 和 StringBuffer的区别 我的答案 String定长 StringBuffer 变长 22、&和&&的区别 我的答案 &短路与 &&逻辑与 网上答案: & 是位运算符,表示按位与运算, && 是逻辑运算符,表示逻辑与(and)。 23、final,finally,finalize的区别 我的答案 Final静变量关键字,finally异常关键字,finalize 网上答案 final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 finally是异常处理语句结构的一部分,表示总是执行。 finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法, 可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 24、数组有没有length()这个方法?String有没有length()这个方法? 我的答案: 数组没有length()这个方法,有length的属性。 String有length()这个方法。 25、是否可以继承String类? 我的答案: 不可以 解释的很乱 26、说出数据连接池的工作机制是什么? 我的答案: 反正解释的很乱我感觉 27、垃圾回收的优点和原理。并考虑2种回收机制。 我的答案: 动态回收 解释的很乱 网上答案: Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解, 它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有"作用域"的概念, 只有对象的引用才有"作用域"。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。 垃圾回收器通常是作为一个单独的低级别的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有 使用的对象进行清除和回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。 回收机制有分代复制垃圾回收和标记垃圾回收,增量垃圾回收。 28、你所知道的集合类都有哪些?区别?主要方法? 我的答案: Arraylist 非线性的、Vertor线性的 29、JSP的内置对象及方法。 我的答案: Page,exception,out,page content,application,request,reponse,session,config 30、页面间对象传递的方法。 我的答案: 那几个方法都写错了 31、你知道Request对象的主要方法有哪些? 32、J2EE是技术还是平台还是框架? 我的答案: J2EE是技术也是平台 网上答案: J2EE本身是一个标准,一个为企业分布式应用的开发提供的标准平台。 J2EE也是一个框架,包括JDBC、JNDI、RMI、JMS、EJB、JTA等技术。 33、我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种(例如GBK编码类型)编码的字符串? Request encording(“GBK”) 34、j2ee常用的设计模式?说明工厂模式。 Gof23种设计模式 工厂模式:Factory 网上答案: Java中的23种设计模式: Factory(工厂模式), Builder(建造模式), Factory Method(工厂方法模式), Prototype(原始模型模式),Singleton(单例模式), Facade(门面模式), Adapter(适配器模式), Bridge(桥梁模式), Composite(合成模式), Decorator(装饰模式), Flyweight(享元模式), Proxy(代理模式), Command(命令模式), Interpreter(解释器模式), Visitor(访问者模式), Iterator(迭代子模式), Mediator(调停者模式), Memento(备忘录模式), Observer(观察者模式), State(状态模式), Strategy(策略模式), Template Method(模板方法模式), Chain Of Responsibleity(责任链模式) 工厂模式:工厂模式是一种经常被使用到的模式,根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例, 通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。 首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。 然后需要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。 当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。 35、JSP四种会话跟踪技术 我的答案: Application cookie session 36、排序都有哪几种方法?请举例 冒泡 选择 快序 二分查找 网上答案: 排序的方法有:插入排序(直接插入排序、希尔排序), 交换排序(冒泡排序、快速排序), 选择排序(直接选择排序、堆排序), 归并排序,分配排序(箱排序、基数排序) 快速排序的伪代码。 //使用快速排序方法对a[ 0 :n- 1 ]排序 从a[ 0 :n- 1 ]中选择一个元素作为m i d d l e,该元素为支点 把余下的元素分割为两段left 和r i g h t,使得l e f t中的元素都小于等于支点,而right 中的元素都大于等于支点 递归地使用快速排序方法对left 进行排序 递归地使用快速排序方法对right 进行排序 所得结果为l e f t + m i d d l e + r i g h t 37、关于模块间的设计原则? 规范要一样 38、项目过程一般是怎样的?你参加过几个项目开发?参加过的项目流程是怎样的?自己负责与人合作工作内容及自我评价? 从需求调研——设计开发——实施 参加过网站的实施 模板的制作 39、tomcat自动关闭常见原因? 我的答案: 现在没遇到过 40、如何设置TOMCAT内存和连接数? 我的答案: Tomcat群集 41、你如何理解Tomcat是什么? 我的答案: Tomcat是JSP Servlet 容器恰当的说 42、静态变量和实例变量的区别? 我的答案: 静态变量域用final修饰,每次都被调用 实例变量则不会 43、IE、FF下面CSS的解释区别 我的答案: 自己编的 44、web前端技术你了解哪些技术? 我的答案: JAVAScript,CSS,DIV,Ajax,Ajax框架,DWR,dojo,jguery 45、什么是报表?什么是报表控件,作用是什么?你了解哪些报表工具? 我的答案: 解释的很乱 46、你了解的那些统计图表类型? 我的答案: 自己编的 47、Flex与数据库连接的三种方式? 我的答案: 自己编的 ------------------------------------------------------- 我答错的、 错在哪里? 没答上的帮忙解答下? 感激了 !
PL0编译器调用procedure无限循环
如题,自己参照网上的例子做了一个C语言的PL0编译器,能跑通,但是遇到调用procedure的时候,就会一直循环无限调用,查错查了好久,还是没有找到,希望有大神能为我解答一下!谢谢~ 代码如下,有点长。。 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> using namespace std; #define MAXERR 20//最多错误次数 #define AL 12//标识符最大长度 #define NORW 14//保留字个数 #define NUMMAX 14//最大数字位数 #define TXMAX 100//符号表容量 #define AMAX 2048//地址上界 #define CXMAX 200//最多的虚拟机代码数 #define stacksize 500//运行时数据栈元素最多为500个 #define symnum 32 #define fctnum 8 enum symbol //符号 { nul, ident, number, pluss, minuss, times, slash, oddsym, eql, neq, lss, leq, gtr, geq, lparen, rparen, comma, semicolon, period, becomes, beginsym, endsym, ifsym, thensym, elsesym, whilesym, writesym, readsym, dosym, callsym, constsym, varsym, procsym, }; enum object //符号表类型 { constant, variable, procedure, }; enum fct //虚拟机指令 { LIT, OPR, LOD, STO, CAL, INT, JMP, JPC, }; struct instruction //虚拟机代码结构 { enum fct f;//虚拟机指令 int l;//引用层与声明层层次差 int a;//根据f的不同而不同 }; FILE * fin; FILE * fout; FILE * fv;//虚拟机代码 FILE * fo;//源代码 FILE * fr;//代码运行结果 FILE * ft;//符号表 char fname[AL]; char ch;//存放当前字符 int cc, ll;//getch计数器,cc表示ch的位 int cx;//虚拟机代码指针 int num;//当前数字 int err;//错误计数器 char a[AL+1];//临时符号 char id[AL+1];//当前ident char line[81];//行缓冲区 char word[NORW][AL];//保留字 enum symbol sym;//当前符号 enum symbol wsym[NORW];//保留字对应符号值 enum symbol ssym[256];//单字符符号值 struct instruction code[CXMAX];//存放虚拟机代码的数组 char mnemonic[fctnum][5];//虚拟机代码指令名称 bool declbegsys[symnum];//表示声明开始的符号集合 bool statbegsys[symnum];//表示语句开始的符号集合 bool facbegsys[symnum];//表示因子开始的符号集合 struct tablestruct //符号表结构 { char name[AL];//名字 enum object kind;//类型 int val;//数值 int level;//所处层 int addr;//地址 int size;//需要分配的数据区空间 }; struct tablestruct table[TXMAX];//符号表 void init(); int inset(int e, bool* s); int addset(bool* sr, bool* s1, bool* s2, int n); int subset(bool* sr, bool* s1, bool* s2, int n); int mulset(bool* sr, bool* s1, bool* s2, int n); void error(int n); void getsym(); void getch(); void gen(enum fct x, int y, int z); void test(bool* s1, bool* s2, int n); void block(int lev, int tx, bool* fsys); void enter(enum object k, int* ptx, int lev, int* pdx); int position(char* idt, int tx); void constdeclaration(int* ptx, int lev, int* pdx); void vardeclaration(int* ptx, int lev, int* pdx); void listcode(int cx0); void statement(bool* fsys, int* ptx, int lev); void expression(bool* fsys, int* ptx, int lev); void term(bool* fsys, int* ptx, int lev); void factor(bool* fsys, int* ptx, int lev); void condition(bool* fsys, int* ptx, int lev); void interpret(); int base(int l, int* s, int b); void init() { int i; for(i=0; i<255; i++) //单字符符号 { ssym[i] = nul; } ssym['+'] = pluss; ssym['-'] = minuss; ssym['*'] = times; ssym['/'] = slash; ssym['('] = lparen; ssym[')'] = rparen; ssym['='] = eql; ssym[','] = comma; ssym['.'] = period; ssym[';'] = semicolon; //保留字名字 strcpy(&(word[0][0]), "begin"); strcpy(&(word[1][0]), "call"); strcpy(&(word[2][0]), "const"); strcpy(&(word[3][0]), "do"); strcpy(&(word[4][0]), "else"); strcpy(&(word[5][0]), "end"); strcpy(&(word[6][0]), "if"); strcpy(&(word[7][0]), "odd"); strcpy(&(word[8][0]), "procedure"); strcpy(&(word[9][0]), "read"); strcpy(&(word[10][0]), "then"); strcpy(&(word[11][0]), "var"); strcpy(&(word[12][0]), "while"); strcpy(&(word[13][0]), "write"); //保留字符号 wsym[0] = beginsym; wsym[1] = callsym; wsym[2] = constsym; wsym[3] = dosym; wsym[4] = elsesym; wsym[5] = endsym; wsym[6] = ifsym; wsym[7] = oddsym; wsym[8] = procsym; wsym[9] = readsym; wsym[10] = thensym; wsym[11] = varsym; wsym[12] = whilesym; wsym[13] = writesym; //指令名称 strcpy(&(mnemonic[LIT][0]), "LIT"); strcpy(&(mnemonic[OPR][0]), "OPR"); strcpy(&(mnemonic[LOD][0]), "LOD"); strcpy(&(mnemonic[STO][0]), "STO"); strcpy(&(mnemonic[CAL][0]), "CAL"); strcpy(&(mnemonic[INT][0]), "INT"); strcpy(&(mnemonic[JMP][0]), "JMP"); strcpy(&(mnemonic[JPC][0]), "JPC"); //符号集 for(i=0; i<symnum; i++) { declbegsys[i] = false; statbegsys[i] = false; facbegsys[i] = false; } //声明开始符号集 declbegsys[constsym] = true; declbegsys[varsym] = true; declbegsys[procsym] = true; //语句开始符号集 statbegsys[beginsym] = true; statbegsys[callsym] = true; statbegsys[ifsym] = true; statbegsys[whilesym] = true; //因子开始符号集 facbegsys[ident] = true; facbegsys[number] = true; facbegsys[lparen] = true; } /* *用数组实现集合的集合运算 */ int inset(int e, bool* s) { return s[e]; } int addset(bool* sr, bool* s1, bool* s2, int n) { int i; for(i=0; i<n ;i++) { sr[i] = s1[i] || s2[i]; } return 0; } int subset(bool* sr, bool* s1, bool* s2, int n) { int i; for(i=0; i<n; i++) { sr[i] = s1[i] && (!s2[i]); } return 0; } int mulset(bool* sr, bool* s1, bool* s2, int n) { int i; for(i=0; i<n; i++) { sr[i] = s1[i] && s2[i]; } return 0; } //error处理:输出报错位置以及错误编号 void error(int n) { cc--;//出错时当前符号已经读完,cc-1 //printf("错误编号:%d\n",n); cout<<"错误编号:"<<n<<endl; fprintf(fo, "错误编号:%d\n", n); err++; if(err > MAXERR) { exit(1); } } //读取字符 void getch() { if(cc == ll)//判断缓冲区中是否有字符,若无字符,则读入下一行字符到缓冲区中 { if(feof(fin)) { cout<<"程序不完整"<<endl; exit(1); } ll = 0; cc = 0; printf("%d ", cx); fprintf(fo, "%d ", cx); ch = ' '; while(ch != 10)//读取一行字符到缓冲区 { //fscanf(fin,"%c",&ch) if(EOF == fscanf(fin, "%c", &ch)) { line[ll] = 0; break; } printf("%c", ch); //cout<<ch; fprintf(fo, "%c", ch); line[ll] = ch; ll++; } } ch = line[cc]; cc++; } //词法分析 void getsym() { int i, j, k; while(ch==' ' || ch==10 || ch==9)//过滤掉空格、换行符 { getch(); } if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z')) { i = 0; do{ if(i < AL) { a[i] = ch; i++; } getch(); } while((ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch>='0' && ch<='9')); a[i] = 0; strcpy(id, a); /* for(j = 0; j < 13; j++) { if(strcmp(id, word[i]) == 0) break; } */ //改为用二分法查找保留字 j = 0; k = NORW - 1; do { i=(j + k) / 2; if(strcmp(id, word[i])<=0) { k = i - 1; } if(strcmp(id, word[i])>=0) { j = i + 1; } } while(j <= k); if(j - 1 > k)//单词为保留字 { sym = wsym[i]; } else//单词为标识符 { sym = ident; } } else { if(ch>='0' && ch<='9')//单词为数字 { i = 0; num = 0; sym = number; do { num = 10 * num + ch - '0'; i++; getch(); } while(ch>='0' && ch<='9'); //获取数字的值 i--; if(i > NUMMAX)//数字位数太大 { error(30); } } else { if(ch == ':')//检测赋值符号 { getch(); if(ch == '=') { sym = becomes; getch(); } else { sym = nul;//不能识别的符号 } } else { if(ch == '<')//检测小于或小于等于符号以及不等号 { getch(); if(ch == '=') { sym = leq; getch(); } else if(ch=='>')//检测不等号 { sym = neq;//构成不等号<> getch(); } else { sym = lss; } } else { if(ch == '>')//检测大于或大于等于符号 { getch(); if(ch == '=') { sym = geq; getch(); } else { sym = gtr; } } else { sym = ssym[ch];//当符号不满足上述条件时,全部按照单字符号处理 if(sym != period) { getch(); } } } } } } } //生成P-code即虚拟机代码 void gen(enum fct x, int y, int z ) { if (cx >= CXMAX) { cout<<"虚拟机代码长度过长!"<<endl; exit(1); } if ( z >= AMAX) { cout<<"地址偏移越界!"<<endl; exit(1); } code[cx].f = x; code[cx].l = y; code[cx].a = z; cx++; } //测速当前符号单词是否合法 void test(bool* s1, bool* s2, int n) { if(!inset(sym, s1)) { error(n);//当检测不通过时,不停获取符号,直到它属于S1或S2 while((!inset(sym, s1)) && (!inset(sym, s2))) { getsym(); } } } //分程序分析处理 void block(int lev, int tx, bool* fsys) { int i; int dx;//名字分配到的相对地址 int tx0;//保留初始tx int cx0;//保留初始cx bool nxtlev[symnum]; dx = 3;//分别存放SL,DL和返回地址 tx0 = tx;//本层标识符初始位置 table[tx].addr = cx;//当前层代码开始位置 gen(JMP, 0, 0);//生成跳转指令 do{ if(sym == constsym)//常量声明符号,处理常量声明 { getsym(); do{ constdeclaration(&tx, lev, &dx); while(sym == comma)//逗号,继续读取 { getsym(); constdeclaration(&tx, lev, &dx); } if(sym == semicolon)//分号,结束读取 { getsym(); } else { error(5);//漏掉逗号或者分号 } }while(sym == ident); } if(sym == varsym)//变量声名符号,处理变量声名 { getsym(); do{ vardeclaration(&tx, lev, &dx); while(sym == comma)//逗号,继续读取 { getsym(); vardeclaration(&tx, lev, &dx); } if(sym == semicolon)//分号,结束读取 { getsym(); } else { error(5);//漏掉逗号或者分号 } }while(sym == ident); } while(sym == procsym)//过程声名符号,处理过程声名 { getsym(); if(sym == ident) { enter(procedure, &tx, lev, &dx);//过程名字 getsym(); } else { error(4);//procedure后应为标识符 } if(sym == semicolon)//分号,结束读取 { getsym(); } else { error(5);//漏掉分号 } memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[semicolon]=true; block(lev+1, tx, nxtlev);//递归 if(sym == semicolon) { getsym(); memcpy(nxtlev, statbegsys, sizeof(bool)* symnum); nxtlev[ident]=true; nxtlev[procsym]=true; test(nxtlev, fsys, 6); } else { error(5);//漏掉分号 } } memcpy(nxtlev, statbegsys, sizeof(bool)*symnum); nxtlev[ident]=true; //nxtlev[period]=true; test(nxtlev, declbegsys, 7); } while(inset(sym, declbegsys));//直到没有声明符号 code[table[tx0].addr].a = cx;//开始生成当前过程代码 table[tx0].addr = cx;//当前过程代码地址 table[tx0].size = dx;//dx为当前过程数据的size cx0 = cx; gen(INT, 0, dx);//生成分配内存代码 //输出符号表 for(i = 1; i <= tx; i++) { switch(table[i].kind) { case constant: printf("%d const %s", i, table[i].name); printf("val=%d\n", table[i].val); fprintf(ft, "%d const %s", i, table[i].name); fprintf(ft, "val=%d\n", table[i].val); break; case variable: printf("%d var %s", i, table[i].name); printf("lev=%d addr=%d\n", table[i].level, table[i].addr); fprintf(ft, "%d var %s", i, table[i].name); fprintf(ft, "lev=%d addr=%d\n", table[i].level, table[i].addr); break; case procedure: printf("%d proc %s", i, table[i].name); printf("lev=%d addr=%d size=%d\n", table[i].level,table[i].addr, table[i].size); fprintf(ft, "%d proc %s", i, table[i].name); fprintf(ft, "lev=%d adr=%d size=%d \n", table[i].level,table[i].addr, table[i].size); break; } } printf("\n"); fprintf(ft, "\n"); //语句后跟分号或end memcpy(nxtlev, fsys, sizeof(bool)* symnum);//每个后跟符号集和都包含上层后跟符号集和,以便补救 nxtlev[semicolon] = true; nxtlev[endsym] = true; statement(nxtlev, &tx, lev); gen(OPR, 0, 0); //每个过程出口都要使用的释放数据段命令 memset(nxtlev, 0, sizeof(bool)* symnum); //分程序没有补救集合 test(fsys, nxtlev, 8);//检测后跟符号正确性 listcode(cx0);//输出代码 } //登录符号表 void enter (enum object k, int *ptx, int lev, int *pdx) { (*ptx)++; strcpy(table[(*ptx)].name, id);//符号表记录标识符的名字 table[(*ptx)].kind = k; switch(k) { case constant://常量 if (num > AMAX) { error(31);//过界报错 num = 0; } table[(*ptx)].val = num;//记录常数值 break; case variable://变量 table[(*ptx)].level = lev; table[(*ptx)].addr = (*pdx); (*pdx)++; break; case procedure://过程 table[(*ptx)].level = lev; break; } } //查找标识符在符号表的位置 int position(char* idt, int tx) { int i; strcpy(table[0].name, idt); i = tx; while(strcmp(table[i].name, idt) != 0) { i--; } return i; } //常量定义处理 void constdeclaration(int* ptx, int lev,int* pdx) { if(sym == ident) { getsym(); if((sym == eql) || (sym == becomes)) { if(sym == becomes) { error(1);//应该是=而不是:= } getsym(); if(sym == number) { enter(constant, ptx, lev, pdx);//填写符号表 getsym(); } else { error(2);//=后应为数 } } else { error(3);//标识符后应为= } } else { error(4);//const后应为标识符 } } //变量声明处理 void vardeclaration(int* ptx ,int lev, int* pdx) { if(sym == ident) { enter(variable, ptx, lev, pdx);//填写符号表 getsym(); } else { error(4);//var后应为标识符 } } //列出P-code指令清单 void listcode(int cx0) { int i; printf("\n"); for(i=cx0; i<cx; i++) { printf("%d %s %d %d\n", i, mnemonic[code[i].f], code[i].l,code[i].a); fprintf(fv,"%d %s %d %d\n", i, mnemonic[code[i].f], code[i].l, code[i].a); } } //语句部分分析处理 void statement(bool* fsys, int * ptx, int lev) { int i, cx1, cx2; bool nxtlev[symnum]; if(sym == ident)//按照赋值语句处理 { i = position(id, *ptx);//查找标识符在符号表中的位置 if(i == 0) { error(11);//标识符未说明 } else { if((table[i].kind != variable)) { error(12);//不可向常量或过程赋值 i = 0; } else { getsym(); if(sym == becomes) { getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); expression(nxtlev, ptx, lev); if(i != 0) { gen(STO, lev-table[i].level, table[i].addr); } } else { error(13);//应为赋值运算符:= } } } } else { if(sym == readsym)//按照read语句处理 { getsym(); if(sym != lparen) { error(40);//应为左括号 } else { do{ getsym(); if(sym == ident) { i = position(id, *ptx);//查找要读的变量 } else { i = 0; } if(i == 0) { error(35);//read括号中标识符未声明 } else { gen(OPR, 0, 15);//生成输入指令 gen(STO, lev-table[i]. level, table[i].addr);//将栈顶内容存到变量中 } getsym(); }while(sym == comma);//读多个变量 } if(sym!=rparen) { error(33);//应为右括号 while(!inset(sym, fsys))//出错补救,直到收到上层函数的后跟符号 { getsym(); } } else { getsym(); } } else { if(sym==writesym)//按照write语句处理 { getsym(); if(sym != lparen) { error(40);//应为左括号 } else { do{ getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[rparen] = true; nxtlev[comma] = true;//write后符号为)或, expression(nxtlev, ptx, lev);//调用表达式处理 gen(OPR, 0, 13);//生成输出指令,输出栈顶的值 gen(OPR, 0, 14);//换行 }while(sym == comma);//输出多个 if(sym != rparen) { error(33);//应为右括号 } else { getsym(); } } } else { if(sym == callsym)//按照call语句处理 { getsym(); if(sym != ident) { error(14);//call后应为标识符 } else { i=position(id, *ptx); if(i == 0) { error(11); //过程未声明 } else { if(table[i].kind == procedure) { gen(CAL, lev-table[i].level, table[i].addr);//生成call指令 } else { error(15);//不可调用常量或变量 } } getsym(); } } else { if(sym == ifsym)//按照if语句处理 { getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[thensym] = true; nxtlev[dosym] = true;//if后符号为then或do condition(nxtlev, ptx, lev);//调用条件处理 if(sym == thensym) { getsym(); } else { error(16);//应为then } cx1 = cx;//当前指令地址 gen(JPC, 0, 0);//生成条件跳转指令 statement(fsys, ptx, lev);//处理then下面的语句 if(sym==elsesym)//处理else语句 { getsym(); cx2 = cx; code[cx1].a=cx+1;//cx+1为then语句执行后的else语句的位置 gen(JMP, 0, 0); statement(fsys, ptx, lev); code[cx2].a = cx;//cx为else后语句执行完的位置 } else { code[cx1].a = cx;//cx为then后面语句执行 完的位置,它正是前面未定的跳转地址*/ } } else { if(sym==beginsym)//按照复合语句处理 { getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[semicolon]=true; nxtlev[endsym]=true;//begin后符号为:或end statement(nxtlev, ptx, lev);//处理begin和end之间的语句 while((inset(sym, statbegsys)) || (sym == semicolon)) { if(sym = semicolon) { getsym(); } else { error(10);//语句之间没有分号 } statement(nxtlev, ptx, lev); }//循环处理 if(sym == endsym) { getsym(); } else { error(17);//应为分号或end } } else { if(sym == whilesym)//按照while语句处理 { cx1 = cx;//判断条件操作位置 getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[dosym]=true;//while后符号为do condition(nxtlev, ptx, lev);//调用条件处理 cx2 = cx;//循环体的结束的下一个位置 gen(JPC, 0, 0);//生成条件跳转 if(sym == dosym) { getsym(); } else { error(18);//应为do } statement(fsys, ptx, lev); gen(JMP, 0, cx1);//重新判断条件 code[cx2].a = cx; } } } } } } } memset(nxtlev, 0, sizeof(bool)* symnum);//语句结束无补救集合 test(fsys, nxtlev, 19);//检测语句结束的正确性 } //表达式分析处理 void expression(bool* fsys, int* ptx, int lev) { enum symbol sign;//正负号 bool nxtlev[symnum]; if((sym == pluss) || (sym == minuss))//开头的正负号 { sign = sym; getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[pluss] = true; nxtlev[minuss] = true; term(nxtlev, ptx, lev);//对项进行处理 if(sign == minuss) { gen(OPR, 0, 1);//如果开头为负号,生成取负指令 } } else { memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[pluss] = true; nxtlev[minuss] = true; term(nxtlev, ptx, lev);//对项进行处理 } while((sym == pluss) || (sym == minuss)) { sign = sym; getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[pluss] = true; nxtlev[minuss] = true; term(nxtlev, ptx, lev);//对项进行处理 if(sign == pluss) { gen(OPR, 0, 2);//加法 } else { gen(OPR, 0, 3);//减法 } } } //项分析处理 void term(bool*fsys, int *ptx, int lev) { enum symbol sign;//乘除法符号 bool nxtlev[symnum]; memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[times] = true; nxtlev[slash] = true; factor(nxtlev, ptx, lev);//对因子进行处理 while((sym == times) || (sym == slash)) { sign = sym; getsym(); factor(nxtlev, ptx, lev); if(sign == times) { gen(OPR, 0, 4);//乘法 } else { gen(OPR, 0, 5);//除法 } } } //因子分析处理 void factor(bool* fsys, int* ptx, int lev) { int i; bool nxtlev[symnum]; test(facbegsys, fsys, 24);//检测因子开始符号 while(inset(sym, facbegsys))//循环处理因子 { if(sym == ident)//因子为常量或者变量 { i = position(id, *ptx);//查找标识符位置 if(i == 0) { error(11);//未声明标识符 } else { switch(table[i].kind)//不同形式标识符 { case constant: gen(LIT, 0, table[i].val);//常量入栈 break; case variable: gen(LOD, lev-table[i].level, table[i].addr);//变量入栈 break; case procedure: error(21);//表达式内不能有过程标识符 break; } } getsym(); } else { if(sym == number) //因子为数字的时候 { if(num > AMAX) { error(31);//过界报错 num = 0; } gen(LIT, 0, num); getsym(); } else { if(sym == lparen)//因子为表达式的时候 { getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[rparen] = true; expression(nxtlev, ptx, lev); if(sym == rparen) { getsym(); } else { error(22);//没有右括号 } } //test(fsys, facbegsys, 23);//一个因子处理完毕,遇到的单词应在fsys集合中 ,如果不是,报错并找到下一个因子的开始,使语法分析继续运行 } } memset(nxtlev, 0, sizeof(bool) * symnum); nxtlev[lparen] = true; test(fsys, facbegsys, 23);//一个因子处理完毕,遇到的单词应在fsys集合中 ,如果不是,报错并找到下一个因子的开始,使语法分析继续运行 } } //条件分析处理 void condition(bool* fsys, int* ptx, int lev) { enum symbol sign; bool nxtlev[symnum]; if(sym == oddsym) { getsym(); expression(fsys, ptx, lev); gen(OPR, 0, 6); } else//处理分析逻辑表达式 { memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[eql]=true; nxtlev[neq]=true; nxtlev[lss]=true; nxtlev[leq]=true; nxtlev[gtr]=true; nxtlev[geq]=true; expression(nxtlev, ptx, lev); if((sym!=eql)&&(sym!=neq)&&(sym!=lss)&&(sym!=leq)&&(sym!=gtr)&&(sym!=geq)) { error(20);//应为关系运算符 } else { sign = sym; getsym(); expression(fsys, ptx, lev); switch(sign) { case eql: gen(OPR, 0, 7); break; case neq: gen(OPR, 0, 8); break; case lss: gen(OPR, 0, 9); break; case gtr: gen(OPR, 0, 10); break; case leq: gen(OPR, 0, 11); break; case geq: gen(OPR, 0, 12); break; } } } } //P-code解释执行程序 void interpret() { int p = 0;//指令指针 int b = 1;//指令基址 int t = 0;//栈顶指针 struct instruction i;//存放当前指令 int s[stacksize];//栈 cout<<"执行PL0:"<<endl; fprintf(fr, "执行PL0:\n"); s[0] = 0; s[1] = 0; s[2] = 0; s[3] = 0; do{ i = code[p];//读当前指令 p++; switch(i.f) { case LIT://将a的值取到栈顶 t++; s[t]=i.a; break; case OPR://数字逻辑运算 switch(i.a) { case 0://函数调用后返回 t = b - 1; p = s[t+3]; b = s[t+2]; break; case 1://取反 s[t] = -s[t]; break; case 2://栈顶两个元素相加 t--; s[t] = s[t] + s[t+1]; break; case 3://栈顶两个元素相减 t--; s[t] = s[t] - s[t+1]; break; case 4://栈顶两个元素相乘 t--; s[t] = s[t] * s[t+1]; break; case 5://栈顶两个元素相除 t--; s[t] = s[t] / s[t+1]; break; case 6://栈顶元素奇偶判断 s[t] = s[t] % 2; break; case 7://栈顶两个元素是否相等 t--; s[t] = (s[t] == s[t+1]); break; case 8://栈顶两个元素是否不等 t--; s[t] = (s[t] != s[t+1]); break; case 9://小于 t--; s[t] = (s[t] < s[t+1]); break; case 10://大于 t--; s[t] = (s[t] > s[t+1]); break; case 11://小于等于 t--; s[t] = (s[t] <= s[t+1]); break; case 12://大于等于 t--; s[t] = (s[t] >= s[t+1]); break; case 13://输出栈顶值 printf("%d", s[t]); fprintf(fr, "%d", s[t]); t--; break; case 14://输出换行符 printf("\n"); fprintf(fr, "\n"); break; case 15://读入 t++; printf("输入:"); fprintf(fr, "输入:"); scanf("%d", &(s[t])); fprintf(fr, "%d\n", s[t]); break; } break; case LOD://取相对当前过程的数据基地址为a的内存的值到栈顶 t++; s[t] = s[base(i.l, s, b) + i.a]; break; case STO://栈顶的值存到相对当前过程的数据基地址为a的内存 s[base(i.l, s, b) + i.a] = s[t]; t--; break; case CAL://调用子程序 s[t+1] = base(i.l, s,b); s[t+2] = b; s[t+3] = p; b = t + 1; p = i.a; break; case INT://分配内存 t += i.a; break; case JMP://直接跳转 p=i.a; break; case JPC://条件跳转 if(s[t] == 0) { p = i.a; } t--; break; } }while(p != 0); printf("PL0结束\n"); fprintf(fr, "PL0结束\n"); } //通过静态链求出数据区基地址 int base(int l,int* s, int b) { int b1; b1 = b; while(l > 0) { b1 = s[b1]; l--; } return b1; } int main() { bool nxtlev[symnum]; cout<<"*****PL0编译器*****"<<endl; cout<<"输出文件中,fv为虚拟机代码,fo为源代码,fr为运行结果,ft为符号表"<<endl; cout<<"请输入pl0文件:"<<endl; scanf("%s", fname); fin = fopen(fname, "r"); if(fin == NULL) { cout<<"无法打开文件!" <<endl; exit(1); } if(fgetc(fin) == EOF) { cout<<"文件为空!" <<endl; exit(1); } rewind(fin); fo = fopen("fo.txt", "w"); init(); err = 0; cc = ll = cx = 0; ch=' '; getsym(); fv = fopen("fv.txt", "w"); ft = fopen("ft.txt", "w"); addset(nxtlev, declbegsys, statbegsys, symnum); nxtlev[period]=true; block(0, 0, nxtlev);//调用编译程序 fclose(fv); fclose(fo); fclose(ft); fclose(fin); printf("\n"); if(sym != period) { error(9);//应为句号 } if(err == 0) { cout<<"*****************************"<<endl; fr = fopen("fr.txt", "w"); interpret(); fclose(fr); } else { printf("程序出错!"); } fclose(fin); printf("\n"); getchar(); }
PTA 03-树3 Tree Traversals Again
在Dev C++里输出答案正确,但过不了PTA测试里的sample测试,显示答案错误DEV C++jie'guo![图片说明](https://img-ask.csdn.net/upload/201904/08/1554730373_211527.jpg) 代码如下 ``` #include<stdio.h> #include<string.h> #include<stdlib.h> typedef struct stack* Ptrs; struct BinTree{ int data; int left; int right; }; struct stack{ int s_data; Ptrs next; }; void push(int data,Ptrs s) { Ptrs tmp; tmp=(Ptrs)malloc(sizeof(struct stack)); tmp->s_data=data; if(s->next==NULL) { s->next=tmp; tmp->next=NULL; } else { tmp->next=s->next; s->next=tmp; } } int pop(Ptrs s) { int top; Ptrs tmp; tmp=s->next; top=tmp->s_data; s->next=tmp->next; free(tmp); return top; } int top(Ptrs s) { if(s->next==NULL) return 0; else return(s->next->s_data); } int Isempty(Ptrs s) { if(s->next==NULL) return 0; else return 1; } void plantTree(int N,struct BinTree T[]) { char op[5]; int data; Ptrs stack; stack=(Ptrs)malloc(sizeof(struct stack)); stack->next=NULL; int k=0; int pre_top; int flag=0; for(int i=0;i<2*N;i++) { //输入部分 scanf("%s",op); if(strcmp(op,"Push")==0) { if(i==2*N-1) scanf(" %d",&data); else scanf(" %d\n",&data); if(flag==0) pre_top=top(stack); push(data,stack); T[k].data=data; k++; if(pre_top!=0) { if(T[pre_top-1].left==0) T[pre_top-1].left=data; else T[pre_top-1].right=data; } flag=0; } else { if(i==2*N-1); else scanf("\n"); pre_top=pop(stack); flag=1;// } }//plant tree successfully } int SearchFather(int child,int N,struct BinTree T[]) { for(int i=0;i<N;i++) { if(T[i].left==child||T[i].right==child) return(T[i].data); } return 0;//root } int LeftLeaf(int left,int root,struct BinTree T[],Ptrs stack)//找到左叶,并一直push father和右兄弟;若没有左叶,则不执行push { while(left!=0) { if(T[root].data!=top(stack)) push(T[root].data,stack); if(T[root].right!=0) push(T[root].right,stack); root=left-1;//一直向左的终点 数组序号 left=T[root].left; } if(T[root].data!=top(stack)) push(T[root].data,stack); } void postOrderTraversal(int N,struct BinTree T[]) { Ptrs stack; stack=(Ptrs)malloc(sizeof(struct stack)); stack->next=NULL; int left,root; int flag=0; root=0;//root left=T[root].left; //push(T[root].data,stack); LeftLeaf(left,root,T,stack); //找到左叶,并push while(Isempty(stack)!=0)//栈不空时 { int _pop; _pop=pop(stack); if(flag==1) printf(" "); printf("%d",_pop);//输出 flag=1; int father=SearchFather(_pop,N,T); if(top(stack)!=father)//还有右兄弟分支需遍历 ,若相等说明已经遍历过右边 { root=top(stack)-1; left=T[root].left; LeftLeaf(left,root,T,stack);//find leftleaf } } } int main() { int N; scanf("%d\n",&N); struct BinTree T[N]={0}; plantTree(N,T); postOrderTraversal(N,T); return 0; } ```
爬虫福利二 之 妹子图网MM批量下载
爬虫福利一:27报网MM批量下载    点击 看了本文,相信大家对爬虫一定会产生强烈的兴趣,激励自己去学习爬虫,在这里提前祝:大家学有所成! 目标网站:妹子图网 环境:Python3.x 相关第三方模块:requests、beautifulsoup4 Re:各位在测试时只需要将代码里的变量 path 指定为你当前系统要保存的路径,使用 python xxx.py 或IDE运行即可。
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、PDF搜索网站推荐 对于大部
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 顺便拉下票,我在参加csdn博客之星竞选,欢迎投票支持,每个QQ或者微信每天都可以投5票,扫二维码即可,http://m234140.nofollow.ax.
Vue + Spring Boot 项目实战(十四):用户认证方案与完善的访问拦截
本篇文章主要讲解 token、session 等用户认证方案的区别并分析常见误区,以及如何通过前后端的配合实现完善的访问拦截,为下一步权限控制的实现打下基础。
比特币原理详解
一、什么是比特币 比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是国家信用。去中心化电子记账系统是参与者共同记账。比特币可以防止主权危机、信用风险。其好处不多做赘述,这一层面介绍的文章很多,本文主要从更深层的技术原理角度进行介绍。 二、问题引入  假设现有4个人
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 欢迎 改进 留言。 演示地点跳到演示地点 html代码如下`&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;music&lt;/title&gt; &lt;meta charset="utf-8"&gt
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。 1. for - else 什么?不是 if 和 else 才
数据库优化 - SQL优化
前面一篇文章从实例的角度进行数据库优化,通过配置一些参数让数据库性能达到最优。但是一些“不好”的SQL也会导致数据库查询变慢,影响业务流程。本文从SQL角度进行数据库优化,提升SQL运行效率。 判断问题SQL 判断SQL是否有问题时可以通过两个表象进行判断: 系统级别表象 CPU消耗严重 IO等待严重 页面响应时间过长
2019年11月中国大陆编程语言排行榜
2019年11月2日,我统计了某招聘网站,获得有效程序员招聘数据9万条。针对招聘信息,提取编程语言关键字,并统计如下: 编程语言比例 rank pl_ percentage 1 java 33.62% 2 c/c++ 16.42% 3 c_sharp 12.82% 4 javascript 12.31% 5 python 7.93% 6 go 7.25% 7
通俗易懂地给女朋友讲:线程池的内部原理
餐厅的约会 餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”我楞了一下,心里想女朋友今天是怎么了,怎么突然问出这么专业的问题,但做为一个专业人士在女朋友面前也不能露怯啊,想了一下便说:“我先给你讲讲我前同事老王的故事吧!” 大龄程序员老王 老王是一个已经北漂十多年的程序员,岁数大了,加班加不动了,升迁也无望,于是拿着手里
经典算法(5)杨辉三角
写在前面: 我是 扬帆向海,这个昵称来源于我的名字以及女朋友的名字。我热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。 这博客是对自己学习的一点点总结及记录,如果您对 Java、算法 感兴趣,可以关注我的动态,我们一起学习。 用知识改变命运,让我们的家人过上更好的生活。 目录一、杨辉三角的介绍二、杨辉三角的算法思想三、代码实现1.第一种写法2.第二种写法 一、杨辉三角的介绍 百度
腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
昨天,有网友私信我,说去阿里面试,彻底的被打击到了。问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题。无独有偶,今天笔者又发现有网友吐槽了一道腾讯的面试题,我们一起来看看。 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹? 在互联网职场论坛,一名程序员发帖求助到。二面腾讯,其中一个算法题:64匹
面试官:你连RESTful都不知道我怎么敢要你?
面试官:了解RESTful吗? 我:听说过。 面试官:那什么是RESTful? 我:就是用起来很规范,挺好的 面试官:是RESTful挺好的,还是自我感觉挺好的 我:都挺好的。 面试官:… 把门关上。 我:… 要干嘛?先关上再说。 面试官:我说出去把门关上。 我:what ?,夺门而去 文章目录01 前言02 RESTful的来源03 RESTful6大原则1. C-S架构2. 无状态3.统一的接
为啥国人偏爱Mybatis,而老外喜欢Hibernate/JPA呢?
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行了一番讨论,感触还是有一些,于是就有了今天这篇文。 声明:本文不会下关于Mybatis和JPA两个持久层框架哪个更好这样的结论。只是摆事实,讲道理,所以,请各位看官勿喷。 一、事件起因 关于Mybatis和JPA孰优孰劣的问题,争论已经很多年了。一直也没有结论,毕竟每个人的喜好和习惯是大不相同的。我也看
SQL-小白最佳入门sql查询一
一 说明 如果是初学者,建议去网上寻找安装Mysql的文章安装,以及使用navicat连接数据库,以后的示例基本是使用mysql数据库管理系统; 二 准备前提 需要建立一张学生表,列分别是id,名称,年龄,学生信息;本示例中文章篇幅原因SQL注释略; 建表语句: CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // dosho
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,
程序员:我终于知道post和get的区别
IT界知名的程序员曾说:对于那些月薪三万以下,自称IT工程师的码农们,其实我们从来没有把他们归为我们IT工程师的队伍。他们虽然总是以IT工程师自居,但只是他们一厢情愿罢了。 此话一出,不知激起了多少(码农)程序员的愤怒,却又无可奈何,于是码农问程序员。 码农:你知道get和post请求到底有什么区别? 程序员:你看这篇就知道了。 码农:你月薪三万了? 程序员:嗯。 码农:你是怎么做到的? 程序员:
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU
加快推动区块链技术和产业创新发展,2019可信区块链峰会在京召开
      11月8日,由中国信息通信研究院、中国通信标准化协会、中国互联网协会、可信区块链推进计划联合主办,科技行者协办的2019可信区块链峰会将在北京悠唐皇冠假日酒店开幕。   区块链技术被认为是继蒸汽机、电力、互联网之后,下一代颠覆性的核心技术。如果说蒸汽机释放了人类的生产力,电力解决了人类基本的生活需求,互联网彻底改变了信息传递的方式,区块链作为构造信任的技术有重要的价值。   1
程序员把地府后台管理系统做出来了,还有3.0版本!12月7号最新消息:已在开发中有github地址
第一幕:缘起 听说阎王爷要做个生死簿后台管理系统,我们派去了一个程序员…… 996程序员做的梦: 第一场:团队招募 为了应对地府管理危机,阎王打算找“人”开发一套地府后台管理系统,于是就在地府总经办群中发了项目需求。 话说还是中国电信的信号好,地府都是满格,哈哈!!! 经常会有外行朋友问:看某网站做的不错,功能也简单,你帮忙做一下? 而这次,面对这样的需求,这个程序员
Android 9.0系统新特性,对刘海屏设备进行适配
其实Android 9.0系统已经是去年推出的“老”系统了,这个系统中新增了一个比较重要的特性,就是对刘海屏设备进行了支持。一直以来我也都有打算针对这个新特性好好地写一篇文章,但是为什么直到拖到了Android 10.0系统都发布了才开始写这篇文章呢?当然,一是因为我这段时间确实比较忙,今年几乎绝大部分的业余时间都放到写新书上了。但是最主要的原因并不是这个,而是因为刘海屏设备的适配存在一定的特殊性
网易云6亿用户音乐推荐算法
网易云音乐是音乐爱好者的集聚地,云音乐推荐系统致力于通过 AI 算法的落地,实现用户千人千面的个性化推荐,为用户带来不一样的听歌体验。 本次分享重点介绍 AI 算法在音乐推荐中的应用实践,以及在算法落地过程中遇到的挑战和解决方案。 将从如下两个部分展开: AI 算法在音乐推荐中的应用 音乐场景下的 AI 思考 从 2013 年 4 月正式上线至今,网易云音乐平台持续提供着:乐屏社区、UGC
【技巧总结】位运算装逼指南
位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子。不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也是可以装逼的,不信,你往下看。我会从最简单的讲起,一道比一道难度递增,不过居然是讲技巧,那么也不会太难,相信你分分钟看懂。 判断奇偶数 判断一个数是基于还是偶数,相信很多人都做过,一般的做法的代码如下
日均350000亿接入量,腾讯TubeMQ性能超过Kafka
整理 | 夕颜出品 | AI科技大本营(ID:rgznai100) 【导读】近日,腾讯开源动作不断,相继开源了分布式消息中间件TubeMQ,基于最主流的 OpenJDK8开发的
8年经验面试官详解 Java 面试秘诀
    作者 | 胡书敏 责编 | 刘静 出品 | CSDN(ID:CSDNnews) 本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三百位候选人。在本文里,就将结合本人的面试经验,针对Java初学者、Java初级开发和Java开发,给出若干准备简历和准备面试的建议。   Java程序员准备和投递简历的实
面试官如何考察你的思维方式?
1.两种思维方式在求职面试中,经常会考察这种问题:北京有多少量特斯拉汽车? 某胡同口的煎饼摊一年能卖出多少个煎饼? 深圳有多少个产品经理? 一辆公交车里能装下多少个乒乓球? 一
碎片化的时代,如何学习
今天周末,和大家聊聊学习这件事情。 在如今这个社会,我们的时间被各类 APP 撕的粉碎。 刷知乎、刷微博、刷朋友圈; 看论坛、看博客、看公号; 等等形形色色的信息和知识获取方式一个都不错过。 貌似学了很多,但是却感觉没什么用。 要解决上面这些问题,首先要分清楚一点,什么是信息,什么是知识。 那什么是信息呢? 你一切听到的、看到的,都是信息,比如微博上的明星出轨、微信中的表情大战、抖音上的...
相关热词 c# clr dll c# 如何orm c# 固定大小的字符数组 c#框架设计 c# 删除数据库 c# 中文文字 图片转 c# 成员属性 接口 c#如何将程序封装 16进制负数转换 c# c#练手项目
立即提问