为什么用while循环至链表某尾时程序不再运行?

void list_smax(lnode *first)//first为链表的首个节点,该函数的目的是找到链表中成员square值最大的节点
{
lnode *p,*s;
int i;
p=first;
s=first;
while(s!=NULL)
{
if(p->squaresquare)//square为链表节点中float类型的成员
p=s;
s=s->next;
printf("%d\n",i);
i++;
}
printf("面积最大项为:\n");
printf("%-18s%-10s%5.3f%12d\n",p->add,p->name,p->square,p->num);
}

图片说明

1个回答

看下链表的初始化
malloc分配之后,有没有默认把next指针设置为NULL
怀疑最后一个以后有野指针,导致while(s!=NULL)没有办法停止。

Cooper__D
Cooper__D 谢谢啦!
11 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
[紧急求救]C++:在循环结构中使用链表,程序运行终端
如题。(这是图像处理中的中值滤波,不过问题不涉及图像处理) 链表操作都没有问题,在另外的程序中测试过。这这段代码中第一次调用也没有问题,就是第二次到list.insert()时会跳出中断: ![图片说明](https://img-ask.csdn.net/upload/201505/14/1431535355_2983.png) 这段代码如下: ``` int i, j, x, y, p, t;//p为当前像素位置 int a[arg*arg] = {0}; linklist list; for (y = 0; y<nHeight - arg + 1; y++) { for (x = 0; x<nWidth - arg + 1; x++) { //计算每一点的算术均值滤波,p为模板左上角点 p = x * 3 + y*nByteWidth; t = p; list.create(); for (j = 0; j < arg; ++j) { for (i = 0; i < arg; ++i) { ****list.insert(lpBits[t]);**** t += 3; } t = t - 3 * arg + nByteWidth; }//上面t指向原图中的位置,下面指向滤波后图像的位置 list.display(a); t = p + (nByteWidth + 3)*(arg - 1) / 2; lpTemp[t] = a[(arg*arg+1)/2]; lpTemp[t + 1] = lpTemp[t]; lpTemp[t + 2] = lpTemp[t]; list.del(list); } } ``` 是一点一点设断点找到这个地方的。其他地方应该都没有问题。应该是我链表没delete好。 插入的函数:list.insert()如下: ``` //插入一个节点并构成顺序链表 void linklist::insert(int pix) { node *p, *q; q = new node; int i, len; len = listlength(); p = head; for (i = 0; i < len; ++i) { if (pix < p->data) { q->data = p->data, q->next = p->next; p->data = pix, p->next = q; i = len; } else if (pix < p->next->data) { q->data = pix, q->next = p->next, p->next = q; i = len; } else { p = p->next; } } if (p->next == NULL) q->data = pix, p->next = q, q->next = NULL; } ``` 删除链表的函数list.del(list);如下: ``` //销毁链表 void linklist::del(linklist list) { node *d, *p; p = head; while (p != NULL){ d = p; p = p->next; delete d; } } ``` 整个工程完整的代码如下[代码](http://pan.baidu.com/s/1pJsUe51 "压缩包是工程,下面是单独的cpp文件") ps:明天晚上就要交作业了,这段代码还要用到其他地方。真心请教各位
求大神指导双向循环链表问题【0xC0000005: 读取位置 0xfeeefeee 时发生访问冲突】
小弟欲新建一双向循环链表,对链表中符合删除条件的数据进行删除操作。整个程序编译无bug,运行中断。主函数运行到新建链表后打印函数中的cout<<pn->data<<" ";VS2010显示的错误为“0xC0000005: 读取位置 0xfeeefeee 时发生访问冲突”,求大神指教,是否是我新建链表的函数或宏定义中new和delete函数使用错误,还是我新建双向循环链表的算法有问题啊,望不吝赐教!!! 以下是部分代码,包含新建函数和打印函数: #include<iostream> #define CreateNode(x) x = new BLPtr #define DeleteNode(x) delete []x using namespace std; struct BLPtr { char data; struct BLPtr *prior; struct BLPtr *next; }; struct BLPtr *creat(void); void print(struct BLPtr *p); bool beErased(char); //struct BLPtr erase(struct BLPtr *p); int erase(struct BLPtr *p); int main() { struct BLPtr *p; p = creat(); cout<<"原始链表数据为:"<<endl; print(p); erase(p); cout<<"处理后链表数据为:"<<endl; print(p); return 0; } struct BLPtr *creat(void) {//建立一个无附加头结点的双向循环链表 struct BLPtr *head,*p1,*p2; head = p1 = CreateNode(p2);//新建第一个结点 cout<<"请输入第一个结点数据:"; cin>>p2->data;//输入第一个结点数据 while(p2->data != '#')//输入“#”结束 { p2->prior = p1;//后方前驱指针指向前方结点 p1->next = p2;//前方后继指针指向后方结点 CreateNode(p2);//新建结点 cout<<"请继续输入:"; cin>>p2->data;//输入新节点数据 } head->prior = p1;//头结点前驱指针指向尾结点 p1->next = head;//尾结点后继指针指向头结点 head = p2;//删除最后无用结点和指针 DeleteNode(p2); return p1; } void print(struct BLPtr *p) { struct BLPtr *pn; pn = p->next; while(pn != p)//输出除p以外的结点数据 { cout<<pn->data<<" ";//运行中断,求指教 pn = pn->next;//沿next向下搜索 } cout<<pn->data<<endl;//输出最后一个结点数据 }
该程序运行时刀输入序号的时候输入不进去为什么?有大神知道吗
#include<stdio.h> #include<stdlib.h> typedef struct splist { double data; splist *next; } splist; /*单链表创建的思路 1.声明一个指针p和计数器变量i 2.初始化一个空链表L; 3.让L的头结点指针指向NULL, 4.循环; 生成一个新节点赋值给p 将p插入头结点和前一新节点之间 */ void CJ(splist *L,int n) { splist *p; splist *x=L; int i; x=(splist*)malloc(sizeof(splist)); x->next=NULL; double c; scanf("%lf",&c); printf("请开始建表"); for(i=0;i<n;i++) { p=(splist*)malloc(sizeof(splist)); p->data=c; p->next=x->next; x->next=p; } } double FH(splist*L,int i) { double *e; int j; splist*p; splist *x=L; p=x->next; j=1; while(p&&j<i) { p=p->next; j++; } if(!p||j>i) return 0; *e=p->data; return *e; } int main() { splist *L; double c; int m; int x; printf("请输入表的长度"); scanf("%d",&m); CJ(L,m); printf("请输入要返回的序号");//运行时无法输入序号 scanf("%d",&x); c=FH(L,x); printf("%lf",c); return 0; }
为什么我这【链表】 内存释放不了?
程序可以运行,可以输入,可以输出,但是到了释放内存的时候就有问题了 求大神指正。 ``` #include <stdio.h> #include <stdlib.h> typedef struct node{ int data; struct node *next; }*LPNODE; LPNODE CreateList(int n); void ShowList(LPNODE lphead); int main(void) { LPNODE lpHead, temp, current; int num; puts("请问您需要几个节点?"); scanf_s("%d", &num); lpHead = CreateList(num); ShowList(lpHead); //释放链表 current = lpHead; while (current != NULL) { temp = current->next; free(current); current = temp; } return 0; } LPNODE CreateList(int n) { int _data, count = 0; LPNODE lpHead = NULL; LPNODE current, prev; lpHead = current = prev = (LPNODE)malloc(sizeof(LPNODE)); puts("请输入一个数字:"); while (scanf_s("%d", &_data)) { current = (LPNODE)malloc(sizeof(LPNODE)); prev->next = current; current->data = _data; current->next = NULL; prev = current; count++; //控制循环 if (count < n) puts("请输入下一个数字"); else { puts("输入结束!"); break; } } return lpHead; } void ShowList(LPNODE lpHead) { LPNODE p = lpHead->next; while (p != NULL) { printf("%d ", p->data); p = p->next; } } ```
c语言链表删除节点问题
#include <stdio.h> #define NUll 0 #include <stdlib.h> struct stu { char name[6]; int xuehao; int grade; struct stu *next; }; typedef struct stu STU; main() { STU *p,*p_start,*p2,*p_print,*p_charu,*p_charu2; int i,xuehao; //输入 for (i=0;i<3;i++) { p=(STU *)malloc(sizeof(STU)); printf("请输入学生姓名:\n"); scanf("%s",&p->name); printf("请输入学生的学号:\n"); scanf("%d",&p->xuehao); printf("请输入学生的成绩:\n"); scanf("%d",&p->grade); if (i==0) p2=p_start=p; else { p2->next=p; p2=p; if (i==2) p->next=NULL; } } // printf("%d",p_start->next->next->next); // printf("%d",p_start->next->next->xuehao); //链表的插入 p_charu=p_start; printf("请输入要删除的学号\n"); scanf("%d",&xuehao); while (1) { p_charu2=p_charu->next; if (p_charu->next->xuehao==xuehao) { // if (p_charu->next->next==NULL) // p_charu->next=NULL; else p_charu->next=p_charu->next->next; free(p_charu2); break; } if (p_charu->xuehao==xuehao) { p_start=p_charu->next; free(p_charu); break; } p_charu=p->next; } //输出 p_print=p_start; /* for (i=0;i<2;i++) { printf("学生姓名为:%s\n",p_print->name); printf("学生的学号为:%d\n",p_print->xuehao); printf("学生的分数为:%d\n",p_print->grade); if (p_print->next!=NULL) p_print=p_print->next; } */ } 这是一个删除结点并输出的程序, 加注释的输出部分没有问题,关键应该在删除结点的循环那里,但是找不见错误啊, 错误为:当删除最后一个链表也就是3时程序发生错误,停止运行。 求解
代码没有错误,为什么程序没运行完就直接结束了?
![图片说明](https://img-ask.csdn.net/upload/201908/08/1565246195_162168.png) ![图片说明](https://img-ask.csdn.net/upload/201908/08/1565246218_224284.png) ``` //主要功能:实现带小数二进制和十进制之间数据的转换 #include <iostream.h> #include <windows.h> #include <fstream.h> #include <string> #include <math.h> using namespace std; const int TAILMAXLENTH=10;//定义十进制转换成二进制小数部分最大位数 const int DABAMAXLENTH=40;//定义原始数据的最大长度 const double ADDMENBERNUM=111.11;//定义一个加数用于检测数据真实可用 /********************************************************************************************************* *栈的部分 *********************************************************************************************************/ class Stack;//类Stack的声明 /* 定义一个链栈结点类Stacknode */ class Stacknode { friend class Stack;//申请友元类 private: Stacknode(Stacknode *nextp=NULL);//构造函数 Stacknode(int &newdata,Stacknode *nextp=NULL);//构造函数 int data;//数据元素 Stacknode *next;//递归定义指向后继结点的指针 }; /* Stacknode的实现部分 */ Stacknode::Stacknode(Stacknode *nextp)//构造函数 { next=nextp; } Stacknode::Stacknode(int &newdata,Stacknode *nextp)//构造函数 { data=newdata; next=nextp; } //结点类Stacknode的定义结束 /* 定义一个链栈类Stack */ class Stack { public: Stack();//创建一个空栈 ~Stack();//回收一个栈 void clear();//销毁一个栈 bool empty() const;//确定栈是否已空 bool push(int &item);//把数据压进栈 bool pop();//出栈 bool top(int &item) const;//取出栈顶元素 private: Stacknode *newnode(Stacknode *nextp=NULL); Stacknode *newnode(int &item,Stacknode *nextp=NULL);//创建新的结点 Stacknode *Stacktop; int Stacklength; }; /* Stack的实现部分 */ Stacknode *Stack::newnode(Stacknode *nextp)//创建新的结点,不带数据 { return new Stacknode(nextp); } Stacknode *Stack::newnode(int &item,Stacknode *nextp)//创建新的结点,数据域赋值 { return new Stacknode(item,nextp); } //以下为栈类Stack的函数定义 Stack::Stack()//创建一个空栈 { Stacktop=newnode();//创建一个栈顶指针初始化,相当于Stacktop=NULL;本链表没有用头结点 Stacklength=0; } Stack::~Stack()//回收一个栈 { clear(); delete Stacktop;//释放栈底 } void Stack::clear()//销毁一个栈 { //while(pop());//不停地出栈,而每次释放空间在出栈函数中完成 Stacknode *usednodep;//定义指针usednodep,准备指向出栈的结点 while(Stacktop->next!=NULL) { usednodep=Stacktop;//指向出栈的结点 Stacktop=Stacktop->next;//栈顶指针后移 delete usednodep;//释放空间 } } bool Stack::empty() const//确定栈是否已空 { return Stacklength<=0?true:false; } bool Stack::push(int &item)//数据进栈 { Stacknode *newnodep;//定义指针newnodep,准备指向申请的新结点 newnodep=newnode(item,Stacktop);//申请新结点,把数据存入,把指针域指向头指针 if(!newnodep)//如果没有申请到空间,返回失败 return false; Stacktop=newnodep;//改链,完成进栈 Stacklength++;//栈的长度增加 return true;//本次操作成功 } bool Stack::pop()//出栈,不要栈顶数据 { Stacknode *usednodep;//定义指针usednodep,准备指向出栈的结点 if(!empty())//判断是否栈空 { usednodep=Stacktop;//指向出栈的结点 Stacktop=Stacktop->next;//栈顶指针后移 // delete usednodep;//释放空间 Stacklength--;//栈的长度减少 return true;//本次操作成功 } return false;//否则本次操作失败 } bool Stack::top(int &item) const//取出栈顶数据返回去 { if(!empty())//如果栈不空,记录当前栈顶元素 { item=Stacktop->data;//通过item返回去 return true;//本次操作成功 } return false;//否则本次操作失败 } /********************************************************************************************************* *队列的部分 *********************************************************************************************************/ /* 定义一个结点类node */ class node { public: int data; node *next; }; /* 定义一个链队类Queue */ class Queue { private: node *rear; node *front; protected: int count;//计数器,统计结点个数即线性队列的长度 public: Queue();//构造函数 ~Queue();//析构函数 void clear(void);//清空链队 bool empty(void) const;//判断是否空队 bool retrieve(int &item) const;//读取队头 bool append(const int &item);//数据入队 bool serve();//数据出队 }; /* 类Queue的实现部分 */ Queue::Queue()//构造函数 { front=new node;//申请新结点,作为队头结点 front->next=NULL; rear=front;//队尾指针指向队头 count=0;//计数器清零,队列开始时没有实际数据 } Queue::~Queue()//析构函数 { clear();//删除所有数据,释放所有结点 delete front;//把头结点也释放掉 count=0;//计数器清零,队列开始时没有实际数据 } void Queue::clear(void)//清空链队 { node *searchp=front->next,*followp=front;//初始化两个指针 while(searchp!=rear) { followp=searchp; searchp=searchp->next; delete followp; } front->next=NULL;//保留了最后一个结点,就是头结点,并且链域置为空 rear=front; count=0;//计数器也清零 } bool Queue::empty(void) const//判断是否空链 { return count==0?true:false; } bool Queue::retrieve(int &item) const//读取队头 { if(empty())//处理意外 return false; item=front->next->data;//返回读取的数据 return true;//本次操作成功 } bool Queue::append(const int &item)//进队 { node *newnodep=new node; newnodep->data=item;//给数据赋值 rear->next=newnodep;//这一步可以看出有头结点 rear=rear->next;//改动队尾指针的位置 count++;//计数器加1 return true; } bool Queue::serve()//出队 { if(empty())//空队处理 return false; node *tempp=front->next; // item=tempp->data;//保存数据 front->next=tempp->next;//改变指针 delete tempp;//释放该结点 count--;//计数器减1 return true; } /********************************************************************************************************* *定义一个功能类NumSysConversion *********************************************************************************************************/ class NumSysConversion { private: int inter; float floater; Stack *stack; Queue *queue; public: NumSysConversion();//构造函数 ~NumSysConversion();//析构函数 bool check(char *array,int number);//检查输入数据是否符合要求 void change(char *array,int number);//将原始数据转化成数值 double change_to_aim(int tokind);//将原始数据转化成目标进制的数据 }; NumSysConversion::NumSysConversion()//构造函数 { stack=new Stack; queue=new Queue; inter=0; floater=0; } NumSysConversion::~NumSysConversion()//析构函数 { delete stack; delete queue; } bool NumSysConversion::check(char *array,int number)//检查输入数据是否符合要求 { bool flag=true; for(int i=0;array[i]!='\0';i++) { cout<<array[i]; if(array[i]-48>=number) { flag=false; break; } } return flag; } void NumSysConversion::change(char *array,int number)//将原始数据转化成数值 { int flag=0,j=0; for(int i=0;array[i]!='\0';i++) { if(array[i]=='.') { flag=1; continue; } if(flag==0)//取整数数据 inter=inter*number+array[i]-48; if(flag==1)//取小数数据 floater+=(float)(((int)array[i]-48)*(float)pow(number,--j)); } } double NumSysConversion::change_to_aim(int tokind)//将原始数据转化成目标进制的数据 { int count=0,temp,flag=0,num; double resnumb=0; //第一步:先将整数部分转换进制后的数据依次入栈 while(inter) { num=inter%tokind; stack->push(num); inter/=tokind; } //第二步:再将小数部分转换进制后的数据依次入队 while(floater&&count<TAILMAXLENTH) { queue->append(int(floater*tokind)); floater*=tokind; if(floater>=1) floater-=(int)floater; count++; } //第三步:显示栈和队中的数据并将其转换成可用数据 cout<<"数据转换后为:"; while(!stack->empty()) { stack->top(temp); stack->pop(); cout<<temp; resnumb=resnumb*tokind+temp; flag=1; } if(!queue->empty()) { if(flag==0) cout<<"0"; cout<<"."; count=-1; } while(!queue->empty()) { queue->retrieve(temp); queue->serve(); cout<<temp; resnumb+=temp*pow(tokind,count--); } cout<<endl; //第四步:清空栈和队中的数据 stack->clear(); queue->clear(); inter=0; floater=0; //第五步:将可用数据信息返回 return resnumb; } /* 定义一个实现进制转换功能的菜单处理类interfacebase */ class interfacebase { private: NumSysConversion NumSysConversiononface; public: void clearscreen(void);//清屏 void showmenu(void);//显示菜单函数 int userchoice(void);//用户的选项 void processmenu(int menuchoice);//菜单函数 }; /* 类interfacebase的实现部分 */ void interfacebase::clearscreen(void) { system("cls"); } void interfacebase::showmenu(void) { cout<<"进制转换功能菜单"<<endl; cout<<"================"<<endl; cout<<"1.十进制转换为二进制"<<endl; cout<<"2.二进制转换为十进制"<<endl; cout<<"0.结束程序"<<endl; cout<<"================"<<endl; } int interfacebase::userchoice(void) { int menuchoice; cout<<"请输入您的选择:"; cin>>menuchoice; return menuchoice; } void interfacebase::processmenu(int menuchoice) { switch(menuchoice)//根据用户的选择进行相应的操作 { case 1: { char array[10]={'0','.','1','2','5'}; int number=10; if(NumSysConversiononface.check(array,number)) cout<<"符合要求!"<<endl; else cout<<"不符合要求!"<<endl; NumSysConversiononface.change(array,number); cout<<NumSysConversiononface.change_to_aim(2)<<endl; cout<<"进制转换成功!"<<endl; } break; case 2: { char array[10]={'1','1','1','1'}; int number=2; if(NumSysConversiononface.check(array,number)) cout<<"符合要求!"<<endl; else cout<<"不符合要求!"<<endl; NumSysConversiononface.change(array,number); cout<<NumSysConversiononface.change_to_aim(10)<<endl; cout<<"进制转换成功!"<<endl; } break; case 0: exit(0); default: cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl; break; } } /* 程序主入口 */ void main(void) { int menuchoice;//定义变量,菜单选单项的选择 interfacebase interfacenow; system("color f0");//修改屏幕的背景色和字的颜色 interfacenow.clearscreen();//清屏 while(1)//永真循环 { interfacenow.showmenu();//显示菜单 menuchoice=interfacenow.userchoice();//获取用户的选择 interfacenow.processmenu(menuchoice);//处理用户的选择 system("pause");//暂停 interfacenow.clearscreen();//清屏 } }//主函数结束 ```
Linux中c语言多线程gdb调试“Cannot access memory at address”如何解决
程序的目的是做一个xml解析的工作。 部分代码如下: #define BUFLEN 10240 typedef struct buffer_t//需要操作的结构体 { char *buf; Bcsarray *bcsay; int bufnum; struct buffer_t *next; }databuf; databuf *buf, *bufs;//buf为链表头,bufs为操作时的游动指针 void readxml(void *arg);//第一个线程,已经正确初始化了buf链表,每块中buf->buf的大小都为BUFLEN+1;问题不在这个函数中,故不再列出 void division(void *arg)//有两个重要位置我标记了出来,后面有说明 { bufs = buf; while (bufs != NULL) { int i = 0, j = 0; int n = 0; if (bufs->buf[i] == '<') { j = i; j++; switch (bufs->buf[j]) { case '/': { while (1) { j++; if (bufs->buf[j] == 0) { if (bufs->next == NULL) { bufs->bcsay->bcs[n].bufnum = bufs->bufnum; bufs->bcsay->bcs[n].bufpos = i; bufs->bcsay->bcs[n].bt = Etag_start; i = j; break; } else { char *e = (char*)malloc(sizeof(char)*(BUFLEN + 1)); **strcpy(e, bufs->next->buf);//这里报错(2号位置)** strcpy(bufs->next->buf, bufs->buf + i); strcat(bufs->next->buf, e); bufs->buf[i] = 0; free(e); break; } } if (bufs->buf[j] == '<') { bufs->bcsay->bcs[n].bufnum = bufs->bufnum; bufs->bcsay->bcs[n].bufpos = i; bufs->bcsay->bcs[n].bt = Etag_start; n++; i = j; break; } } }; break; case '?': { while (1) { j++; if (bufs->buf[j] == 0) { char *e = (char*)malloc(sizeof(char)*(BUFLEN + 1)); strcpy(e, bufs->next->buf); strcpy(bufs->next->buf, bufs->buf + i); strcat(bufs->next->buf, e); bufs->buf[i] = 0; free(e); break; } if (bufs->buf[j] == '>') { if (bufs->buf[j - 1] == '?') { bufs->bcsay->bcs[n].bufnum = bufs->bufnum; bufs->bcsay->bcs[n].bufpos = i; bufs->bcsay->bcs[n].bt = PI_start; n++; j++; i = j; break; } } } }; break; case '!': { while (1) { j++; if (bufs->buf[j] == 0) { char *e = (char*)malloc(sizeof(char)*(BUFLEN + 1)); strcpy(e, bufs->next->buf); strcpy(bufs->next->buf, bufs->buf + i); strcat(bufs->next->buf, e); bufs->buf[i] = 0; free(e); break; } if (bufs->buf[j] == '>') { if (bufs->buf[j - 1] == '-'&&bufs->buf[j - 2] == '-') { bufs->bcsay->bcs[n].bufnum = bufs->bufnum; bufs->bcsay->bcs[n].bufpos = i; bufs->bcsay->bcs[n].bt = COMMENT_start; n++; j++; i = j; break; } else if (bufs->buf[j - 1] == ']'&&bufs->buf[j - 2] == ']') { bufs->bcsay->bcs[n].bufnum = bufs->bufnum; bufs->bcsay->bcs[n].bufpos = i; bufs->bcsay->bcs[n].bt = CDSECT_start; n++; j++; i = j; break; } } } }; break; default: { while (1) { j++; if (bufs->buf[j] == 0) { if (bufs->next == NULL) { bufs->bcsay->bcs[n].bufnum = bufs->bufnum; bufs->bcsay->bcs[n].bufpos = i; int k = 1; while (1) { if (bufs->buf[j - k] == '>') { if (bufs->buf[j - k - 1] == '/') bufs->bcsay->bcs[n].bt = Etag_start; else bufs->bcsay->bcs[n].bt = Stag_start; break; } k++; } i = j; } else { char *e = (char*)malloc(sizeof(char)*(BUFLEN + 1)); **strcpy(e, bufs->next->buf);//这里正常运行(1号位置)** strcpy(bufs->next->buf, bufs->buf + i); strcat(bufs->next->buf, e); bufs->buf[i] = 0; free(e); break; } } if (bufs->buf[j] == '<') { bufs->bcsay->bcs[n].bufnum = bufs->bufnum; bufs->bcsay->bcs[n].bufpos = i; int k = 1; while (1) { if (bufs->buf[j - k] == '>') { if (bufs->buf[j - k - 1] == '/') bufs->bcsay->bcs[n].bt = Etag_start; else bufs->bcsay->bcs[n].bt = Stag_start; break; } k++; } n++; i = j; break; } } }; break; } } else { i++; } } bufs = bufs->next; } } 两个线程我已经做了处理,暂时是串行执行的,互不影响。division这个线程,第一次(1号位置)和第二次(二号位置)运行的分支我已标注出,分支中的逻辑完全相同,但是只有第一次可以运行通过,第二次就不行了。循环会有很多次,但现在只能运行到第二次结尾。本来想删掉一部分无关代码,但害怕出问题,敬请谅解。 以上代码,我在windows下用vs2015跑过。把两个线程串行地写在一个函数中,正常运行。但是在Linux下用多线程,就会出现以上问题,strcpy函数位置出错。 后来经过调试发现,是在二号位置中,bufs->next->buf的问题。当我在gdb中调试到这里时,用“p bufs->next->buf”输出内容时,就出现Cannot access memory at address的错误。但是我访问数据结构中的其他项,比如 “p bufs->next->bufnum”,输出正常。并且在上一个线程中,一切正常。 求大神指点。
简易家谱系统——哪位大神能帮我看看下面的代码有什么问题,非常感谢!!!
/*在DEV C++编译有问题,但在CodeBlocks编译没问题而且能运行,但是运行时又在数据测试在删除结点后程序运行异常结束*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #define M 100+1 // 宏定义,定义最大名字字母长度 typedef struct elem { char* name; char* post; }element; //双亲孩子表示法 typedef struct tree { element* item; int level; int childNum; struct tree* parent; struct tree* nextSibling; struct tree* prevSibling; struct tree* firstChild; }Node; // 实现一个栈,用于后续操作 typedef struct stack_t { Node** array; // array是个数组,其元素为Node*型指针 int index; // 指示栈顶元素 int size; // 栈的大小 } STACK; // 重命名 // 实现一个队列,用于后续操作 typedef struct queue_t { Node** array; // array是个数组,其内部元素为Node*型指针 int head; // 队列的头 int tail; // 队列的尾 int num; // 队列中元素的个数 int size; // 队列的大小 } QUEUE; // 这里的栈和队列,都是用动态数组实现的,另一种实现方式是用链表 // 内存分配函数 void* util_malloc(int size) { void* ptr = malloc(size); if (ptr == NULL) // 如果分配失败,则终止程序 { printf("Memory allocation error!\n"); exit(EXIT_FAILURE); } // 分配成功,则返回 return ptr; } // 实现一些栈操作 // 栈的初始化 STACK* STACKinit(int size)// 初始化栈大小为size { STACK* sp; sp = (STACK*)util_malloc(sizeof (STACK)); sp->size = size; sp->index = 0; sp->array = (Node**)util_malloc(size * sizeof (Node*)); return sp; } // 检测栈是否为空 // 如果为空返回1,否则返回0 int STACKempty(STACK* sp) { if (sp == NULL || sp->index <= 0) // 空 { return 1; } return 0; } // 入栈操作 int STACKpush(STACK* sp, Node* data) { if (sp == NULL || sp->index >= sp->size) // sp没有被初始化,或者已满 { return 0; // 入栈失败 } sp->array[sp->index++] = data; // 入栈 return 1; } // 出栈操作 int STACKpop(STACK* sp, Node** data_ptr) { if (sp == NULL || sp->index <= 0) // sp为初始化,或者为空没有元素 { return 0; } *data_ptr = sp->array[--sp->index]; // 出栈并把栈顶元素由参数data_ptr带回,成功则返回1 return 1; } // 将栈消毁 void STACKdestroy(STACK* sp) { free(sp->array); free(sp); } // 以上是栈的操作 // 实现队列的操作 QUEUE* QUEUEinit(int size) { QUEUE* qp; qp = (QUEUE*)util_malloc(sizeof (QUEUE)); qp->size = size; qp->head = qp->tail = qp->num = 0; //初始化队列的头、尾、元素个数都为0 qp->array = (Node**)util_malloc(size * sizeof (Node*)); return qp; } // 入队列 int QUEUEenqueue(QUEUE* qp, Node* data) { if (qp == NULL || qp->num >= qp->size) // qp未初始化或已满 { return 0; //入队失败 } qp->array[qp->tail] = data; // 入队,tail一直指向最后一个元素的下一个位置 qp->tail = (qp->tail + 1) % (qp->size); // 循环队列 ++qp->num; return 1; } // 出队列 int QUEUEdequeue(QUEUE* qp, Node** data_ptr) { if (qp == NULL || qp->num <= 0) // qp未初始化或队列内无元素 { return 0; } *data_ptr = qp->array[qp->head]; // 出队 qp->head = (qp->head + 1) % (qp->size); // 循环队列 --qp->num; return 1; } // 检测队列是否为空 int QUEUEempty(QUEUE* qp) { if (qp == NULL || qp->num <= 0) { return 1; } return 0; } // 销毁队列 void QUEUEdestroy(QUEUE* qp) { free(qp->array); free(qp); } // 以上是队列的有关操作实现 //创建元素 element* createElement() { element* temp = (element*)util_malloc(sizeof(element)); printf("请输入姓名和职业:\r\n"); temp->name = (char*)util_malloc(M); temp->post = (char*)util_malloc(M); scanf("%s %s",temp->name,temp->post); return temp; } //创建新结点 Node* createNode() { Node* temp = (Node*)util_malloc(sizeof(Node)); temp->childNum = 0; temp->level = 0; temp->firstChild = temp->parent = temp->nextSibling = temp->prevSibling = NULL; temp->item = createElement(); return temp; } //通过姓名查找结点元素 Node* searchNodeByName(char* name,Node* tree)//采用二叉树层序遍历的算法 { Node* head = tree; Node* result = NULL; QUEUE* que = QUEUEinit(M); QUEUEenqueue(que,head); while(QUEUEempty(que)==0&&result == NULL) { Node* temp; QUEUEdequeue(que,&temp); // &代表取地址 if (strcmp(name,temp->item->name) == 0) { result = temp; } else { temp = temp->firstChild; while(temp != NULL) { QUEUEenqueue(que,temp); temp = temp->nextSibling; } } } /* if (tree!=NULL) { if (strcmp(name,tree->item->name) == 0) { temp = tree; } else { while(temp!=NULL&&tree->nextSibling!=NULL){ temp = searchNodeByName(name,tree->firstChild); } } } */ return result; } //插入节点 void insertNode(Node* tree) { printf(" 请输入双亲的名字:\r\n"); char* parentName = (char*)util_malloc(M); scanf("%s",parentName); Node* parent = searchNodeByName(parentName,tree); if (parent!=NULL) { printf("找到双亲姓名:%s 职位:%s",parent->item->name,parent->item->post); Node* child = createNode(); child->parent = parent; if (parent->firstChild == NULL) { parent->firstChild = child; } else { Node* lastChild = parent->firstChild; while(lastChild->nextSibling!=NULL) { lastChild = lastChild->nextSibling; } lastChild->nextSibling = child; child->prevSibling = lastChild; } printf("插入成功\r\n"); } else { printf("没有找到双亲\r\n"); system("pause"); } free(parentName); } //释放结点所占空间 void FreeNode(Node* Node) { free(Node->item->name); free(Node->item->post); free(Node->item); free(Node->firstChild); free(Node->parent); free(Node->nextSibling); free(Node); } //倒叙层次遍历, 从右往左,从孩子到父亲 void ReverseTraversal(Node* node,void (*func)(Node*)) { STACK* stack = STACKinit(M); Node *temp = node; STACKpush(stack,temp); if (temp!=NULL) { if (temp->firstChild == NULL&&temp->nextSibling == NULL) { func(temp); } else { temp = temp->firstChild; while (temp!=NULL) { STACKpush(stack,temp); temp = temp->nextSibling; } while(STACKempty(stack) == 0) { Node* pop; STACKpop(stack,&pop); ReverseTraversal(pop,func); } } } } //层次遍历 void OrderTraversal(Node* node,void (*func)(Node*)) { QUEUE* que = QUEUEinit(M); Node* head = node; QUEUEenqueue(que,head); while(QUEUEempty(que) == 0) { Node* deque; QUEUEdequeue(que,&deque); func(deque); deque = deque->firstChild; while(deque) { QUEUEenqueue(que,deque); deque = deque->nextSibling; } } } void delNode(Node* tree) { printf("请输入要删除的姓名\r\n"); char * name = (char*)util_malloc(M); scanf("%s",name); Node* temp = searchNodeByName(name,tree); if(temp->nextSibling!=NULL&&temp->prevSibling!=NULL){ temp->prevSibling->nextSibling = temp->nextSibling; temp->nextSibling->prevSibling = temp->prevSibling; } else if(temp->prevSibling==NULL&&temp->nextSibling!=NULL){ temp->parent->firstChild = temp->nextSibling; temp->nextSibling->prevSibling = NULL; } else if(temp->prevSibling!=NULL&&temp->nextSibling == NULL){ temp->prevSibling->nextSibling == NULL; } else if(temp->prevSibling==NULL&&temp->nextSibling==NULL) { temp->parent->firstChild = NULL; } ReverseTraversal(temp,FreeNode); printf("删除成功\r\n"); free(name); } void printNode(Node* node) { printf("%5s",node->item->name); } int count(Node* tree) { int result = 0; QUEUE* que = QUEUEinit(M); Node* head = tree; QUEUEenqueue(que,head); while(QUEUEempty(que) == 0) { Node* deque; QUEUEdequeue(que,&deque); result ++; deque = deque->firstChild; while(deque) { QUEUEenqueue(que,deque); deque = deque->nextSibling; } } return result; } void search(Node* tree){ printf("请输入节点的名字:\r\n"); char* parentName = (char*)util_malloc(M); scanf("%s",parentName); Node* parent = searchNodeByName(parentName,tree); if (parent!=NULL) { printf("找到节点姓名:%s 职位:%s\n",parent->item->name,parent->item->post); } else { printf("查无此人!\r\n"); } } void modify(Node* tree) { printf("请输入要修改的姓名\r\n"); char * name = (char*)util_malloc(M); scanf("%s",name); Node* temp = searchNodeByName(name,tree); printf("请输入姓名和职业:\r\n"); scanf("%s %s",temp->item->name,temp->item->post); printf("修改成功\r\n"); } void searchSiblings(Node* node){ printf("请输入要查找同辈的姓名\r\n"); char * name = (char*)util_malloc(M); scanf("%s",name); Node* temp = searchNodeByName(name,node); Node* parent = temp->parent; Node* siblings = parent->firstChild; if (siblings!=NULL) { printf("和你同辈的人有:"); while(siblings!=NULL){ printf("%2s",siblings->item->name); siblings = siblings->nextSibling; } } else { printf("没有找到同辈\r\n"); } } void getParent(Node* node){ printf("请输入节点的名字:\r\n"); char* parentName = (char*)util_malloc(M); scanf("%s",parentName); Node* parent = searchNodeByName(parentName,node); parent = parent->parent; if (parent!=NULL) { printf("找到祖先姓名:%s 职位:%s",parent->item->name,parent->item->post); } else { printf("查无此人!\r\n"); } } void statistical(Node* tree){ printf("请输入要查找的职业\r\n"); char *post = (char *)util_malloc(M); scanf("%s",post); int result = 0; QUEUE* que = QUEUEinit(M); Node* head = tree; QUEUEenqueue(que,head); while(QUEUEempty(que) == 0){ Node* deque; QUEUEdequeue(que,&deque); if (strcmp(post,deque->item->post) == 0) { result++; } deque = deque->firstChild; while(deque){ QUEUEenqueue(que,deque); deque = deque->nextSibling; } } printf("从事%s的人数共%d",post,result); } //主函数 int main() { printf("请创建一份您的简易家谱系统\r\n"); Node* tree = createNode(); printf("家谱初始化成功\r\n"); system("pause"); for(;;) { system("cls"); printf("请选择所需要的功能\r\n"); printf("1.添加子孙\r\n"); printf("2.修改信息\r\n"); printf("3.删除信息\r\n"); printf("4.查询信息\r\n"); printf("5.族谱中集合\r\n"); printf("6.查找同辈\r\n"); printf("7.查询上一辈\r\n"); printf("8.统计总人数\r\n"); printf("9.统计从事某一种职业的人数\r\n"); int option = 0; scanf("%d",&option); system("cls"); switch (option) { case 1: insertNode(tree); system("pause"); break; case 2: modify(tree); system("pause"); break; case 3: delNode(tree); system("pause"); break; case 4: search(tree); system("pause"); break; case 5: OrderTraversal(tree,&printNode); system("pause"); break; case 6: searchSiblings(tree); system("pause"); break; case 7: getParent(tree); system("pause"); break; case 8: printf("族谱中总人数%d",count(tree)); system("pause"); break; case 9: statistical(tree); system("pause"); break; default: printf("暂时没有此功能\r\n"); system("pause"); } } return 0; }
C++初学问题!!求讲解
新手,我写了一个职工管理系统,没有语法错误。但运行不了,应该是类和链表有问题,但我太菜,不知道怎么解决,求大神帮忙。 以下是我的程序(因为有格式问题,可能略乱,跪求忽视) #include "stdafx.h" #include <iostream> #include <fstream> #include <process.h> #include <cstring> #include <conio.h> using namespace std; void MainMenuControl(); int MainMenu(); class CStaff { public: CStaff( char *id, char *name, char *birth, char *depart, char *title, char *rank, float tel, char sex= 'M' ) { strcpy(this->id,id); strcpy(this->name,name); strcpy(this->birth,birth); strcpy(this->depart,depart); strcpy(this->title,title); strcpy(this->rank,rank); this->tel= tel; this->sex= sex; } friend class CStaffList; void ShowInfo() { cout<<"**工号"<<"\t"<<"姓名"<<"\t"<<"性别"<<"\t"<<"出生年月"<<"\t" <<"部门"<<"\t"<<"职称"<<"\t"<<"工资级别"<<"\t"<<"电话**"<<endl; cout<<"**"<<this->id<<"\t"<<this->name<<"\t"<<( this->sex == 'M'?"男":"女" )<<"\t"<<this->birth<<"\t" <<this->depart<<"\t"<<this->title<<"\t"<<this->rank<<"\t"<<this->tel<<"**"<<endl; } private: char id[10]; char name[15]; char sex; char birth[10]; char depart[10]; char title[10]; char rank[10]; float tel; CStaff *next; }; class CStaffList { private: CStaff *Staff; CStaff *p; void Clear() { CStaff *pt= Staff; while(pt) { Staff= pt->next; delete pt; pt= Staff; } }//重新载入的时候清除原内存 public: CStaffList() { Staff= 0; Load(); } ~CStaffList() { CStaff *pt; pt= Staff; while(pt) { pt= pt->next; delete Staff; Staff= pt; } Staff= 0; } void Add();//录入 void modify();//链接编辑和检索函数 void Modify();//修改 void Browsing();//显示到屏幕上 void Save(); //数据存盘 void Load(); //数据装入 void Retrieval();//检索 }; int main() { MainMenuControl(); return 0; } int MainMenu() { cout<<"********************************************************************************"<<endl; cout<<"** 职工档案管理系统 **"<<endl; cout<<"********************************************************************************"<<endl; cout<<"** **"<<endl; cout<<"** 信息浏览.......Information Browsing...1 **"<<endl; cout<<"** 信息检索.......Information Retrieval..2 **"<<endl; cout<<"** 添加职工信息...Add Staff Information..3 **"<<endl; cout<<"** 职工信息编辑...Information Modify.....4 **"<<endl; cout<<"** 数据导入.......Load Information ......5 **"<<endl; cout<<"** 数据保存.......Save Information.......6 **"<<endl; cout<<"** 退出...........Exit...................0 **"<<endl; cout<<" 请输入项目号进入应用:"; int choice; cin>>choice; return choice; } void MainMenuControl() { while(1) { int choice= MainMenu(); CStaffList s1; switch(choice) { case 1: s1.Browsing(); break; case 2: s1.Retrieval();break; case 3: s1.Add(); break; case 4: s1.modify(); break; case 5: s1.Load(); break; case 6: s1.Save(); break; case 0: cout<<"*************************系统退出,欢迎下次使用*********************************"<<endl; exit(0); default: break; } system("cls"); } } void CStaffList::Load()//数据装入 { char id[10]; char name[15]; char sex; char birth[10]; char depart[10]; char title[10]; char rank[10]; float tel; fstream file; file.open("staff_file.txt",ios::in); if(!file) { cout<<"** 不能打开文件文件:staff_file.txt!! **"<<endl; exit(1); } file>>id>>name>>sex>>birth>>depart>>title>>rank>>tel;//预读第一行(项目名称),不录入 CStaffList::Clear(); CStaff *p1,*p0;//p1用于创建新的内存空间的,p0用于找到尾地址,链接作用 file>>id>>name>>sex>>birth>>depart>>title>>rank>>tel;//录入第二行 获得首地址 p1= new CStaff( id, name, birth, depart, title, rank, tel, sex ); p0= Staff= p1; while( !file.eof())//从第三行开始循环录入 { file>>id>>name>>sex>>birth>>depart>>title>>rank>>tel; p1= new CStaff( id, name, birth, depart, title, rank, tel, sex ); p0->next= p1; p0= p0->next; } p0= NULL; file.close(); } void CStaffList::Save() { CStaff *p1; fstream file; file.open("staff_file.txt",ios::trunc); if(!file) { cout<<"** 不能打开文件文件:staff_file.txt!! **"<<endl; exit(1); } if(Staff) { file<<"工号"<<"\t"<<"姓名"<<"\t"<<"性别"<<"\t"<<"出生年月"<<"\t" <<"部门"<<"\t"<<"职称"<<"\t"<<"工资级别"<<"\t"<<"电话"<<"\n"; for( p1= Staff; p1 != NULL; p1= p1->next ) file<<p1->id<<"\t"<<p1->name<<"\t"<<( p1->sex == 'M'?"男":"女" )<<"\t"<<p1->birth<<"\t" <<p1->depart<<"\t"<<p1->title<<"\t"<<p1->rank<<"\t"<<p1->tel<<"\n"; } else { cout<<"** 无成员,请添加:staff_file.txt!! **"<<endl; return; } file.close(); //返回主菜单 cout<<"** 按任意键返回主菜单 **"<<endl; char ch; ch= getch(); return; } void CStaffList::Add() { CStaff *p1; char id[10]; cout<<">> 工号:"; cin>>id; char name[15]; cout<<">> 姓名:"; cin>>name; char sex; cout<<">> 性别(M/W):"; cin>>sex; char birth[10]; cout<<">> 生日(1970.1.1):";cin>>birth; char depart[10];cout<<">> 部门:"; cin>>depart; char title[10]; cout<<">> 职称:"; cin>>title; char rank[10]; cout<<">> 工资级别:"; cin>>rank; float tel; cout<<">> 电话:"; cin>>tel; p1= new CStaff( id, name, birth, depart, title, rank, tel, sex ); p1->next= 0; if(Staff) { CStaff *p0; for( p0= Staff; p0->next!= NULL; p0= p0->next ); p0->next= p1; } else { Staff= p1; } //链接到save函数进行保存和文件数据同步 cout<<"** 请按『s』键进行保存 **"<<endl; char c; cin>>c; while(1) { if( c== 's'||'S' ) { CStaffList::Save();return; } else { cout<<" 输入有误,重新输入:"; cin>>c; } } } void CStaffList::Retrieval() { while(1) { cout<<"** 请选择查找方式 **"<<endl; cout<<"** 1. 按工号进行搜索 Search by ID **"<<endl; cout<<"** 2. 按姓名进行搜素 Search by Name **"<<endl; cout<<"** 0. 返回主菜单 Return MainMenu **"<<endl; int choice; cin>>choice; CStaff *p1; p1= Staff; char c; switch(choice) { case 1: //按id筛选查找结点 char id[10]; cin>>id; for( ; p1 != NULL; p1= p1->next ) if( strcmp( p1->id,id) == 0 ) break; if( p1 == NULL ) { cout<<"** 您所查找的用户不存在 **"<<endl;break; } else { cout<<"** 你所查找的信息如下: **"<<endl; p1->ShowInfo(); } //在检索的基础上进行编辑操作 cout<<" 是否对该用户进行编辑?Y/N"<<endl; cin>>c; while(1) { if( c == 'y'||'Y') { p= p1; CStaffList::Modify(); } else if( c == 'n'||'N') break; else { cout<<" 输入有误,请重新输入:"; cin>>c; } } break; case 2: //按姓名找结点 char name[10]; cin>>name; for( ; p1 != NULL; p1= p1->next ) if( strcmp( p1->name,name) == 0 ) break; if( p1 == NULL ) { cout<<"** 您所查找的用户不存在 **"<<endl;break; } else p1->ShowInfo(); cout<<" 是否对该用户进行编辑?Y/N:"; cin>>c; while(1) { if( c == 'y'||'Y') { p= p1; CStaffList::Modify(); } else if( c == 'n'||'N') break; else { cout<<" 输入有误,请重新输入:"; cin>>c; } } break; case 0: return; } } } void CStaffList::modify()//没有实际作用,连接到检索菜单 { cout<<"** 1.检索所要编辑的职工 **"<<endl; cout<<"** 0. 返回主菜单 **"<<endl; int choice; while(1) { cout<<" 请输入您的选择:"; cin>>choice; switch(choice) { case 1: CStaffList::Retrieval(); case 0: return; default:cout<<"** 输入有误,请重新输入! **"<<endl; break; } } } void CStaffList::Modify() { while(1) { cout<<"** 请选择你所需要修改信息,请填序号: **"<<endl; cout<<"** 1. 工号 2.姓名 **"<<endl; cout<<"** 3. 性别 4.出生日期 **"<<endl; cout<<"** 5. 部门 6.职称 **"<<endl; cout<<"** 7. 工资级别 8.电话 **"<<endl; int choice; cin>>choice; switch(choice) { case 1: cout<<">> 工号:"; cin>>p->id; break; case 2: cout<<">> 姓名:"; cin>>p->name; break; case 3: cout<<">> 性别(M/W):"; cin>>p->sex; break; case 4: cout<<">> 出生年月(1970.1.1):";cin>>p->birth; break; case 5: cout<<">> 部门:"; cin>>p->depart;break; case 6: cout<<">> 职称:"; cin>>p->title; break; case 7: cout<<">> 工资等级:"; cin>>p->rank; break; case 8: cout<<">> 电话:"; cin>>p->tel; break; } cout<<"** 已修改,信息如下: **:"<<endl; p->ShowInfo(); char c; cin>>c; while(1) { cout<<" 是否保存并退出编辑?Y/N:"; if( c == 'y'||'Y' ) { CStaffList::Save();return; } else if( c == 'n'||'N' )break; else { cout<<"** 输入有误,请重新输入: **"; cin>>c; } } } p= Staff; } void CStaffList::Browsing() { CStaff *p1; cout<<"** 职工信息如下 **"<<endl; cout<<"**工号"<<"\t"<<"姓名"<<"\t"<<"性别"<<"\t"<<"出生年月"<<"\t" <<"部门"<<"\t"<<"职称"<<"\t"<<"工资级别"<<"\t"<<"电话**"<<endl; for( p1= Staff; p1!= NULL; p1= p1->next ) cout<<"**"<<p1->id<<"\t"<<p1->name<<"\t"<<(p1->sex=='M'?"男":"女")<<"\t"<<p1->birth<<"\t" <<p1->depart<<"\t"<<p1->title<<"\t"<<p1->rank<<"\t"<<p1->tel<<"**"<<endl; }
爬虫福利二 之 妹子图网MM批量下载
爬虫福利一:27报网MM批量下载    点击 看了本文,相信大家对爬虫一定会产生强烈的兴趣,激励自己去学习爬虫,在这里提前祝:大家学有所成! 目标网站:妹子图网 环境:Python3.x 相关第三方模块:requests、beautifulsoup4 Re:各位在测试时只需要将代码里的变量 path 指定为你当前系统要保存的路径,使用 python xxx.py 或IDE运行即可。
字节跳动视频编解码面经
三四月份投了字节跳动的实习(图形图像岗位),然后hr打电话过来问了一下会不会opengl,c++,shador,当时只会一点c++,其他两个都不会,也就直接被拒了。 七月初内推了字节跳动的提前批,因为内推没有具体的岗位,hr又打电话问要不要考虑一下图形图像岗,我说实习投过这个岗位不合适,不会opengl和shador,然后hr就说秋招更看重基础。我当时想着能进去就不错了,管他哪个岗呢,就同意了面试...
开源一个功能完整的SpringBoot项目框架
福利来了,给大家带来一个福利。 最近想了解一下有关Spring Boot的开源项目,看了很多开源的框架,大多是一些demo或者是一个未成形的项目,基本功能都不完整,尤其是用户权限和菜单方面几乎没有完整的。 想到我之前做的框架,里面通用模块有:用户模块,权限模块,菜单模块,功能模块也齐全了,每一个功能都是完整的。 打算把这个框架分享出来,供大家使用和学习。 为什么用框架? 框架可以学习整体...
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它是一个过程,是一个不断累积、不断沉淀、不断总结、善于传达自己的个人见解以及乐于分享的过程。
Spring Boot2 系列教程(十七)SpringBoot 整合 Swagger2
前后端分离后,维护接口文档基本上是必不可少的工作。 一个理想的状态是设计好后,接口文档发给前端和后端,大伙按照既定的规则各自开发,开发好了对接上了就可以上线了。当然这是一种非常理想的状态,实际开发中却很少遇到这样的情况,接口总是在不断的变化之中,有变化就要去维护,做过的小伙伴都知道这件事有多么头大!还好,有一些工具可以减轻我们的工作量,Swagger2 就是其中之一,至于其他类似功能但是却收费的软...
Python 基础(一):入门必备知识
目录1 标识符2 关键字3 引号4 编码5 输入输出6 缩进7 多行8 注释9 数据类型10 运算符10.1 常用运算符10.2 运算符优先级 1 标识符 标识符是编程时使用的名字,用于给变量、函数、语句块等命名,Python 中标识符由字母、数字、下划线组成,不能以数字开头,区分大小写。 以下划线开头的标识符有特殊含义,单下划线开头的标识符,如:_xxx ,表示不能直接访问的类属性,需通过类提供
天天学JAVA-JAVA基础(6)
如果觉得我写的还行,请关注我的博客并且点个赞哟。本文主要介绍JAVA 中最常使用字符串常量String相关知识。 1.String简介 2.创建字符串对象两种方式的区别 3.String常用的方法 4.String的不可变性 5.一道阿里面试题,你会做吗? 1.String简介 1.1String源码 首先看一段String源码,String主要实现了Serializable、Compar...
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发
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匹
2020 网络课 智慧树自动刷课代码,自动跳转,自动答题并关闭弹窗,自动1.5倍速静音
刷课一时爽,一直刷课一直爽! 终于让我找到了这个黑客代码了,教程开始: 只限谷歌浏览器和火狐浏览器使用,如果第一次失败,请重新试一下次 将下面代码复制后,进入浏览器按F12键,先点击console 然后Ctrl+v复制代码 最后按回车键即可 var ti = $("body"); var video = $(".catalogue_ul1 li[id*=video-]"); var i = 1;...
面试官:你连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
致 Python 初学者
文章目录1. 前言2. 明确学习目标,不急于求成,不好高骛远3. 在开始学习 Python 之前,你需要做一些准备2.1 Python 的各种发行版2.2 安装 Python2.3 选择一款趁手的开发工具3. 习惯使用IDLE,这是学习python最好的方式4. 严格遵从编码规范5. 代码的运行、调试5. 模块管理5.1 同时安装了py2/py35.2 使用Anaconda,或者通过IDE来安装模
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,
程序员:我终于知道post和get的区别
IT界知名的程序员曾说:对于那些月薪三万以下,自称IT工程师的码农们,其实我们从来没有把他们归为我们IT工程师的队伍。他们虽然总是以IT工程师自居,但只是他们一厢情愿罢了。 此话一出,不知激起了多少(码农)程序员的愤怒,却又无可奈何,于是码农问程序员。 码农:你知道get和post请求到底有什么区别? 程序员:你看这篇就知道了。 码农:你月薪三万了? 程序员:嗯。 码农:你是怎么做到的? 程序员:
羞,Java 字符串拼接竟然有这么多姿势
二哥,我今年大二,看你分享的《阿里巴巴 Java 开发手册》上有一段内容说:“循环体内,拼接字符串最好使用 StringBuilder 的 append 方法,而不是 + 号操作符。”到底为什么啊,我平常一直就用的‘+’号操作符啊!二哥有空的时候能否写一篇文章分析一下呢? 就在昨天,一位叫小菜的读者微信我说了上面这段话。 我当时看到这条微信的第一感觉是:小菜你也太菜了吧,这都不知道为啥啊!我估...
写1行代码影响1000000000人,这是个什么项目?
不带钱不带卡,只带手机出门就能畅行无阻,这已是生活的常态。益普索发布的《2019第一季度第三方移动支付用户研究》报告显示,移动支付在手机网民中的渗透率高达95.1%,截至今年1月,支付宝全球用户数已经突破10亿。你或许每天都会打开支付宝,付款购物、领取权益、享受服务……但你或许不知道的是,在这个方便、快捷、智能化的APP背后,有一群年轻的技术人,用智慧和创新让它每天都变得更“聪明”一点。 ...
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU
程序员把地府后台管理系统做出来了,还有3.0版本!12月7号最新消息:已在开发中有github地址
第一幕:缘起 听说阎王爷要做个生死簿后台管理系统,我们派去了一个程序员…… 996程序员做的梦: 第一场:团队招募 为了应对地府管理危机,阎王打算找“人”开发一套地府后台管理系统,于是就在地府总经办群中发了项目需求。 话说还是中国电信的信号好,地府都是满格,哈哈!!! 经常会有外行朋友问:看某网站做的不错,功能也简单,你帮忙做一下? 而这次,面对这样的需求,这个程序员
网易云6亿用户音乐推荐算法
网易云音乐是音乐爱好者的集聚地,云音乐推荐系统致力于通过 AI 算法的落地,实现用户千人千面的个性化推荐,为用户带来不一样的听歌体验。 本次分享重点介绍 AI 算法在音乐推荐中的应用实践,以及在算法落地过程中遇到的挑战和解决方案。 将从如下两个部分展开: AI 算法在音乐推荐中的应用 音乐场景下的 AI 思考 从 2013 年 4 月正式上线至今,网易云音乐平台持续提供着:乐屏社区、UGC
一点一滴记录 Java 8 stream 的使用
日常用到,一点一滴记录,不断丰富,知识积累,塑造自身价值。欢迎收藏 String 转 List String str = 1,2,3,4; List&lt;Long&gt; lists = Arrays.stream(str.split(",")).map(s -&gt; Long.parseLong(s.trim())).collect(Collectors.toList()); Lis...
8年经验面试官详解 Java 面试秘诀
    作者 | 胡书敏 责编 | 刘静 出品 | CSDN(ID:CSDNnews) 本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三百位候选人。在本文里,就将结合本人的面试经验,针对Java初学者、Java初级开发和Java开发,给出若干准备简历和准备面试的建议。   Java程序员准备和投递简历的实
面试官如何考察你的思维方式?
1.两种思维方式在求职面试中,经常会考察这种问题:北京有多少量特斯拉汽车? 某胡同口的煎饼摊一年能卖出多少个煎饼? 深圳有多少个产品经理? 一辆公交车里能装下多少个乒乓球? 一
碎片化的时代,如何学习
今天周末,和大家聊聊学习这件事情。 在如今这个社会,我们的时间被各类 APP 撕的粉碎。 刷知乎、刷微博、刷朋友圈; 看论坛、看博客、看公号; 等等形形色色的信息和知识获取方式一个都不错过。 貌似学了很多,但是却感觉没什么用。 要解决上面这些问题,首先要分清楚一点,什么是信息,什么是知识。 那什么是信息呢? 你一切听到的、看到的,都是信息,比如微博上的明星出轨、微信中的表情大战、抖音上的段子
so easy! 10行代码写个"狗屁不通"文章生成器
前几天,GitHub 有个开源项目特别火,只要输入标题就可以生成一篇长长的文章。 背后实现代码一定很复杂吧,里面一定有很多高深莫测的机器学习等复杂算法 不过,当我看了源代码之后 这程序不到50行 尽管我有多年的Python经验,但我竟然一时也没有看懂 当然啦,原作者也说了,这个代码也是在无聊中诞生的,平时撸码是不写中文变量名的, 中文...
知乎高赞:中国有什么拿得出手的开源软件产品?(整理自本人原创回答)
知乎高赞:中国有什么拿得出手的开源软件产品? 在知乎上,有个问题问“中国有什么拿得出手的开源软件产品(在 GitHub 等社区受欢迎度较好的)?” 事实上,还不少呢~ 本人于2019.7.6进行了较为全面的回答,对这些受欢迎的 Github 开源项目分类整理如下: 分布式计算、云平台相关工具类 1.SkyWalking,作者吴晟、刘浩杨 等等 仓库地址: apache/skywalking 更...
基础拾遗:除了&和&&的区别,你还要知道位运算的这5个运算符
&和&&都可作逻辑与的运算符,表示逻辑与(and),&是位运算符,你还需要知道这5个位运算符,基础很重要,云运算其实很骚!
MySQL数据库总结
一、数据库简介 数据库(Database,DB)是按照数据结构来组织,存储和管理数据的仓库。 典型特征:数据的结构化、数据间的共享、减少数据的冗余度,数据的独立性。 关系型数据库:使用关系模型把数据组织到数据表(table)中。现实世界可以用数据来描述。 主流的关系型数据库产品:Oracle(Oracle)、DB2(IBM)、SQL Server(MS)、MySQL(Oracle)。 数据表:数...
记一次腾讯面试:进程之间究竟有哪些通信方式?如何通信? ---- 告别死记硬背
有一次面试的时候,被问到进程之间有哪些通信方式,不过由于之前没深入思考且整理过,说的并不好。想必大家也都知道进程有哪些通信方式,可是我猜很多人都是靠着”背“来记忆的,所以今天的这篇文章,讲给大家详细着讲解他们是如何通信的,让大家尽量能够理解他们之间的区别、优缺点等,这样的话,以后面试官让你举例子,你也能够顺手拈来。 1、管道 我们来看一条 Linux 的语句 netstat -tulnp | gr...
20行Python代码爬取王者荣耀全英雄皮肤
引言 王者荣耀大家都玩过吧,没玩过的也应该听说过,作为时下最火的手机MOBA游戏,咳咳,好像跑题了。我们今天的重点是爬取王者荣耀所有英雄的所有皮肤,而且仅仅使用20行Python代码即可完成。 准备工作 爬取皮肤本身并不难,难点在于分析,我们首先得得到皮肤图片的url地址,话不多说,我们马上来到王者荣耀的官网: 我们点击英雄资料,然后随意地选择一位英雄,接着F12打开调试台,找到英雄原皮肤的图片...
张小龙-年薪近3亿的微信之父,他是如何做到的?
张小龙生于湖南邵东魏家桥镇, 家庭主要特点:穷。 不仅自己穷,亲戚也都很穷,可以说穷以类聚。爷爷做过铜匠,总的来说,标准的劳动阶级出身。 家有兄弟两人, 一个小龙,一个小虎。 小虎好动,与邻里打成一片, 小龙好静,喜好读书。 “文静的像个妹子。”张小龙的表哥如是说。 穷文富武,做个读书郎是个不错的选择。 87年至94年, 华中科技大学本硕连读。 本科就读电信系, 不喜欢上课...
阿里靠什么武功秘籍渡过“双十一“的天量冲击
双十一大概会产生多大的数据量呢,可能大家没概念,举个例子央视拍了这么多年电视新闻节目,几十年下来他存了大概80P的数据。而今年双11一天,阿里要处理970P的数据,做为一个IT人,笔者认为今年”双十一“阿里最大的技术看点有有以下两个: 阿里的数据库,也就是刚刚拿下TPC冠军的OcceanBase,处理峰值也达到了骇人听闻的6100万次/秒, 阿里核心系统百分百上云了。 如果把信息系统比做一个武...
西游记团队中如果需要裁掉一个人,会先裁掉谁?
2019年互联网寒冬,大批企业开始裁员,下图是网上流传的一张截图: 裁员不可避免,那如何才能做到不管大环境如何变化,自身不受影响呢? 我们先来看一个有意思的故事,如果西游记取经团队需要裁员一名,会裁掉谁呢,为什么? 西游记团队组成: 1.唐僧 作为团队teamleader,有很坚韧的品性和极高的原则性,不达目的不罢休,遇到任何问题,都没有退缩过,又很得上司支持和赏识(直接得到唐太宗的任命,既给袈...
相关热词 c#处理浮点数 c# 生成字母数字随机数 c# 动态曲线 控件 c# oracle 开发 c#选择字体大小的控件 c# usb 批量传输 c#10进制转8进制 c#转base64 c# 科学计算 c#下拉列表获取串口
立即提问