C++ 数组指针问题,删除指针出错

比如下面这样:

 int*  P = new int [10];
//然后我想通过指针删除中间节点
int * q = &p[2];
delete q;

编译器报错:_BLOCK_TYPE_IS_VALID
我想请问一下为什么会出错呢?

5个回答

delete q不能这么写
只能整体释放P

要不然你用链表

Fukui_YB_yb
Fukui_YB_yb 谢谢
大约 3 年之前 回复
caozhy
贵阳老马马善福专业维修游泳池堵漏防水工程 回复Fukui_YB_yb: 是的
大约 3 年之前 回复
Fukui_YB_yb
Fukui_YB_yb 是因为p是分配的连续空间所以不能单独删除p【1】吗?
大约 3 年之前 回复

delete q不能这么写
只能整体释放P

要不然你用链表

是因为p是分配的连续空间所以不能单独删除p【1】吗?

这编译器好。VS都编译不报警,运行时出错

这数组的操作权限由p所占有,p[2]的地址权限也属于p,只能通过p进行操作,q应该是不存在这种权限。随便说说不知道对不对,哈哈。

 int main()
{
    int*  P = new int [10];
    //然后我想通过指针删除中间节点
    int * q = &P[2];

    delete P;

    return 0;
}

new 谁,delete 谁。。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
C++ 数组指针问题,删除指针出错
比如下面这样: ``` int* P = new int [10]; //然后我想通过指针删除中间节点 int * q = &p[2]; delete q; ``` 编译器报错:_BLOCK_TYPE_IS_VALID 我想请问一下为什么会出错呢?
C++链表头指针位置不知为什么出错
希望实现第一行输入n和m,后面共输入n+m行 后面有n行由四个数字组成,第一个为1,表示创建新的结点,第二个为此 结点的数据域,第三个为某个结点的数据域(如果为-1则表示此为第一个 创建的结点),第四个为0或者1,若为0表示新结点 建立在第三个数字代表的结点的左边,若为1则表示在右边。 后面有m行由2个数字组成,第一个为0,表示删除结点,第二个为需要删除 的结点的数据域。 最终把最后的链表打印出来,并在末尾加-1表示输出结束。 代码如下: #include<iostream> #include<conio.h> using namespace std; typedef struct node //同学结点 { int data; //同学编号 struct node *next; //结点指针,指向下一个 }NODE; class list { private: NODE *head; int length; public: list(){head=NULL;length=0;} ~list(){} int find(int i) { NODE *p=head; int j=1; //元素地址,第一位标记为第1位 while(p&&p->data!=i&&p&&p!=NULL) { p=p->next; j++; } if(p==NULL)return 0; //未找到返回0 return j; } int Insert(int i,int x,int k) { NODE *p=head, *s; int j=0; int location=find(x); if(location==0) { s=(NODE *)new NODE[1]; s->data=i; s->next=p; head=s; length++; return 1; } if(k==0) //插入左边 { while(p&&j<location-2){p=p->next;j++;} if(!p)return 0; s=(NODE *)new NODE[1]; s->data=i; s->next=p->next; p->next=s; length++; return 1; } else if(k==1) //插入右边??? { while(p&&j<location-1){p=p->next;j++;} if(!p)return 0; s=(NODE *)new NODE[1]; s->data=i; s->next=p->next; p->next=s; length++; return 1; } return 0; } int Delete(int i) { NODE *p=head,*q; int j=0; int location=find(i); if(!p)return 0; if(location==1) { head=head->next; delete p; p=NULL; length--; return 1; } while(p->next&&j<i-1){p=p->next;j++;} if(!(p->next)||j>i-1)return 0; q=p->next; p->next=q->next; delete q; q=NULL; length--; return 1; } void setlength(int n,int m) { length=n-m; } void print() //打印函数 { NODE *p=head; for(int i=0;i<length&&p!=NULL&&p;i++) { cout<<p->data<<' '; p=p->next; } } }; int main() { list student; int m,n,a1,a2,a3,a4,a5; scanf("%d",&n); scanf("%d",&m); student.setlength(n,m); for(int i=0;i<n+m;i++) { scanf("%d",&a1); if(a1==1) { scanf("%d",&a2); scanf("%d",&a3); scanf("%d",&a4); student.Insert(a2,a3,a4); } if(a1==0) { scanf("%d",&a5); student.Delete(a5); } } student.print(); cout<<-1; return 0; } 结果指针的顺序倒是没问题,但是打印出来的结果 经常不是从头开始打印,请问这是为什么?
为什么在队尾插入元素时总是提示内存出错(C语言新人)
写了一个层序遍历创建二叉树的函数,但在入队列部分提示内存出错,求大佬指点... 出错函数:void EnQueue(BiTree e) 错误提示:内存出错 ``` #include<stdio.h> #include<stdlib.h> #define link 1; #define child 0; typedef struct BiTNode{ char data; struct BiTNode* lchild; struct BiTNode* rchild; int LTag = child; int RTag = child; }BiTNode,*BiTree; typedef struct QNode{ BiTNode* data; struct QNode* next; }QNode,*QueuePtr; typedef struct { QueuePtr front;//队头指针 QueuePtr rear;//队尾指针 }LinkQueue; LinkQueue Q;//用队列存储需要访问的树的结点 void IniiLinkQueue(){ Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode)); Q.front->next = NULL; return ; } bool QueueEmpty(){ //判断队列是否为空队列,若不是,返回true;否则,返回false if(Q.front == Q.rear) return false; return true; } void EnQueue(BiTree e){ //插入e为Q的新的队尾元素 QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); p->data = e; p->next = NULL; Q.rear->next = p;//报错位置 Q.rear = p; return ; } BiTree DeQueue(){ //删除Q的队头元素,并返回其值 BiTree e = Q.front->next->data; if(Q.front->next == Q.rear) Q.rear = Q.front; else Q.front->next = Q.front->next->next; return e; } void createBiTree(BiTree T){ //按层序遍历创建二叉树 char ch; EnQueue(T);//将树的根结点存入队列 while(QueueEmpty()){ while((ch = getchar()) != '\n'){ T = DeQueue(); if(ch != '-'){ //若输入字符不为'-',表示当前结点不为空,将字符存入结点,并将其左右孩子地址存入队列中 T->data = ch; T->lchild = (BiTree)malloc(sizeof(BiTNode)); T->rchild = (BiTree)malloc(sizeof(BiTNode)); EnQueue(T->lchild); EnQueue(T->rchild); } else{ //若输入字符为'-',表示当前结点为空,无需将其左右孩子入队 T->data = NULL; } } } return ; } ```
c语言图书管理系统设计,卡在查找时如果是找不到则程序出错,大神能帮我解决一下吗?
输入是成功,但是如果查找的不是已输入,则程序出错。 #include <stdio.h> #include <stdlib.h> #include <string.h> //定义一本书 struct book { char name[10]; char writer[10]; char publisher[21]; char price[5]; }; struct Node { //int data; struct book data; struct Node* next; }; //创建表 struct Node* createList() { //结构体变量表示表头 //指针--->变量 动态内存申请 struct Node* headNode = (struct Node*)malloc(sizeof(struct Node)); headNode->next = NULL; return headNode; } //创建结点 struct Node* createNode(struct book data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; return newNode; } //插入结点 void insertNodeByHead(struct Node* headNode, struct book data) { struct Node* newNode = createNode(data); //表头法 newNode->next = headNode->next; headNode->next = newNode; } //指定位置删除 void deleteAppoinNode(struct Node* headNode, char* name) { //struct book struct Node* posNode = headNode->next; struct Node* posFrontNode = headNode; if (posNode == NULL) { printf("数据为空,无法删除!\n"); return; } //书名是字符串,字符串:strcmp while (strcmp(posNode->data.name,name)) { posFrontNode = posNode; posNode = posFrontNode->next; if (posNode == NULL) { printf("未找到指定位置无法删除!\n"); return; } } //找到了 posFrontNode->next = posNode->next; free(posNode); } //查找功能 struct Node* searchInfoByData(struct Node* headNode, char *name) { struct Node* pMove = headNode->next; if (pMove == NULL) return NULL; while (strcmp(pMove->data.name, name)) { pMove = pMove->next; } return pMove; } //打印 void printList(struct Node* headNode) { struct Node* pMove = headNode->next; //设计到数据的处理 printf("书名\t作者\t出版社\t价格\n"); while (pMove) { printf("%s\t%s\t%s\t%s\n", pMove->data.name, pMove->data.writer, pMove->data.publisher, pMove->data.price); pMove = pMove->next; } printf("\n"); } void menu() { //所有操作都同步到文件 printf("-------------【图书信息管理系统】-----------\n"); printf("\t\t1.录入图书信息\n"); printf("\t\t2.浏览图书信息\n"); printf("\t\t3.修改图书信息\n"); printf("\t\t4.删除图书信息\n"); printf("\t\t5.查找图书信息\n"); printf("\t\t0.退出系统\n"); printf("-------------------------------------------\n"); } struct Node* list = createList(); //接收指令 void keyDown() { int choice = 0; struct book data; struct Node* pMove = NULL; scanf("%d", &choice); switch (choice) { case 0: printf("正常退出!\n"); system("pause"); exit(0); break; case 1: printf("--------------【录入图书信息】-----------\n"); //插入链表 printf("请输入书名,作者,出版社,价格:\n"); fflush(stdin); //清空缓冲区 scanf("%s%s%s%s", data.name, &data.writer, data.publisher, data.price); insertNodeByHead(list, data); break; case 2: printf("--------------【浏览图书信息】-----------\n"); printList(list); //打印链表 break; case 3: printf("--------------【修改图书信息】-----------\n"); printf("请输入要修改的书名:"); scanf("%s", data.name); pMove = searchInfoByData(list, data.name); if (pMove == NULL) { printf("未找到相关信息,无法修改!\n"); system("pause"); } else { printf("请输入图书名,作者,出版社,价格:"); scanf("%s%s%s%s", data.name, &data.writer, data.publisher, data.price); strcpy(pMove->data.name, data.name); strcpy(pMove->data.writer, data.writer); strcpy(pMove->data.publisher, data.publisher); strcpy(pMove->data.price, data.price); } break; case 4: printf("--------------【删除图书信息】-----------\n"); printf("请输入删除的书名:"); scanf("%s", data.name); deleteAppoinNode(list, data.name); break; case 5: printf("--------------【查找图书信息】-----------\n"); printf("请输入要查找的书名:"); scanf("%s", data.name); pMove = searchInfoByData(list, data.name); if (pMove == NULL) { printf("未找到相关信息,无法删除!\n"); system("pause"); } else { printf("书名\t作者\t出版社\t价格\n"); printf("%s\t%s\t%s\t%s\n", pMove->data.name, pMove->data.writer, pMove->data.publisher, pMove->data.price); } break; default: printf("选择错误,重新输入\n"); system("pause"); break; } } int main() { while (1) { menu(); keyDown(); system("pause"); system("cls"); } system("pause"); return 0; }
c语言 图书管理程序设计,当对图书信息进行修改时,如若未找到则程序出错
#include <stdio.h> #include <stdlib.h> #include <string.h> //定义一本书 struct book { char name[10]; char writer[10]; char publisher[21]; char price[5]; }; struct Node { //int data; struct book data; struct Node* next; }; //创建表 struct Node* createList() { //结构体变量表示表头 //指针--->变量 动态内存申请 struct Node* headNode = (struct Node*)malloc(sizeof(struct Node)); headNode->next = NULL; return headNode; } //创建结点 struct Node* createNode(struct book data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; return newNode; } //插入结点 void insertNodeByHead(struct Node* headNode, struct book data) { struct Node* newNode = createNode(data); //表头法 newNode->next = headNode->next; headNode->next = newNode; } //指定位置删除 void deleteAppoinNode(struct Node* headNode, char* name) { //struct book struct Node* posNode = headNode->next; struct Node* posFrontNode = headNode; if (posNode == NULL) { printf("数据为空,无法删除!\n"); return; } //书名是字符串,字符串:strcmp while (strcmp(posNode->data.name,name)) { posFrontNode = posNode; posNode = posFrontNode->next; if (posNode == NULL) { printf("未找到指定位置无法删除!\n"); return; } } //找到了 posFrontNode->next = posNode->next; free(posNode); } //查找功能 struct Node* searchInfoByData(struct Node* headNode, char *name) { struct Node* pMove = headNode->next; if (pMove == NULL) return NULL; while (strcmp(pMove->data.name, name)) { pMove = pMove->next; } return pMove; } //打印 void printList(struct Node* headNode) { struct Node* pMove = headNode->next; //设计到数据的处理 printf("书名\t作者\t出版社\t价格\n"); while (pMove) { printf("%s\t%s\t%s\t%s\n", pMove->data.name, pMove->data.writer, pMove->data.publisher, pMove->data.price); pMove = pMove->next; } printf("\n"); } void menu() { //所有操作都同步到文件 printf("-------------【图书信息管理系统】-----------\n"); printf("\t\t1.录入图书信息\n"); printf("\t\t2.浏览图书信息\n"); printf("\t\t3.修改图书信息\n"); printf("\t\t4.删除图书信息\n"); printf("\t\t5.查找图书信息\n"); printf("\t\t0.退出系统\n"); printf("-------------------------------------------\n"); } struct Node* list = createList(); //接收指令 void keyDown() { int choice = 0; struct book data; struct Node* pMove = NULL; scanf("%d", &choice); switch (choice) { case 0: printf("正常退出!\n"); system("pause"); exit(0); break; case 1: printf("--------------【录入图书信息】-----------\n"); //插入链表 printf("请输入书名,作者,出版社,价格:\n"); fflush(stdin); //清空缓冲区 scanf("%s%s%s%s", data.name, &data.writer, data.publisher, data.price); insertNodeByHead(list, data); break; case 2: printf("--------------【浏览图书信息】-----------\n"); printList(list); //打印链表 break; case 3: printf("--------------【修改图书信息】-----------\n"); printf("请输入要修改的书名:"); scanf("%s", data.name); pMove = searchInfoByData(list, data.name); if (pMove == NULL) { printf("未找到相关信息,无法修改!\n"); system("pause"); } else { printf("请输入图书名,作者,出版社,价格:"); scanf("%s%s%s%s", data.name, &data.writer, data.publisher, data.price); strcpy(pMove->data.name, data.name); strcpy(pMove->data.writer, data.writer); strcpy(pMove->data.publisher, data.publisher); strcpy(pMove->data.price, data.price); } break; case 4: printf("--------------【删除图书信息】-----------\n"); printf("请输入删除的书名:"); scanf("%s", data.name); deleteAppoinNode(list, data.name); break; case 5: printf("--------------【查找图书信息】-----------\n"); printf("请输入要查找的书名:"); scanf("%s", data.name); pMove = searchInfoByData(list, data.name); if (pMove == NULL) { printf("未找到相关信息,无法删除!\n"); system("pause"); } else { printf("书名\t作者\t出版社\t价格\n"); printf("%s\t%s\t%s\t%s\n", pMove->data.name, pMove->data.writer, pMove->data.publisher, pMove->data.price); } break; default: printf("选择错误,重新输入\n"); system("pause"); break; } } int main() { while (1) { menu(); keyDown(); system("pause"); system("cls"); } system("pause"); return 0; }
为什么我的插入、删除、计数出错,小白需要大神帮改下
#include<stdio.h> #include<stdlib.h> #define L sizeof(struct Linklist) struct Linklist { int date; struct Linklist *next;//定义了一个指向struct linklist类型数据的指针变量next,用来存放结点的地址。 }; struct Linklist *creat(); void print (struct Linklist ); void insert(struct Linklist ,int i,int x); void delet(struct Linklist ,int i); int GetElem(struct Linklist ,int i); int jishu(struct Linklist *head); struct Linklist *creat()//定义creat函数,指针类型,所以函数带回一个指针量 { printf("请输入链表数据:"); struct Linklist *head,*p,*p1; head=(struct Linklist*)malloc(L); head->next=NULL; head=p=p1=(struct Linklist*)malloc(L); scanf("%d",&p->date); int n=1; while(p->date!=0) { p=(struct Linklist*)malloc(L); scanf("%d",&p->date); p1->next=p; p1=p; n++; } p->next=NULL; return(head); } //建立链表 void print (struct Linklist *head)// struct Linklist *head是定义一个结构体指针变量head { struct Linklist *p; printf("链表数据为:"); p=head; while(p->date!=0) { printf("%d ",p->date); p=p->next; } printf("\n"); return; }//输出链表 void insert( struct Linklist *head,int i,int x) { int j=1; struct Linklist *p,*r; p=head; while(p&&j<i) { p=p->next; j++; } if(!p||j>i) printf("插入出错!"); r=(struct Linklist *)malloc(L); r->date=x; r->next=p->next; p->next=r; }//在第i个位置之前插入数据x void delet(struct Linklist *head,int i) { int j=1; struct Linklist *p,*r; p=head->next; while(p&&j<i-1) { p=p->next; j++; } if(!p||j>i-1) printf("删除出错!"); r=p->next; p->next=r->next; free(r); }//删除第i个位置上的数据 int GetElem(struct Linklist *head,int i) { int j=1,e; struct Linklist *p; p=head->next; while(p&&j<i-1) { p=p->next; j++; } if(!p||j>i) printf("查找出错!"); e=p->next->date; return(e); }//查找第i个位置上的数据是多少,并赋值给e int jishu(struct Linklist *head) { int n=0; struct Linklist *p; p=head; while(p->next!=NULL) { n++; p=p->next; n++; } return(n); }//计数,链表的个数 int main() { int m,n,k,h,e,o; struct Linklist *head; printf("请选择您要做的操作:\n1.建立链表\n2.输出链表\n3.给链表中插入数据\n4.删除链表中的数据\n5.查找链表中的数据\n6.链表中的数据计数\n\n"); head=creat(); print (head); printf("请输入插入的位置和插入的数据");//调用插入函数 scanf("%d,%d",&m,&n); insert(head, m, n); print(head); printf("\n"); printf("请输入要删除的数据的位置");//调用删除函数 scanf("%d",&k); delet( head, k); print(head); printf("\n"); printf("请输入要查找数据的位置");//调用查找函数 scanf("%d",&h); e=GetElem( head,h); printf("要查找的数据的位置在第%d个\n",&e); o=jishu( head); printf("链表中的数据有%d个\n",&o); return 0; }
(C++)小白来提问,程序出错。
#include <iostream> using namespace std; double capital = 0.0; double cal(int num, double quantity) { switch (num) { case 0: return quantity*1.50; case 1: return quantity*1.70; case 2: return quantity*4.60; case 3: return quantity*0.90; case 4: return quantity*2.50; case 5: return quantity*3.70; case 6: return quantity*7.60; case 7: return quantity*3.90; } } int main() { cout << "提示:本店提供8种水果,如下(左边为水果编号及名称,右边为其单价)" << endl; cout << "0西瓜 1.50,1木瓜 1.70,2哈密瓜 4.60,3苹果 0.9\n" << "4梨 2.50,5柚子 3.70,6猕猴桃 7.60,7山楂 3.90" << endl; int num_choice = 0; while (1) { int Y_N; cout << "请输入你你要购买的种类数量:"; cin >> num_choice; if (num_choice == 0) { cout << "您确定只是看看吗?要不买点吧?继续请按1,退出请按0" << endl; cin >> Y_N; if (Y_N == 0) { cout << "退出成功!" << endl; break; } else if (Y_N == 1) { } else cout << "不要捣乱,请按规定输入哦,亲" << endl; } else { cout << "种类编号分别为:"; int *choice = new int[num_choice]; double *quantity_choice = new double[num_choice]; for (int i = 0; i < num_choice; i++) cin >> choice[i]; cout << "请输入对应购买种类的重量:"; for (int i = 0; i < num_choice; i++) cin >> quantity_choice[i]; for (int j = 0; j < num_choice; j++) { capital += cal(choice[j], quantity_choice[j]); } cout << "继续购物吗?继续请按1,否则请按0,开始结算" << endl; cin >> Y_N; if (Y_N == 0) { cout << "开始结算,请付款:" << capital << "元" << endl; break; } else if (Y_N == 1) { } else cout << "猴子你又调皮了,按规定输入哦" << endl; } } delete[] choice; choice = NULL; delete[] quantity_choice; quantity_choice = NULL; system("pause"); return 0; } 以上是程序,请无视掉小白的system("pause") 以下是错误提示 error C2065: “choice”: 未声明的标识符 error C2541: “delete”: 不能删除不是指针的对象 error C2065: “choice”: 未声明的标识符 error C2065: “quantity_choice”: 未声明的标识符 error C2541: “delete”: 不能删除不是指针的对象 error C2065: “quantity_choice”: 未声明的标识符 应该是因为自己不熟悉int *XXXXX=new int[XXX]的用法,哪位大咖来给讲一下,谢谢了。
求解C++析构函数释放内存错误原因,头疼。
拜托看一下我这个矩阵类实现里的析构函数哪里错了,编译没问题,运行出错。 删掉析构函数就可以运行了,为什么呢? * #include<iostream> * using namespace std; * class CMatrix * { * public: * CMatrix(int, int); //构造函数 * void output(); //输出矩阵各元素 * CMatrix operator +(CMatrix &M2); //重载矩阵加运算 * CMatrix operator -(CMatrix &M2); //重载矩阵减运算 * friend istream & operator>>(istream &, CMatrix &); * friend ostream & operator<<(ostream &, CMatrix &); * ~CMatrix() * { * delete[] m_pData; * } * private: * int m_row; //矩阵行数 * int m_col; //矩阵列数 * double *m_pData; //使用指针指向矩阵各元素 * }; * //构造函数 * CMatrix::CMatrix(int r, int c) * { * m_row = r; * m_col = c; * m_pData = new double[r*c]; * for (int i = 0; i<m_row*m_col; i++) * m_pData[i] = 0; * } * //矩阵输出函数 * void CMatrix::output() * { * int j = 0; * for (int i = 0; i<m_row*m_col; i++) * { * cout << m_pData[i] << " "; * if ((i + 1) % m_col == 0) * cout << endl; * } * } * //重载矩阵相加运算 * CMatrix CMatrix::operator +(CMatrix &M2) * { * CMatrix M(m_row,m_col); * for (int i = 0; i<m_row*m_col; i++) * M.m_pData[i] = m_pData[i] + M2.m_pData[i]; * return M; * } * //重载矩阵相减运算 * CMatrix CMatrix::operator -(CMatrix &M2) * { * CMatrix M(this->m_row,this->m_col); * for (int i = 0; i<m_row*m_col; i++) * M.m_pData[i] = m_pData[i] - M2.m_pData[i]; * return M; * } * istream & operator>>(istream &input, CMatrix &c) * { * for (int i = 0; i < c.m_row*c.m_col; i++) * input >> c.m_pData[i]; * return input; * } * ostream & operator<<(ostream &output, CMatrix &c) * { * for (int i = 0; i < c.m_row*c.m_col; i++) * { * output << c.m_pData[i]; * if ((i + 1) % c.m_col == 0) * output << endl; * } * return output; * } * int main() * { * CMatrix M1(2, 2), M2(2, 2), M3(2, 2); * cin >> M1; * cout << M1; * cin >> M2; * cout << M2; * M3 = M1 + M2; * cout << M3; * M3 = M1 - M2; * cout << M3; * return 0; * }
c语言运行出错 是链表哪里出错了吗
![图片说明](https://img-ask.csdn.net/upload/201806/13/1528859680_335574.png) ![图片说明](https://img-ask.csdn.net/upload/201806/13/1528859695_89773.png) ![图片说明](https://img-ask.csdn.net/upload/201806/13/1528859715_415797.png) #include <stdio.h> #include <malloc.h> #include <string.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct NODE { char name[MAXSIZE]; int p_num; double p_price; char kind[MAXSIZE]; struct NODE *next; }node; //下面这部分是啥??? typedef struct { char name[MAXSIZE]; int p_num; double p_price; }str; #if 0 void create(node *head); /*创建货物 main 194line*/ void del(node *head); /*删除指定货物*/ void find(node *head) /*查找货物*/ void all_delete(node *head); /*清空全部货物*/ void change(node *head); /*修改货物信息*/ int display() /*菜单*/ #endif void create(node *head) /*创建货物 main 194line*/ { node *p; /*判断货物是否存在的指针变量*/ int i = 1; char name[MAXSIZE]; int p_num; double p_price; char kind[MAXSIZE]; printf("*****************请输入货物名称:************\n"); scanf("%s",name); //getchar(); p = head->next; while(p != NULL) { if(strcmp(p->name,name) == 0) { printf("*********货物已存在************\n"); p = NULL; i = 0; /* 货物已存在,不执行输入货物命令*/ } else { p = p->next; } } while( 1 == i) { node *q; printf("**************请输入货物单位价格:**************\n"); scanf("%lf",&p_price); printf("**************请输入货物数量:**************\n"); scanf("%d",&p_num); printf("*****************请输入货物所属类型:************\n"); scanf("%s",kind); q = (node*)malloc(sizeof(node)); if(NULL == q) { printf("error2\n"); } strcpy(q->name,name); //strcpy(q->p_num,p_num); q->p_num=p_num; q->p_price=p_price; strcpy(q->kind,kind); q->next = head->next; head->next = q; /*头插法*/ i = 0; } } //我的代码跟这个的区别:没有在函数内重新定义变量 然后使用strcpy这些赋值 void order(node *head,int len1) //给货物排序 { node *p; /*用来排序的变量*/ node *q; /*同上*/ p = head->next; while(len1 > 0) /*实现货物按字母排列*/ { while(p != NULL && p->next!= NULL) { char tempname[MAXSIZE]; /*相当于中间变量用来存储货物信息*/ int tempp_num; double tempp_price; char tempkind[MAXSIZE]; if(strcmp(p->name,p->next->name) > 0) { strcpy(tempname, p->next->name); tempp_price=p->next->p_price; tempp_num=p->next->p_num; strcpy(tempkind,p->next->kind); strcpy(p->next->name,p->name); p->next->p_price=p->p_price; p->next->p_num=p->p_num; strcpy(p->next->kind,tempkind); strcpy(p->name,tempname); p->p_price=tempp_price; p->p_num=tempp_num; strcpy(p->kind,tempkind); } else { p=p->next; } } len1--; } } void print(node *head) /*打印联系人的函数*/ { int i = 1; node *p; p = head->next; printf("现在货物为:\n"); printf("编号 名称 价格 数量 所属类型\n"); while(p != NULL) { printf("%d %s %.2lf %d %s\n", i,p->name,p->p_price,p->p_num,p->kind); p = p->next; i++; } } void del(node *head) /*删除指定货物函数*/ { node *p; node *q; q = head; p = q->next; char name[MAXSIZE]; printf("************请输入要删除的货物名称:*********\n"); scanf("%s",name); while((p != NULL) && (strcmp(p->name,name) != 0)) { q = p; p = p->next; } if(NULL == p) { printf("************未查找到***************\n"); } else { q->next = p->next; free(p); printf("***********删除成功****************\n"); } } void find(node *head) //查找货物 { node *p; char name[MAXSIZE]; printf("*******请输入要查找货物名称:**********\n"); scanf("%s",name); p = head->next; while(p != NULL && strcmp(p->name,name) != 0) { p = p->next;//为什么del函数里面还定义了一个指针q } if(NULL == p) { printf("********没有这个货物*********\n"); } else { printf(" 名称:%s\n 价格:%.2lf 数量:%d 所属类型:%s", p->name,p->p_price,p->p_num,p->kind); } } void all_delete(node *head) //清空全部货物 { while(head->next != NULL) { node *q; q = head->next; head->next = q->next; free(q); } if(NULL == head->next) { printf("*********清除所有货物成功*********\n"); } } void change(node *head) //修改货物信息 { node *p; char name[MAXSIZE]; double p_price; int p_num; char kind[MAXSIZE]; p = head->next; printf("请输入要修改的货物名称\n"); scanf("%s",name); while( p != NULL) { if(strcmp(p->name,name) == 0) { printf("请输入要修改的货物价格\n"); scanf("%lf",p_price); p->p_price=p_price; printf("修改成功\n"); break; } else { p = p->next; } } if(p == NULL) { printf("未查找到此联系人!\n"); } } int sum(node *head) //求链表中有多少货物 { int count_node = 0; node *p; p = head->next; if(p != NULL) { count_node++; p = p->next; } return count_node; } /*void write_to_file(node *head,int len) //链表中的货物信息写到文件 { int i; str string[100]; FILE *fp = fopen("a2","wb"); if(NULL == fp) { printf("open error\n"); exit(1); } //printf("1111\n"); while( head->next != NULL) { for(i = 0;i < len;i++) { strcpy(string[i].name,head->next->name); strcpy(string[i].p_num,head->next->p_num); fwrite(&string[i],sizeof(str),1,fp); //依次将结构体数组写到文件 head = head->next; } } fclose(fp); } void read_to_linklist(node *head) //将文件中的数据读到链表中 { int i; int m; int j = 0; node *p; node *q; p = head; FILE *fp; fp = fopen("a2","rb"); fseek(fp,0,SEEK_END); i = ftell(fp); fseek(fp,0,SEEK_SET); m = (i/(sizeof(str))); // m :文件中有多少个联系人 str string[100]; //结构体数组,存放所有联系人 fread(string,sizeof(str),m,fp); while(m > 0) { q = (node*)malloc(sizeof(node)); strcpy(q->name,string[j].name); strcpy(q->p_num,string[j].p_num); m--; j++; p->next = q; p = q; } fclose(fp); }*/ int display() //菜单 { printf( "\n**************请选择要进行的操作***********\n"); printf("-----------------------------------------------\n"); printf("*|************* 1 .添加货物******************|*\n"); printf("*|************* 2 .删除货物******************|*\n"); printf("*|**************3 .查找货物******************|*\n"); printf("*|**************4 .显示货物******************|*\n"); printf("*|**************5 .修改货物******************|*\n"); printf("*|**************6 .清空货物******************|*\n"); printf("*|**************7 .退 出******************|*\n"); printf("-----------------------------------------------"); } int main() { int a; int n = 1; node *head; node *q; head = (node*)malloc(sizeof(node)); if(NULL == head) { printf("error\n"); } q = head; head->next = NULL; //read_to_linklist(q); while(n == 1) { printf("\n",display()); printf("\n**********************请输入要进行的操作**********\n\n"); scanf("%d",&a); switch(a) { case 1: while(getchar() != '\n'); create(q); order(q,sum(q)); a = 0; break; case 2: while(getchar() != '\n'); del(q); getchar(); print(q); break; case 3: find(q); break; case 4: while(getchar() != '\n'); print(q); break; case 5: while(getchar() != '\n'); change(q); break; case 6: all_delete(q); break; case 7: //write_to_file(q,sum(q)); n = 0; break; default: { printf("*****输入错误,请重新选择指令:******\n"); } while(getchar() != '\n'); break; } } free(head); }
关于C++中遇到一个错误,不知道是哪里错了.
原文是: List2Node是自定义类 List1Node也是自定义类 List中有组合着List1Node和List2Node的指针 List2Node* List::lookupbook(List1Node *q1,string name)//传入要删除的种类当中的书,并找到该书的地址 错误提示:D:\work by C++\Test_list.cpp(93) : error C2556: 'struct List2 *__thiscall List::lookupbook(struct List1 *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)' : overloaded function differs only by return type fro m 'struct List1 *__thiscall List::lookupbook(struct List1 *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)' D:\work by C++\Test_list.cpp(72) : see declaration of 'lookupbook' 请教各位大神,这是什么原因?由于本人是初学者,不是很了解这错误是应为什么而出错.
实验是数据结构中做一个学生成绩管理系统,在网上找到了相应代码,但是不知道怎么插入学生信息,希望大佬帮助完成这个课题
#include<stdio.h> #include<stdlib.h> #include<string.h> char top[50]; //成绩文件顶部的标题用top保存 typedef struct student //单个学生成绩的记录 { char name[10]; //姓名 int number; //学号 int chinese; //语文 int math; //数学 int english; //英语 struct student *next; }student,*gradelist; gradelist fileread(char *adress) //读取成绩文件 { FILE * fp; if((fp=fopen(address,"r"))==NULL) //打开文件 { printf("文件打开出错"); exit(0); } gradelist file=(student *)malloc(sizeof(student)); //申请空间 file->next=NULL; student * p=file; //操作指针 int n=0; //循环标记,具体作用是在第一次循环时方便处理标题 while(!feof(fp)) { if(n==0) { fgets(top,50,fp); //处理标题,并且文件指针移到第二行 } if(n==1) //申请空间 { (p->next)=(student *)malloc(sizeof(student)); p=p->next; p->next=NULL; } fscanf(fp,"%s%d%d%d%d",p->name,&p->number,&p->chinese,&p->math,&p->english); //将文件的数据输入到链表中 n=1; } if(fclose(fp)) //关闭文件 { printf("文件关闭失败"); exit(0); } return file; } void FilePrint(gradelist file) //将成绩文件打印到屏幕上 { student *p=file; printf("%s\n",top); //打印标题 while(p->next!=NULL) { printf("%6s %2d %d %d %d\n",p->name,p->number,p->chinese,p->math,p->english); //循环打印 p=p->next; } } void merger() //合并文件 { char * address1="1.txt",*address2="2.txt",*address3="3.txt"; gradelist file1=fileread(address1),file2=fileread(address2); FILE *fp; if((fp=fopen("3.txt","w+"))==NULL) //先新建一个3.txt,然后将1.txt和2.txt的内容输入到里面 { printf("合并成绩文档失败,原因:建立文档出错"); exit(0); } student *p1=file1,*p2=file2; fprintf(fp,"%s",top); //先输入标题 while(p1->next!=NULL) { fprintf(fp,"%6s %2d %d %d %d\n",p1->name,p1->number,p1->chinese,p1->math,p1->english); //输入1.txt p1=p1->next; } while(p2->next!=NULL) { fprintf(fp,"%6s %2d %d %d %d\n",p2->name,p2->number,p2->chinese,p2->math,p2->english); //输入2.txt p2=p2->next; } if(fclose(fp)) { printf("文件关闭失败"); exit(0); } } void extract() //抽取补考的成绩记录 { char * address4="4.txt",*address3="3.txt"; FILE *fp; if((fp=fopen("4.txt","w+"))==NULL) //新建文件4.txt { printf("抽取补考学生成绩记录建立新文件失败"); exit(0); } gradelist file3=fileread(address3); student *p=file3; fprintf(fp,"%s",top); //先输入标题 while(p->next!=NULL) { if((p->chinese)<60||(p->math)<60||(p->english)<60) //补考条件 { fprintf(fp,"%6s %2d %d %d %d\n",p->name,p->number,p->chinese,p->math,p->english); } p=p->next; } if(fclose(fp)) { printf("文件关闭失败"); exit(0); } } void sort(int i) { char * address3="3.txt"; gradelist file3=fileread(address3); //先将3.txt读入链表 student *p=file3; if(remove("3.txt")) //由于排序后的内容也要保存到3.txt,故删除3.txt { printf("删除文件出错"); exit(0); } int n=0; //学生个数 FILE *fp; if((fp=fopen("3.txt","w+"))==NULL) //新建一个空的3.txt { printf("新建文件出错"); exit(0); } fprintf(fp,"%s",top); //标题先输入 while(p->next!=NULL) { n++; p=p->next; } typedef struct //链表不容易操作,故而新建一个结构数组 { int totalgrade; char name[10]; int number; int chinese; int math; int english; }gradenote; //成绩记录 typedef struct { gradenote r[100]; //只初始化了100了空间,学生人数超过100就不能了,懒得动态分配了 }grade_list; //待排序成绩表 grade_list L; p=file3; int t; for(t=1;t<=n;t++,p=p->next) //将链表的内容复制到结构数组里 { strcpy(L.r[t].name,p->name); L.r[t].number=p->number; L.r[t].chinese=p->chinese; L.r[t].math=p->math; L.r[t].english=p->english; L.r[t].totalgrade=p->chinese+p->math+p->english; } if(i==1) //直接插入排序 { int k; for(k=2;k<=n;++k) { if(L.r[k].totalgrade<L.r[k-1].totalgrade) { L.r[0]=L.r[k]; L.r[k]=L.r[k-1]; int j; for(j=k-2;L.r[0].totalgrade<L.r[j].totalgrade;--j) { L.r[j+1]=L.r[j]; } L.r[j+1]=L.r[0]; } } } if(i==2) //折半插入排序 { int m; int k; for(k=2;k<=n;++k) { L.r[0]=L.r[k]; int low=1,high=k-1; while(low<=high) { m=(low+high)/2; if(L.r[0].totalgrade<L.r[m].totalgrade) high=m-1; else low=m+1; } int j; for(j=k-1;j>=high+1;--j) L.r[j+1]=L.r[j]; L.r[high+1]=L.r[0]; } } int q; for(q=n;q>=1;q--) //将排序好的内容输入到3.txt { fprintf(fp,"%6s %2d %d %d %d\n",L.r[q].name,L.r[q].number,L.r[q].chinese,L.r[q].math,L.r[q].english); } if(fclose(fp)) { printf("文件关闭失败"); exit(0); } } void search(char *name) //按姓名查找 { gradelist file=fileread("3.txt"); student * p=file; while(p->next!=NULL) { if(strcmp(name,p->name)==0) { printf("%6s %2d %d %d %d\n",p->name,p->number,p->chinese,p->math,p->english); return; } p=p->next; } printf("查无此人,请确定名字输入正确\n"); exit(0); } void main(void) // { int chioce; gradelist file1=fileread("1.txt"),file2=fileread("2.txt"); printf("现有成绩记录文件1\n"); printf("*********************************************************\n"); FilePrint(file1); printf("*********************************************************\n"); printf("现有成绩记录文件2\n"); printf("*********************************************************\n"); FilePrint(file2); printf("*********************************************************\n"); printf("第一步,合并成绩记录文件\n"); merger(); printf("合并成功\n"); system("PAUSE"); printf("现有合并后的成绩记录文件3\n"); printf("*********************************************************\n"); gradelist file3=fileread("3.txt"); FilePrint(file3); printf("*********************************************************\n"); printf("第二步,抽取补考成绩记录\n"); extract(); system("PAUSE"); printf("现有补考成绩记录文件4\n"); printf("*********************************************************\n"); gradelist file4=fileread("4.txt"); FilePrint(file4); printf("*********************************************************\n"); printf("第三步,对文件3进行排序\n"); printf("请输入排序方式(1/2)\n1:直接插入排序\n2:折半插入排序\n"); scanf("%d",&chioce); if(chioce==1) sort(1); else if(chioce==2) sort(2); else { printf("输入不合理,程序默认采用1方式\n"); sort(1); } file3=fileread("3.txt"); printf("现有按总分降序的成绩记录3\n"); printf("*********************************************************\n"); FilePrint(file3); printf("*********************************************************\n"); printf("第四步,查找学生信息\n"); char name[100]; printf("请输入学生姓名\n"); scanf("%s",name); search(name); printf("按任意键结束程序\n"); getchar(); } 姓名 学号 语文 数学 英语 张明明 01 67 78 82 李成友 02 78 91 88 张辉灿 03 68 82 56 王露 04 56 45 77 陈东明 05 67 38 47 姓名 学号 语文 数学 英语 陈果 31 57 68 82 李华明 32 88 90 68 张明东 33 48 42 56 李明国 34 50 45 87 陈道亮 35 47 58 77
C++程序运行时不能读取内存
``` #include<iostream> using namespace std; //**********结点类********** template<class ElemType> struct BinTreeNode { ElemType data; BinTreeNode <ElemType> * leftchild = NULL; BinTreeNode <ElemType> * rightchild = NULL; BinTreeNode(); BinTreeNode(const ElemType &d, BinTreeNode<ElemType>* lchild = NULL, BinTreeNode<ElemType>* rchild = NULL); }; template<class ElemType> BinTreeNode<ElemType>::BinTreeNode() //无参构造函数 { leftchild = rightchild = NULL; } template<class ElemType> BinTreeNode<ElemType>::BinTreeNode(const ElemType &d, BinTreeNode<ElemType>* lchild, BinTreeNode<ElemType>* rchild) //有参构造函数 { data = d; leftchild = lchild; rightchild = rchild; } //**********二叉排序树类********** template<class ElemType> class BinarySortTree { protected: //数据成员: BinTreeNode<ElemType> *root; public: //函数成员: BinarySortTree(); //无参数构造函数 virtual ~BinarySortTree(); //析构函数 BinTreeNode<ElemType> *GetRoot() const; //求二叉排序树的根 BinTreeNode<ElemType> *Find(ElemType &key, BinTreeNode<ElemType> *&f); //查找关键字为key的数据元素 void Insert(ElemType e, BinTreeNode<ElemType> *head); //插入数据元素e void Delete(BinTreeNode<ElemType> *&p); //删除结点 void InOrder(BinTreeNode<ElemType> *r); //中序遍历 }; //无参构造函数 template<class ElemType> BinarySortTree<ElemType>::BinarySortTree() { root = NULL; } //析构函数 template<class ElemType> BinarySortTree<ElemType>::~BinarySortTree() { } //求二叉排序树的根 template<class ElemType> BinTreeNode<ElemType> * BinarySortTree<ElemType>::GetRoot() const { return root; } //查找关键字为key的数据元素 template<class ElemType> BinTreeNode<ElemType> * BinarySortTree<ElemType>::Find(ElemType &key, BinTreeNode<ElemType> *&f) { BinTreeNode<ElemType> *p = GetRoot(); //指向当前结点 f = NULL; //指向p的双亲 while (p != NULL && p->data != key){ if (key < p->data){//key比p小,左子树 f = p; p = p->leftchild; } else{//key比p大,右子树 f = p; p = p->rightchild; } } return p; } //二叉排序树插入 template<class ElemType> void BinarySortTree<ElemType>::Insert(ElemType e, BinTreeNode<ElemType> *head) { if (head == NULL){ head = new BinTreeNode<int>(e); cout << "head == NULL" << endl; } else{ if (e > head->data){ Insert(e, head->rightchild); cout <<"head != NULL"<< endl; } else{ Insert(e, head->leftchild); cout <<"head != NULL"<< endl; } } } //删除结点 template<class ElemType> void BinarySortTree<ElemType>::Delete(BinTreeNode<ElemType> *&p) { BinTreeNode<ElemType> *tmpPtr, *tmpF; if (p->leftchild == NULL && p->rightchild == NULL){ delete p; p = NULL; } else if (p->leftchild == NULL){ tempPtr = p; p = p->rightchild; delete tmpPtr; } else if (p->rightchild == NULL){ tmpPtr = p; p = p->leftchild; delete tmpPtr; } else { tmpF = p; tmpPtr = p->leftchild; while (tmpPtr->rightchild != NULL){ tmpF = tmpPtr; tmpPtr = tmpPtr->rightchild; } p->data = tmpPtr->rightchild; if (tmpF->rightchild == tmpPtr) Delete(tmpF->rightchild); else Delete(tmpF->leftchild); } } //中序遍历 template<class ElemType> void BinarySortTree<ElemType>::InOrder(BinTreeNode<ElemType> *r) { if (r != NULL) { cout << r->data; InOrder(r->leftchild); cout << r->data; InOrder(r->rightchild); } } int main() { int n[30]; int m; BinarySortTree<int> A; BinTreeNode<int> *head=NULL; cout << "输入要插入的数据个数: " << endl; cin >> m; for (int i = 0; i <= m-1; i++) { cout << "输入要插入的数据: " << endl; cin >> n[i]; A.Insert(n[i], head); } A.InOrder(head); system("pause"); } ``` 只要是BinTreeNode定义的变量,在访问它的data或左右孩子的时候,都会显示无法读取内存,然后出错。而且主函数定义的head指针永远都是空的,不知道为什么,跪求大佬的解读。
c语言 运行出错 回车怎么进行不下去了呢 是不是文件部分出错了
![图片说明](https://img-ask.csdn.net/upload/201806/13/1528883958_468190.png) #include <stdio.h> #include <malloc.h> #include <string.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct NODE { char name[MAXSIZE]; int p_num; double p_price; char kind[MAXSIZE]; struct NODE *next; }node; //下面这部分是啥??? typedef struct { char name[MAXSIZE]; int p_num; double p_price; char kind[MAXSIZE]; }str; #if 0 void create(node *head); /*创建货物 main 194line*/ void del(node *head); /*删除指定货物*/ void find(node *head) /*查找货物*/ void all_delete(node *head); /*清空全部货物*/ void change(node *head); /*修改货物信息*/ int display() /*菜单*/ #endif void create(node *head) /*创建货物 main 194line*/ { node *p; /*判断货物是否存在的指针变量*/ int i = 1; char name[MAXSIZE]; int p_num; double p_price; char kind[MAXSIZE]; printf("*****************请输入货物名称:************\n"); scanf("%s",name); //getchar(); p = head->next; while(p != NULL) { if(strcmp(p->name,name) == 0) { printf("*********货物已存在************\n"); p = NULL; i = 0; /* 货物已存在,不执行输入货物命令*/ } else { p = p->next; } } while( 1 == i) { node *q; printf("**************请输入货物单位价格:**************\n"); scanf("%lf",&p_price); printf("**************请输入货物数量:**************\n"); scanf("%d",&p_num); printf("*****************请输入货物所属类型:************\n"); scanf("%s",kind); q = (node*)malloc(sizeof(node)); if(NULL == q) { printf("error2\n"); } strcpy(q->name,name); //strcpy(q->p_num,p_num); q->p_num=p_num; q->p_price=p_price; strcpy(q->kind,kind); q->next = head->next; head->next = q; /*头插法*/ i = 0; } } //我的代码跟这个的区别:没有在函数内重新定义变量 然后使用strcpy这些赋值 void order(node *head,int len1) //给货物排序 { node *p; /*用来排序的变量*/ node *q; /*同上*/ p = head->next; while(len1 > 0) /*实现货物按字母排列*/ { while(p != NULL && p->next!= NULL) { char tempname[MAXSIZE]; /*相当于中间变量用来存储货物信息*/ int tempp_num; double tempp_price; char tempkind[MAXSIZE]; if(strcmp(p->name,p->next->name) > 0) { strcpy(tempname, p->next->name); tempp_price=p->next->p_price; tempp_num=p->next->p_num; strcpy(tempkind,p->next->kind); strcpy(p->next->name,p->name); p->next->p_price=p->p_price; p->next->p_num=p->p_num; strcpy(p->next->kind,p->kind); strcpy(p->name,tempname); p->p_price=tempp_price; p->p_num=tempp_num; strcpy(p->kind,tempkind); } else { p=p->next; } } len1--; } } void print(node *head) /*打印联系人的函数*/ { int i = 1; node *p; p = head->next; printf("现在货物为:\n"); printf("编号 名称 价格 数量 所属类型\n"); while(p != NULL) { printf("%d %s %.2lf %d %s\n", i,p->name,p->p_price,p->p_num,p->kind); p = p->next; i++; } } void del(node *head) /*删除指定货物函数*/ { node *p; node *q; q = head; p = q->next; char name[MAXSIZE]; printf("************请输入要删除的货物名称:*********\n"); scanf("%s",name); while((p != NULL) && (strcmp(p->name,name) != 0)) { q = p; p = p->next; } if(NULL == p) { printf("************未查找到***************\n"); } else { q->next = p->next; free(p); printf("***********删除成功****************\n"); } } void find(node *head) //查找货物 { node *p; char name[MAXSIZE]; printf("*******请输入要查找货物名称:**********\n"); scanf("%s",name); p = head->next; while(p != NULL && strcmp(p->name,name) != 0) { p = p->next;//为什么del函数里面还定义了一个指针q } if(NULL == p) { printf("********没有这个货物*********\n"); } else { printf(" 名称:%s\n 价格:%.2lf 数量:%d 所属类型:%s", p->name,p->p_price,p->p_num,p->kind); } } void all_delete(node *head) //清空全部货物 { while(head->next != NULL) { node *q; q = head->next; head->next = q->next; free(q); } if(NULL == head->next) { printf("*********清除所有货物成功*********\n"); } } void change(node *head) //修改货物信息 { node *p; char name[MAXSIZE]; double p_price; int p_num; char kind[MAXSIZE]; p = head->next; printf("请输入要修改的货物名称\n"); scanf("%s",name); while( p != NULL) { if(strcmp(p->name,name) == 0) { printf("请输入要修改的货物价格\n"); scanf("%lf",p_price); p->p_price=p_price; printf("修改成功\n"); break; } else { p = p->next; } } if(p == NULL) { printf("未查找到此联系人!\n"); } } int sum(node *head) //求链表中有多少货物 { int count_node = 0; node *p; p = head->next; if(p != NULL) { count_node++; p = p->next; } return count_node; } void write_to_file(node *head,int len) //链表中的货物信息写到文件 { int i; str string[100]; FILE *fp = fopen("a2","wb"); if(NULL == fp) { printf("open error\n"); exit(1); } //printf("1111\n"); while( head->next != NULL) { for(i = 0;i < len;i++) { strcpy(string[i].name,head->next->name); string[i].p_num=head->next->p_num; string[i].p_price=head->next->p_price; strcpy(string[i].kind,head->next->kind); fwrite(&string[i],sizeof(str),1,fp); //依次将结构体数组写到文件 head = head->next; } } fclose(fp); } void read_to_linklist(node *head) //将文件中的数据读到链表中 { int i; int m; int j = 0; node *p; node *q; p = head; FILE *fp; fp = fopen("a2","rb"); fseek(fp,0,SEEK_END); i = ftell(fp); fseek(fp,0,SEEK_SET); m = (i/(sizeof(str))); // m :文件中有多少个联系人 str string[100]; //结构体数组,存放所有联系人 fread(string,sizeof(str),m,fp); while(m > 0) { q = (node*)malloc(sizeof(node)); strcpy(q->name,string[j].name); q->p_num=string[j].p_num; q->p_price=string[j].p_price; strcpy(q->kind,string[j].kind); m--; j++; p->next = q; p = q; } fclose(fp); } int display() //菜单 { printf( "\n**************请选择要进行的操作***********\n"); printf("-----------------------------------------------\n"); printf("*|************* 1 .添加货物******************|*\n"); printf("*|************* 2 .删除货物******************|*\n"); printf("*|**************3 .查找货物******************|*\n"); printf("*|**************4 .显示货物******************|*\n"); printf("*|**************5 .修改货物******************|*\n"); printf("*|**************6 .清空货物******************|*\n"); printf("*|**************7 .退 出******************|*\n"); printf("-----------------------------------------------"); } int main() { int a; int n = 1; node *head; node *q; head = (node*)malloc(sizeof(node)); if(NULL == head) { printf("error\n"); } q = head; head->next = NULL; read_to_linklist(q); while(n == 1) { printf("\n",display()); printf("\n**********************请输入要进行的操作**********\n\n"); scanf("%d",&a); switch(a) { case 1: while(getchar() != '\n'); create(q); order(q,sum(q)); a = 0; break; case 2: while(getchar() != '\n'); del(q); getchar(); print(q); break; case 3: find(q); break; case 4: while(getchar() != '\n'); print(q); break; case 5: while(getchar() != '\n'); change(q); break; case 6: all_delete(q); break; case 7: write_to_file(q,sum(q)); n = 0; break; default: { printf("*****输入错误,请重新选择指令:******\n"); } while(getchar() != '\n'); break; } } free(head); } //1.把显示错的那边改一下 ok //2.文件那边补充好(代码中是二进制形式,可以试试w,r)50%ok fprintf fscanf呀呀呀呀 //3.货物种类大框架 //4.把细节理解好
(C语言)在二叉搜索树的学习时遇到了问题,求大佬帮忙看看
如题,在学习二叉搜索树时想要自己添加一些内容,但是不知道为什么就是会出错,自己感觉好像问题出在创建二叉树的地方,但是不知道怎么改.希望大佬能帮忙看看,如果能配上讲解就更好了,感谢. 下面贴上代码,之后是罗列的一些问题,如果代码中还有问题希望大佬能指点下我,谢谢: 项目总共三个文件,二叉搜索树头文件.h和.c文件,然后一个用于测试的主函数.c (二叉搜索树头文件) BSTree.h ``` #ifndef BSTREE_H #define BSTREE_H typedef int DataType; //二叉排序树节点定义 struct BinSearchTreeNode { DataType data; struct BinSearchTreeNode *leftchild; struct BinSearchTreeNode *rightchild; }; typedef struct BinSearchTreeNode *BSTreeNode; typedef struct BinSearchTreeNode *BinSearchTree; /****************************************************************/ /* BinSearchTree *create() */ /* 功能:创建二叉排序树 */ /* 输入参数:无 */ /* 返回值:二叉排序树 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ BinSearchTree create(); /****************************************************************/ /* void InOrder(BinSearchTree ptree) */ /* 功能:中序遍历二叉排序树 */ /* 输入参数ptree:二叉排序树 */ /* 返回值:无 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ void InOrder(BinSearchTree ptree); /****************************************************************/ /* BSTreeNode BSTSearch(BinSearchTree bt, DataType key) */ /* 功能:检索二叉排序树 */ /* 输入参数bt:二叉排序树的根 */ /* 输入参数key:要检索的元素 */ /* 返回值:成功返回NULL,失败返回元素插入的父结点位置 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ BSTreeNode BSTSearch(BinSearchTree bt, DataType key); /****************************************************************/ /* int BSTInsert(BinSearchTree bt, DataType key) */ /* 功能:在二叉排序树中插入元素key */ /* 输入参数bt:二叉排序树的根 */ /* 输入参数key:要插入的元素 */ /* 返回值:成功插入返回1,否则返回0 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ int BSTInsert(BinSearchTree bt, DataType key); /****************************************************************/ /* int BSTgetMax(BinSearchTree *bt) */ /* 功能:查找二叉排序树的最大值 */ /* 输入参数bt:二叉排序树的根 */ /* 返回值:无 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ void BSTgetMax(BinSearchTree *bt); /****************************************************************/ /* int BSTgetMin(BinSearchTree *bt) */ /* 功能:查找二叉排序树的最小值 */ /* 输入参数bt:二叉排序树的根 */ /* 返回值:无 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ void BSTgetMin(BinSearchTree *bt); /****************************************************************/ /* int BSTDelete1(BinSearchTree *bt, DataType key) */ /* 功能:删除二叉排序树中的元素key,方法1 */ /* 输入参数bt:二叉排序树的根 */ /* 输入参数key:要删除的元素 */ /* 返回值:成功删除返回1,否则返回0 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ int BSTDelete1(BinSearchTree *bt, DataType key); /****************************************************************/ /* int BSTDelete2(BinSearchTree *bt, DataType key) */ /* 功能:删除二叉排序树中的元素key,方法2 */ /* 输入参数bt:二叉排序树的根 */ /* 输入参数key:要删除的元素 */ /* 返回值:成功删除返回1,否则返回0 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ int BSTDelete2(BinSearchTree *bt, DataType key); /****************************************************************/ /* void BST_Destory(BinSearchTree bt) */ /* 功能:销毁二叉排序树 */ /* 输入参数bt:二叉排序树的根 */ /* 返回值:无 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ void BST_Destory(BinSearchTree bt); #endif // BSTREE_H ``` 对应的c文件 BSTree.c ``` #include <stdio.h> #include <stdlib.h> #include "BSTree.h" /****************************************************************/ /* BinSearchTree create() */ /* 功能:创建二叉排序树,注意这里输入的应该是先序序列,并且保证是一*/ /* 个二叉排序树的先序序列 */ /* 输入参数:无 */ /* 返回值:二叉排序树 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ BinSearchTree create() { int ch = 0;//初始化 BinSearchTree bt; scanf_s("%d", &ch); if (ch == -1) { bt = NULL; } else { bt = (BSTreeNode *)malloc(sizeof(struct BinSearchTreeNode)); bt->data = ch; //递归赋值左子树 bt->leftchild = create(); //递归赋值右子树 bt->rightchild = create(); } //返回根节点 return bt; } /****************************************************************/ /* void InOrder(BinSearchTree ptree) */ /* 功能:中序遍历二叉排序树 */ /* 输入参数ptree:二叉排序树 */ /* 返回值:无 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ void InOrder(BinSearchTree ptree) { if (ptree == NULL) { return; } InOrder(ptree->leftchild); printf("%d", ptree->data); InOrder(ptree->rightchild); } /****************************************************************/ /* BSTreeNode BSTSearch(BinSearchTree bt, DataType key) */ /* 功能:检索二叉排序树 */ /* 输入参数bt:二叉排序树的根 */ /* 输入参数key:要检索的元素 */ /* 返回值:成功返回NULL,失败返回元素插入的父结点位置 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ BSTreeNode BSTSearch(BinSearchTree bt, DataType key) { BSTreeNode p, parent; p = bt; parent = p; //记录待插入结点的父结点 while (p) { parent = p; //当查找到时提示,返回NULL if (p->data == key) { printf("Exist this key\n"); return NULL; } //根结点大于要查的结点,进入左分支查找 if (p->data > key) { p = p->leftchild; } //根结点小于要查的结点,进入右分支查找 else { p = p->rightchild; } }//p=NULL,跳出循环 return parent; //查找失败,返回parent }//return NULL和parent是为了便于之后的操作 /****************************************************************/ /* int BSTInsert(BinSearchTree bt, DataType key) */ /* 功能:在二叉排序树中插入元素key */ /* 输入参数bt:二叉排序树的根 */ /* 输入参数key:要插入的元素 */ /* 返回值:成功插入返回1,否则返回0 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ int BSTInsert(BinSearchTree bt, DataType key) { BSTreeNode p, temp; temp = BSTSearch(bt, key); //temp保存查找之后的结果 //已存在,返回0 if (temp == NULL) { printf("Exist this key\n"); return 0; } //申请结点的内存空间 p = (BSTreeNode *)malloc(sizeof(struct BinSearchTreeNode)); //申请失败提示 if (p == NULL) { printf("Alloc Failure!\n"); return 0; } p->data = key; //数据域赋值,左右指针域默认为空 //p->leftchild = NULL; //左子树指针域赋值 //p->rightchild = NULL; //右子树指针域赋值 if (key < temp->data) { temp->leftchild = p; //作为左子树插入 } else { temp->rightchild = p; //作为右子树插入 } return 1; } /****************************************************************/ /* int BSTgetMax(BinSearchTree bt) */ /* 功能:查找二叉排序树的最大值 */ /* 输入参数bt:二叉排序树的根 */ /* 返回值:无 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ void BSTgetMax(BinSearchTree *bt) { BSTreeNode temp; temp = bt; if (temp) { while (temp->leftchild) { temp = temp->leftchild; } printf("%d", temp->data); } } /****************************************************************/ /* int BSTgetMin(BinSearchTree bt) */ /* 功能:查找二叉排序树的最小值 */ /* 输入参数bt:二叉排序树的根 */ /* 返回值:无 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ void BSTgetMin(BinSearchTree *bt) { BSTreeNode temp; temp = bt; if (temp) { while (temp->rightchild) { temp = temp->rightchild; } printf("%d", temp->data); } } /****************************************************************/ /* int BSTDelete1(BinSearchTree *bt, DataType key) */ /* 功能:删除二叉排序树中的元素key,方法1 */ /* 输入参数bt:二叉排序树的根 */ /* 输入参数key:要删除的元素 */ /* 返回值:成功删除返回1,否则返回0 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ int BSTDelete1(BinSearchTree *bt, DataType key) { BSTreeNode parent, p, maxpl; p = *bt; parent = NULL; //查找被删除的结点 while (p != NULL) { if (p->data == key) break; //查找到了,跳出循环 if (p->data > key) p = p->leftchild; else p = p->rightchild; }//查询结束 if (p == NULL) { printf("%d not exist\n", key); return 0; } //只有右子树的情况 if (p->leftchild == NULL) { //如果被删除的结点是根结点,那就要修改的是二叉排序树的根 if (parent == NULL) *bt = p->rightchild; //检查是左孩子还是右孩子 else if (parent->leftchild == p) parent->leftchild = p->rightchild; else parent->rightchild = p->rightchild; } //既有左子树也有右子树 if (p->leftchild != NULL) { BSTreeNode parentp; //parentp记录maxpl的父结点 parentp = p; maxpl = p->leftchild; //对称遍历中,右侧的总是大的数 //定位p的左子树中的最大结点maxpl while (maxpl->rightchild != NULL) { parentp = maxpl; maxpl = maxpl->rightchild; } p->data = maxpl->data; //修改p的数据域为maxpl的值 if (parentp == p) //如果maxpl的父结点是p p->leftchild = maxpl->leftchild; //修改p结点的左指针 else parentp->rightchild = maxpl->leftchild; //修改父结点的右指针 p = maxpl; //更新p指针为maxpl结点以便删除 } //释放空间 free(p); return 1; } /****************************************************************/ /* int BSTDelete2(BinSearchTree *bt, DataType key) */ /* 功能:删除二叉排序树中的元素key,方法2 */ /* 输入参数bt:二叉排序树的根 */ /* 输入参数key:要删除的元素 */ /* 返回值:成功删除返回1,否则返回0 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ int BSTDelete2(BinSearchTree *bt, DataType key) { //parent记录p的父结点,maxpl记录p的左子树中的关键码最大结点 BSTreeNode parent, p, maxpl; p = *bt; parent = NULL; //查找被删除的结点 while (p != NULL) { if (p->data == key) break; //查找到了,跳出循环 parent = p; //注意这一句 if (p->data > key) p = p->leftchild; else p = p->rightchild; }//查找结束 if (p == NULL) { printf("%d not exist!\n", key); return 0; } //只有右子树的情况 if (p->leftchild == NULL) { //删除的是根结点,做特殊处理 if (parent == NULL) *bt = p->rightchild; //p是父结点parent的左孩子,则修改父结点的左指针 else if (parent->leftchild == p) parent->leftchild = p->rightchild; else parent->rightchild = p->rightchild; } //以上和方法1几乎完全相同 //有左子树和右子树 if (p->leftchild != NULL) { maxpl = p->leftchild; //定位左子树中的最大结点maxpl while (maxpl->rightchild != NULL) maxpl = maxpl->rightchild; maxpl->rightchild = p->rightchild; if (parent == NULL) *bt = p->leftchild; //p是父结点parent的左孩子,则修改父结点的左指针 else if (parent->leftchild == p) parent->leftchild = p->leftchild; //p是父结点parent的右孩子,则修改父结点的右指针 else parent->rightchild = p->leftchild; } free(p); //释放结点p return 1; } /****************************************************************/ /* void BST_Destory(BinSearchTree *bt) */ /* 功能:递归销毁二叉排序树 */ /* 输入参数bt:二叉排序树的根 */ /* 返回值:无 */ /* 创建日期:2019-5-21 Author:Cyber Kaka */ /****************************************************************/ void BST_Destory(BinSearchTree bt) { if (bt) { BST_Destory(bt->leftchild); BST_Destory(bt->rightchild); free(bt); } } ``` 主函数.c文件 main.c ``` #include <stdio.h> #include <stdlib.h> #include "BSTree.h" //用于测试的二叉树先序序列,-1表示空 //40 10 5 -1 -1 -1 55 45 -1 48 47 -1 -1 52 -1 -1 60 -1 70 -1 -1 void main() { BinSearchTree bt; int n = 0; printf("输入二叉排序树的先序序列:\n"); bt = create(); printf("输入要查找的元素,存在返回1,不存在返回0,插入:"); scanf_s("%d", &n); printf("%d\n", BSTSearch(bt, n)->data); printf("输入要插入的元素,成功插入返回1,否则返回0:"); scanf_s("%d", &n); printf("%d\n", BSTInsert(bt, n)); //printf("二叉排序树的中序遍历序列:\n"); //InOrder(bt); printf("\n第一种删除方法,输入要删除的元素,成功返回1,不成功返回0:"); scanf_s("%d", &n); printf("%d\n", BSTDelete1(&bt, n)); //printf("二叉排序树的中序遍历序列:\n"); //InOrder(bt); printf("\n第二种删除方法,输入要删除的元素,成功返回1,不成功返回0:"); scanf_s("%d", &n); printf("%d\n", BSTDelete2(&bt, n)); //printf("二叉排序树的中序遍历序列:\n"); //InOrder(bt); } ``` **问题:**<br> <br> * [0]生成解决方案的时候有警告,但是我忽略了,因为显示程序生成成功了,感觉这几个警告是最大的问题,第4个问题中我详细列出了这些内容<br> <br> * [1]二叉树的递归创建自己感觉有问题,尤其是内存申请这里<br> <br> <code>bt = (BSTreeNode *)malloc(sizeof(struct BinSearchTreeNode));</code><br> <br> * [2]中序遍历的内容在搜索到左子树底的时候本应返回上一步时会出现异常,建立断点异常内容如下:<br> 引发了异常: 读取访问权限冲突。<br> **ptree** 是 0xCDCDCDCD。<br> <br> * [3]由于中序遍历有异常,所以我注释掉了所有的相关内容,编译时没什么问题,但是删除结点的函数也会出现类似的异常,异常内容如下:<br> 引发了异常: 读取访问权限冲突。<br> **maxpl** 是 0xCDCDCDCD。<br> <br> <br> * [4]好吧,我就都注释掉了,看看别的代码是不是有问题,重新生成解决方案,熟悉的警告出现了,c语言是速成的结构体这块不是很明了,感觉应该是创建二叉搜索树的代码有问题,或者是结构体创建有问题,以下是警告的内容:<br> */bstree.c(24): warning C4047: “=”:“BinSearchTree”与“BSTreeNode *”的间接级别不同<br> */bstree.c(108): warning C4047: “=”:“BSTreeNode”与“BSTreeNode *”的间接级别不同<br> *\bstree.c(139): warning C4047: “=”:“BSTreeNode”与“BinSearchTree *”的间接级别不同<br> *\bstree.c(160): warning C4047: “=”:“BSTreeNode”与“BinSearchTree *”的间接级别不同<br> <br> 第24行:<br> BinSearchTree create()<br> {<br> &nbsp;&nbsp;...<br> &nbsp;&nbsp;&nbsp;&nbsp;bt = (BSTreeNode *)malloc(sizeof(struct BinSearchTreeNode));<br> &nbsp;&nbsp;...<br> }<br> <br> 第108行:<br> int BSTInsert(BinSearchTree bt, DataType key)<br> {<br> &nbsp;&nbsp;...<br> &nbsp;&nbsp;&nbsp;&nbsp;//申请结点的内存空间<br> &nbsp;&nbsp;&nbsp;&nbsp;p = (BSTreeNode *)malloc(sizeof(struct BinSearchTreeNode));<br> &nbsp;&nbsp;...<br> }<br> <br> 第139行:<br> void BSTgetMax(BinSearchTree *bt)<br> {<br> &nbsp;&nbsp;...<br> &nbsp;&nbsp;&nbsp;&nbsp;temp = bt;<br> &nbsp;&nbsp;...<br> }<br> <br> 第160行:<br> void BSTgetMin(BinSearchTree *bt)<br> {<br> &nbsp;&nbsp;...<br> &nbsp;&nbsp;&nbsp;&nbsp;temp = bt;<br> &nbsp;&nbsp;...<br> }<br> <br> 以上,求各位大佬指点迷津<br>
用fscanf和fgets从文件读取数据存储到链表失败是为什么??
我建立了链表结构,然后从文件导入数据,然后输出链表内容,发现输出的内容顺序不对内容也有点地方出错了! (下面是代码) #include <iostream> #include<fstream> #include<stdlib.h> #include<string.h> #include<stdio.h> typedef struct node{ char question[200]; char option_A[50]; char option_B[50]; char option_C[50]; char option_D[50]; char answer[3]; char respond[3]; char analysis[200]; int length; struct node *next; }LNODE,*LinkList; int main(void) { LNODE *L; L=new LNODE; L->next=NULL; L->length=0; LNODE *p; LNODE *q; q=L; int i; FILE *tk; if((tk=fopen("//Users//apple//Documents//Test System//test question.txt","r"))==NULL) { printf("File open error!\n"); exit(0); } while(!feof(tk)) { fgets(q->question,sizeof(LNODE),tk); fgets(q->option_A,sizeof(LNODE),tk); fgets(q->option_B,sizeof(LNODE),tk); fgets(q->option_C,sizeof(LNODE),tk); fgets(q->option_D,sizeof(LNODE),tk); fgets(q->answer,sizeof(LNODE),tk); fgets(q->analysis,sizeof(LNODE),tk); p=new LNODE; p->next=NULL; q->next=p; q=q->next; } if(fclose(tk)) { printf("Can not close the file!\n"); exit(0); } q=L; while(q->next) { printf("%s",q->question); printf("%s",q->option_A); printf("%s",q->option_B); printf("%s",q->option_C); printf("%s",q->option_D); printf("%s",q->answer); printf("%s",q->analysis); q=q->next; } } (这是文档里的内容) 在数据结构中,从逻辑结构上可以把数据结构分成() A.动态结构和静态结构 B.紧凑结构和非紧凑结构 C.线性结构和非线性结构 D.内部结构和外部结构 C 略 与数据元素本身的形式,内容,相对位置,个数无关的是数据的() A.存储结构 B.存储实现 C.逻辑结构 D.运算实现 C 略 通常要求同一逻辑结构中的所有数据元素具有相同的特性,这意味着() A.数据具有同一特点 B.每个数据元素都一样 C.不仅每个数据元素所包含的数据项都一样,而且对应数据项的类型要一致 D.数据元素所包含的数据项的个数要相等 C 只有这样系统才能高效统一的对数据进行管理。 算法的时间复杂度取决于() A.问题的规模 B.待处理的数据的初态 C.计算机的配置 D.A和B D 略 顺序表中第一个元素的储存地址是100,每个元素的长度为2,则第5个元素的地址是() A.100 B.108 C.100 D.120 B 100+(5-1)*2==108 线性表若采用链式存储结构,要求内存中可用存储单元的地址() A.部分是连续的 B.一定是不连续的 C.必须是连续的 D.连续或不连续都可以 D 因为链表有指针跟踪从而连不连续都可以。 用链接方式存储的队列,在进行删除运算时() A.仅修改头指针 B.仅修改尾指针 C.头尾指针都一定要修改 D.头尾指针可能都要修改 D 一般只修改头指针,但是删除的结点若为最后一个时,则要重新对尾指针赋值。 一个递归算法必须包括() A.递归部分 B.终止条件和递归部分 C.迭代部分 D.终止条件和迭代部分 D 略 串是一种特殊的线性表,其特殊性体现在() A.可以顺序储存 B.可以链式储存 C.数据元素是单个字符 D.数据元素可以是多个字符 C 串是一种内容受限的线性表。 把一棵树转化为二叉树后,这棵二叉树的形态是() A.唯一的 B.有多种 C.有多种,但根结点都没有左孩子 D.有多种,但根结点都没有右孩子 A 略。 利用二叉链表存储树,则根结点的右指针() A.指向最左孩子 B.指向最右孩子 C.非空 D.为空 C 右指针指向兄弟结点。 在以下的存储形式中,不是树的存储形式的是() A.双亲表示法 B.孩子链表表示法 C.孩子兄弟表示法 D.顺序存储表示法 D 常用孩子兄弟表示法转化为二叉树进行储存。 在一个无向图,所有顶点的度数之和等于图的边数的()倍 A.1/2 B.1 C.2 D.4 A 略 折半查找与二叉排序树的时间性能() A.相同 B.完全不同 C.有时不相同 D.数量级都是O(log2n) C 要看初始数据的状态。 堆的形状是一棵() A.二叉排序树 B.满二叉树 C.完全二叉树 D.平衡二叉树 C 略 若一组记录的排序码为(46,79,56,38,40,84),则利用堆排序的方式建立的初始堆为() A.79,46,56,38,40,84 B.84,79,56,38,40,46 C.84,79,56,46,40,38 D.84,56,79,40,46,38 C 画出图去找矛盾。 快速排序在下列()最易发挥作用 A.被排序的数据中具有多个相同的排序码 B.被排序的数据已经基本有序 C.被排序的数据完全无序 D.被排序的数据中的最大值和最小值相差悬殊 C 完全无序时用快速排序。 (这是输出后的内容,第一行与原文档的根本不同,而且后面也有很多乱的错误的) ![图片说明](https://img-ask.csdn.net/upload/201812/31/1546187214_133620.jpeg) 有哪位大神指导一下小白!!
C数据结构顺序表操作问题
两种操作方式 一、利用点运算符访问 ``` #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct { int data[MAXSIZE]; //存放数组元素 int last; //数组的最后一个元素的下标 }squeuelist; squeuelist l={0}; int main(void) { int choice=0, mount=0, i=0, dat=0, pos=0; while(1) { printf(" 线性顺序表操作练习\n"); printf("1.创建一个顺序表\n"); printf("2.插入数据\n"); printf("3.删除数据\n"); printf("4.打印顺序表\n"); printf("5.退出\n"); printf("请输入你的选择(1-5):"); scanf("%d",&choice); switch(choice) { case 1: printf("请输入你要创建的元素个数:"); scanf("%d", &mount); if(mount>MAXSIZE) { printf("创建的个数大于规定范围!"); break; } printf("请输入数据:"); for(i=0; i<mount; i++) { scanf("%d",&l.data[i]); } l.last = mount-1; break; //插入操作 case 2: printf("请输入要插入的元素值及所在位置(位置1表示元素0,依次类推):"); scanf("%d %d", &dat, &pos); if(l.last>MAXSIZE-1) { printf("空间溢出!\n"); break; } else if(pos<1 || pos>l.last+2) { printf("插入的位置非法!\n"); break; } else { for(i=l.last; i>=pos-1;i--) { l.data[i+1] = l.data[i]; } l.data[pos-1] = dat; l.last += 1; } break; //删除操作 case 3: printf("请输入你要删除元素所在的位置(位置1代表元素0,依次类推):"); scanf("%d",&pos); if(pos<1 || pos>l.last+1) { printf("输入的位置无效!\n"); break; } else { for(i=pos; i<=l.last; i++) { l.data[i-1] = l.data[i]; } l.last -= 1; } break; //打印输出顺序表 case 4: if (mount<=0) { printf("No data!\n"); break; } printf("顺序表为:"); for(i=0; i<=l.last; i++) { printf("%d ", l.data[i]); } printf("\n"); printf("顺序表的个数为:%d\n",l.last+1); break; //退出程序 case 5: exit(0); break; default: break; } } return 1; } ``` 这种访问方式能够成功! 第二种方式利用指针访问 ``` #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 typedef struct { int data[MAXSIZE]; //存放数组元素 int last; //数组的最后一个元素的下标 }squeuelist; squeuelist *l=NULL; int main(void) { int choice=0, mount=0, i=0, dat=0, pos=0; while(1) { printf(" 线性顺序表操作练习\n"); printf("1.创建一个顺序表\n"); printf("2.插入数据\n"); printf("3.删除数据\n"); printf("4.打印顺序表\n"); printf("5.退出\n"); printf("请输入你的选择(1-5):"); scanf("%d",&choice); switch(choice) { case 1: printf("请输入你要创建的元素个数:"); scanf("%d", &mount); if(mount>MAXSIZE) { printf("创建的个数大于规定范围!"); break; } printf("请输入数据:"); for(i=0; i<mount; i++) { scanf("%d",&l->data[i]); } l->last = mount-1; break; //插入操作 case 2: printf("请输入要插入的元素值及所在位置(位置1表示元素0,依次类推):"); scanf("%d %d", &dat, &pos); if(l->last>MAXSIZE-1) { printf("空间溢出!\n"); break; } else if(pos<1 || pos>l->last+2) { printf("插入的位置非法!\n"); break; } else { for(i=l->last; i>=pos-1;i--) { l->data[i+1] = l->data[i]; } l->data[pos-1] = dat; l->last += 1; } break; //删除操作 case 3: printf("请输入你要删除元素所在的位置(位置1代表元素0,依次类推):"); scanf("%d",&pos); if(pos<1 || pos>l->last+1) { printf("输入的位置无效!\n"); break; } else { for(i=pos; i<=l->last; i++) { l->data[i-1] = l->data[i]; } l->last -= 1; } break; //打印输出顺序表 case 4: if (mount<=0) { printf("顺序表无数据!\n"); break; } printf("顺序表为:"); for(i=0; i<=l->last; i++) { printf("%d ", l->data[i]); } printf("\n"); printf("顺序表的个数为:%d\n",l->last+1); break; //退出程序 case 5: exit(0); break; default: break; } } return 1; } ``` 当运行创建一个顺序表时,显示出错,报指令引用的“0x00000000”内存,该内存不能被“written”。 求大神帮忙分析下~
只有C语言实现,急求用C#实现机票预订管理系统源代码及界面
#include<stdio.h> //标准输入、输出头文件 #include<string.h> //包含字符串函数处理头文件 #include<stdlib.h> //包含动态存储与释放函数头文件 #define N 10000 struct air //定义结构体数组 { int num; char start[20]; char over[20]; char time[10]; int count; }s[N]; int i; int m=0; #define PRINT "%-d%12s%12s%10s%12d\n",s[i].num,s[i].start,s[i].over,s[i].time,s[i].count //定义输出格式 void input(); //输入航班信息 void print(); //输出航班信息 void save(); //保存航班信息 void read(); //读取航班信息 void search(); //查找航班信息 void shanchu(); //删除航班信息 void dingpiao(); //订票信息 void tuipiao(); //退票信息 void xiugai(); //修改信息 void main() { int j; printf(" ★---您好,欢迎进入中国民航管理系统!---★\n"); printf("================================================================================\n"); do { printf(" -------- ☆ 1.输入航班信息 ☆-------- \n\n" " -------- ☆ 2.浏览航班信息 ☆-------- \n\n" " -------- ☆ 3.修改航班信息 ☆-------- \n\n" " -------- ☆ 4.查找航班信息 ☆-------- \n\n" " -------- ☆ 5.删除航班信息 ☆-------- \n\n" " -------- ☆ 6.订票信息 ☆-------- \n\n" " -------- ☆ 7.退票信息 ☆-------- \n\n" " -------- ☆ 0.退出 ☆-------- \n\n"); printf("================================================================================\n"); printf("请在0-7中选择以回车键结束:\n\n"); scanf("%d",&j); switch(j) { case 1: input();//调用输入模块 break; case 2:print();//调用打印模块 break; case 3:xiugai();//调用修改模块 break; case 4:search();//调用查找模块 break; case 5:shanchu(); //调用删除模块 break; case 6:dingpiao();//调用订票模块 break; case 7:tuipiao();//调用退票模块 break; case 0:; break; } }while(j!=0); //判断结束 printf("谢谢使用,再见!\n"); }//主函数结束 void input()//打印模块程序 { char f[]="zhangbin0027"; //设置密码 int y; printf("请输入密码并以回车键结束:\n\n"); scanf("%s",f); //读取密码 if(strcmp(f,"zhangbin0027")==0) { printf("请依次输入航班信息(机票数位0结束输入):\n\n" "完成输入信息请键入w以回车键结束\n\n"); //打印提示信息 printf("-----------------------------------------------------------------\n"); for(i=0;i<N;i++) { printf("请输入航班号:\n"); scanf("%d",&s[i].num); //读取航班号 printf("请输入起始站:\n"); scanf("%s",s[i].start);//读取起始站 printf("请输入终点站:\n"); scanf("%s",s[i].over);//读取终点站 printf("请输入时间:\n"); scanf("%s",s[i].time);//读取时间 printf("请输入机票数(机票数为0结束输入):\n",m); scanf("%d",&s[i].count);//读取机票数 m++; printf("第%d个信息已经输完是否继续?按任意键继续,按 0结束",m); scanf("%d",&y); if(y==0) { save();//将结构体信息存盘 print();//输出输入的航班信息 break; } } } else printf("输入密码错误!请检查您的密码是否正确!谢谢!再见!\n\n"); } void save()//保存模块程序 { FILE *fp,*fp1;//定义文件指针 if((fp=fopen("chen.dat","wb"))==NULL)//打开文件并判断是否出错 { printf("创建文件失败!\n\n");//打印出错提示 getchar(); return; } if((fp1=fopen("hao.dat","wb"))==NULL)//打开文件并判断是否出错 { printf("创建文件失败!\n\n");//打印出错提示 getchar(); return; } for(i=0;i<m;i++) if(fwrite(&s[i],sizeof(struct air),1,fp)==0)//向文件写入数据,并判断是否出错 printf("向文件输入数据失败!\n\n"); fprintf(fp1,"%d",m); fclose(fp);//关闭文件 fclose(fp1);//关闭文件 } void read()//从文件读取信息模块 { FILE *fp,*fp1;//定义文件指针 if((fp=fopen("chen.dat","rb"))==NULL)//打开文件,并判断是否出错 { printf("出错,请检查文件是否存在,按任意键返回住菜单");//打印出错提示 getchar(); } if((fp1=fopen("hao.dat","rb"))==NULL)//打开文件并判断是否出错 { printf("创建文件失败!\n\n");//打印出错提示 getchar(); return; } fscanf(fp1,"%d",&m); fclose(fp1);//关闭文件 for(i=0;i<m;i++) { fread(&s[i],sizeof(air),1,fp);//从文件中读取信息 } fclose(fp);//关闭文件 } void print()//打印模块 { char w[10]; read();//调用读取文件函数 printf("航班号 起始站 终点站 时间 机票数\n"); for(i=0;i<m;i++) { printf(PRINT);//打印信息 } printf("请按任意键回车键结束返回上层菜单以:\n"); scanf("%s",w); } void search()//查询模块 { char name1[20]; char name2[20]; char ii[10]; int n,no; do { printf("请选择查找方式:\n\n");//打印查询方式菜单 printf("1.按航班号查找\n\n" "2.按终点站查找\n\n" "3.按航线查找\n\n" "0.返回\n\n"); printf("请在0-3中选择:\n\n" "按其他键以回车键结束返回主菜单:\n\n"); scanf("%d",&n);//读取查找方式 if(n==0) break; switch(n) { case 1: printf("请输入航班号:\n"); scanf("%d",&no);//航班号 break; case 2: printf("请输入终点站名称:\n"); scanf("%s",name2);//读取终点站 break; case 3: printf("请输入起始站名称:\n"); scanf("%s",name1);//读取起始站 printf("请输入终点站名称:\n"); scanf("%s",name2);//终点站 break; } read();//调用读取函数 for(i=0;i<m;i++) { if(strcmp(s[i].over,name1)==0||strcmp(s[i].over,name2)==0)//按终点站起始站判断输出条件 { printf("\n查找航班信息成功!\n"); printf("航班号 起始站 终点站 时间 机票数\n"); printf(PRINT);//打印信息 break; } if(s[i].num==no)//按航班号判断输出条件 { printf("\n查找航班信息成功!\n"); printf("航班号 起始站 终点站 时间 机票数\n"); printf(PRINT);//打印信息 break; } } no=0;//将航班号赋值为0 printf("没有您需要的信息或查找完毕:\n\n" "是否继续查找?请键入yes或no以回车键结束\n"); scanf("%s",ii); }while(strcmp(ii,"yes")==0);//判断结束 } void shanchu()//删除模块 { char name1[20]; char name2[ 20]; char ii[10]; char f[]="zhangbin0027";//设置密码 int no,n; printf("请输入密码并以回车键结束:\n\n"); scanf("%s",f);//读取密码 if(strcmp(f,"zhangbin0027")==0) //判断密码是否正确 { do { printf("请选择删除以方式回车键结束:\n\n");//打印删除方式菜单 printf("*1.按航班号删除\n\n" "*2.按航线删除\n\n" "*0.返回\n\n"); printf("请在0-2中选择以回车键结束:\n"); scanf("%d",&n);//读取删除方式 if(n==0) break; //跳出循环 switch(n) { case 1: printf("请输入航班号:\n"); scanf("%d",&no);//读取航班号 read();//调用读取函数 break;//跳出循环 case 2: printf("请输入起始站 名称:\n"); scanf("%s",name1);//读取起始站 printf("请输入终点站名称:\n"); scanf("%s",name2);//读取终点站 read();//调用读取函数 break;//跳出循环 } for(i=0;i<m;i++) { if(s[i].num==no||strcmp(s[i].start,name1)==0&&strcmp(s[i].over,name2)==0)//判断输入信息是否存在 { s[i]=s[m-1]; m--; } } printf("查找完毕或没有这个信息\n\n"); printf("是否继续删除\n"); printf("请键入yes或no以回车键结束\n"); scanf("%s",ii); //读取是否继续信息 save(); //调用读取函数 if(!strcmp(ii,"yes")) //判断是否继续删除 printf("请按任意键以回车键结束返回上层菜单:\n"); break; }while(n!=1&&n!=2&&n!=3&&n!=4&&n!=0); //判断结束 } else printf("对不起密码错误!您不是管理员,不能使用此项功能!谢谢!再见!\n\n"); } void dingpiao()//订票模块 { int n; char a[10]; do { search();//调用查询模块 printf("请输入您要订的机票数以回车键结束:\n"); scanf("%d",&n);//读取所订机票数 if(n<0) { printf("请输入有效的机票数!\n");//判断机票数是否出错 break; } if(s[i].count!=0&&s[i].count>=n)//判断是否出错 { s[i].count=s[i].count-n; save();//调用保存函数 printf("订票成功!\n\n"); break; } if(s[i].count<n)//判断是否出错 { printf("请输入有效的机票数:\n"); break; } printf("是否继续? 请输入yes或no以回车键结束:\n");//判断是否继续订票 scanf("%s",a); }while(!strcmp(a,"yes"));//判断结束 } void tuipiao()//退票模块 { int n; char a[10]; do { search();//调用查询模块 printf("请输入您要退的机票数目:\n"); scanf("%d",&n);//输入所退票数 if(n<0) //判断票数是否有效 printf("请输入有效的机票数!\n"); s[i].count=s[i].count+n; save(); //调用保存模块 printf("退票成功!\n\n"); printf("是否继续? 请键入yes或no以回车键结束:\n\n");//判断是否继续退票 scanf("%s",a); }while(!strcmp(a,"yes"));//判断并跳出循环 getchar(); } void xiugai() //修改模块 { struct xiu //定义结构体 { int no; char name1[20]; char name2[20]; char time[20]; int count; }x[1]; char j[10]; char f[]="zhangbin0027";//设置密码 int n; printf("请输入密码并以回车键结束:\n\n"); scanf("%s",f);//读取密码 if(strcmp(f,"zhangbin0027")==0)//判断是否出错 { read();//调用读取模块 do { printf( "请选择修改方式:\n\n" "*1,按航班号修改:\n\n" "*2,按航线修改: \n\n"); printf("请在1---2中修改以回车键结束:\n\n"); scanf("%d",&n);//读取修改方式 switch(n) { case 1:printf("请输入航班号:\n"); scanf("%d",&x[0].no);//读取航班号 break; case 2:printf("请输入起始站:\n"); scanf("%s",x[0].name1);//读取起始站 printf("请输入终点站:\n"); scanf("%s",x[0].name2);//读取终点站 break; } for(i=0;i<m;i++) { if(strcmp(s[i].over,x[0].name1)==0&&strcmp(s[i].over,x[0].name2)==0)//判断输出条件 { printf("航班号 起始站 终点站 时间 机票数\n"); printf(PRINT); break; } if(s[i].num==x[0].no)//判断输出条件 { printf("航班号 起始站 终点站 时间 机票数\n"); printf(PRINT); break; } } x[0].no=0; //将结构体中的号为零 printf("请输入新航班号、起始站、终点站、时间(星期几)、机票数:\n"); scanf("%d%s%s%s%d",&x[0].no,x[0].name1,x[0].name2,x[0].time,&x[0].count);//定义输入格式 s[i].num=x[0].no;//替换航班号 strcpy(s[i].start,x[0].name1);//替换其始站 strcpy(s[i].over,x[0].name2);//替换终点站 strcpy(s[i].time,x[0].time);//替换时间 s[i].count=x[0].count;//替换机票数 save();//调用保存模块 printf("是否继续?请键入yes或no以回车键结束:\n\n"); scanf("%s",j); }while(strcmp(j,"yes")==0); //判断结束 } else printf("对不起密码错误!您不是管理员,不能使用此项功能!谢谢!再见!\n\n"); }
链表操作中即使函数传入的是链表指针,若根节点没有改变,链表也会改变?
事情是这样的,今天刷剑指offer时,对书中的内容产生了一点点小质疑,所以就拿VS2013和Code::Blocks都跑了一遍,两者结果是一致的,但程序执行的结果让我有点疑惑。 题目如下: 在一个排序的链表中,删除链表中重复的节点。 例如: 1->2->3->3->4->4->5,删除后的结果为1->2->5。 书中说由于头节点也可能被删除,所以函数应申明为 ``` void deleteDuplication(ListNode** pHead) ``` 而不是 ``` void deleteDuplication(ListNode* pHead) ``` 然后我就试了一下第二者,发现如果函数deleteDuplication处理完毕后,如果以形参形式传入的根节点pHead没有发生改变,则在main()函数里打印出链表的时候,链表和处理前的不一样了(即发生了改变);但如果根节点发生了改变,在mian()函数里打印结果却发现链表和处理前一样(即没有发生改变)。 所以我就懵了,按书上这句话的意思,应该就是如果传入的根节点为链表指针(即ListNode* pHead),则链表应该出了函数也不会发生任何变化。 但实际的结果却是由根节点是否发生了变化而决定,求大家赐教哈。 (注:ListNode** pHead是正常的,却是是出了函数也会改变链表实参本身)。 还有一个问题就是如果在函数里delete掉形参链表一个节点,也会影响链表实参本身,这又是什么原理。 完整代码如下: 1)当形参根节点未发生变化时: ``` #include <stdio.h> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: void deleteDuplication(ListNode* pHead) { if (pHead == NULL || pHead->next == NULL) return; ListNode* pNode = pHead; ListNode* preNode = NULL; while (pNode) { bool deleteflag = false; if (pNode->next && pNode->val == pNode->next->val) deleteflag = true; if (!deleteflag) { preNode = pNode; pNode = pNode->next; } else { int value = pNode->val; ListNode* next = pNode; while (pNode && pNode->val == value) { next = pNode->next; //delete pNode; pNode = next; } if (preNode == NULL) pHead = pNode; else preNode->next = pNode; } } } }; int main() { //生成链表1->2->3->3->4->4->5 ListNode* pHead = new ListNode(1); pHead->next = new ListNode(2); ListNode* pNode = pHead; pNode = pNode->next; pNode->next = new ListNode(3); pNode = pNode->next; pNode->next = new ListNode(3); pNode = pNode->next; pNode->next = new ListNode(4); pNode = pNode->next; pNode->next = new ListNode(4); pNode = pNode->next; pNode->next = new ListNode(5); Solution so; so.deleteDuplication(pHead); pNode = pHead; while (pNode) { printf("%d ", pNode->val); pNode = pNode->next; } printf("\n"); return 0; } ``` 输出结果如下图: ![图片说明](https://img-ask.csdn.net/upload/201904/07/1554621274_199353.jpg) 2)当形参根节点发生变化时: ``` #include <stdio.h> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: void deleteDuplication(ListNode* pHead) { if (pHead == NULL || pHead->next == NULL) return; ListNode* pNode = pHead; ListNode* preNode = NULL; while (pNode) { bool deleteflag = false; if (pNode->next && pNode->val == pNode->next->val) deleteflag = true; if (!deleteflag) { preNode = pNode; pNode = pNode->next; } else { int value = pNode->val; ListNode* next = pNode; while (pNode && pNode->val == value) { next = pNode->next; //delete pNode; pNode = next; } if (preNode == NULL) pHead = pNode; else preNode->next = pNode; } } } }; int main() { //生成链表1->1->3->3->4->4->5 ListNode* pHead = new ListNode(1); pHead->next = new ListNode(1); ListNode* pNode = pHead; pNode = pNode->next; pNode->next = new ListNode(3); pNode = pNode->next; pNode->next = new ListNode(3); pNode = pNode->next; pNode->next = new ListNode(4); pNode = pNode->next; pNode->next = new ListNode(4); pNode = pNode->next; pNode->next = new ListNode(5); Solution so; so.deleteDuplication(pHead); pNode = pHead; while (pNode) { printf("%d ", pNode->val); pNode = pNode->next; } printf("\n"); return 0; } ``` 输出结果如下图: ![图片说明](https://img-ask.csdn.net/upload/201904/07/1554621424_901317.jpg) 3)当函数中delete掉形参链表的一个节点时 无论形参根节点是否改变,实现链表都会发生变化。且在VS2013下,形参根节点发生改变时,程序会报内存访问出错。 ``` #include <stdio.h> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: void deleteDuplication(ListNode* pHead) { if (pHead == NULL || pHead->next == NULL) return; ListNode* pNode = pHead; ListNode* preNode = NULL; while (pNode) { bool deleteflag = false; if (pNode->next && pNode->val == pNode->next->val) deleteflag = true; if (!deleteflag) { preNode = pNode; pNode = pNode->next; } else { int value = pNode->val; ListNode* next = pNode; while (pNode && pNode->val == value) { next = pNode->next; delete pNode; //删除当前节点 pNode = next; } if (preNode == NULL) pHead = pNode; else preNode->next = pNode; } } } }; int main() { ListNode* pHead = new ListNode(1); pHead->next = new ListNode(1); ListNode* pNode = pHead; pNode = pNode->next; pNode->next = new ListNode(3); pNode = pNode->next; pNode->next = new ListNode(3); pNode = pNode->next; pNode->next = new ListNode(4); pNode = pNode->next; pNode->next = new ListNode(4); pNode = pNode->next; pNode->next = new ListNode(5); Solution so; so.deleteDuplication(pHead); pNode = pHead; while (pNode) { printf("%d ", pNode->val); pNode = pNode->next; } printf("\n"); return 0; } ``` ![图片说明](https://img-ask.csdn.net/upload/201904/07/1554622769_237692.png)
为什么不允许删除循环单链表中最后一个结点?如何解决?
/*****************************************************/ /* 函数功能:建立一个空的循环单链表 */ /* 函数参数:无 */ /* 函数返回值:指向node类型变量的指针 */ /* 文件名:clnkinit.c,函数名init() */ /*****************************************************/ node *init() /*建立一个空的循环单链表*/ { return NULL; } /******************************************************/ /* 函数功能:获得循环单链表的最后一个结点的存储地址 */ /* 函数参数:指向node类型变量的指针变量head */ /* 函数返回值:指向node类型变量的指针 */ /* 文件名:clnklist.c,函数名:rear() */ /*******************************************************/ node *rear(node *head) { node *p; if(!head)/*循环单链表为空*/ p=NULL; else { p=head;/*从第一个结点开始*/ while(p->next!=head)/*没有到达最后一个结点*/ p=p->next;/*继续向后*/ } return p; } /*****************************************************/ /* 函数功能:输出循环单链表中各个结点的值 */ /* 函数参数:指向node类型变量的指针变量head */ /* 函数返回值:空 */ /* 文件名:clnklist.c,函数名:display() */ /*****************************************************/ void display(node *head) { node *p; if(!head) printf("\n循环单链表是空的!\n"); else { printf("\n循环单链表各个结点的值分别为:\n"); printf("%5d",head->info);/*输出非空表中第一个结点的值*/ p=head->next;/*p指向第一个结点的下一个结点*/ while(p!=head)/*没有回到第一个结点*/ { printf("%5d",p->info); p=p->next; } } }​ /*****************************************************/ /* 函数功能:循环单链表中查找值为x的结点的存储地址 */ /* 函数参数:指向node类型变量的指针变量head */ /* datatype类型的变量x */ /* 函数返回值:指向node类型变量的指针 */ /* 文件名:clnklist.c,函数名:find() */ /*****************************************************/ node *find(node *head,datatype x) { /*查找一个值为x的结点*/ node *q; if(!head) /*循环单链表是空的*/ { printf("\n循环单链表是空的!无法找指定结点!"); return NULL; } q=head;/* q指向循环单链表的第一个结点,准备查找*/ while(q->next!=head&&q->info!=x)/*没有查找到并且没有查找完整个表*/ q=q->next;/*继续查找*/ if(q->info==x) return q; else return NULL; } /*****************************************************/ /* 函数功能:循环单链表第i个结点后插入值为x的新结点*/ /* 函数参数:指向node类型变量的指针变量head */ /* datatype类型的变量x,int类型的变量i */ /* 函数返回值:指向node类型变量的指针 */ /* 文件名:clnklist.c,函数名:insert() */ /*****************************************************/ node *insert(node *head,datatype x,int i) {/*i为0时表示将值为x的结点插入作为循环单链表的第一个结点*/ node *p,*q,*myrear; int j; p=(node*)malloc(sizeof(node));/*分配空间*/ p->info=x;/*设置新结点的值*/ if(i<0)/*如果i小于0,则输出出错信息*/ {printf("\n无法找到指定的插入位置!"); free(p);return head;} if(i==0&&!head) /*插入前循环单链表如果是空的,则新结点的指针域应指向它自己*/ { p->next=p;head=p;return head;} if(i==0&&head) /*在非空的循环单链表最前面插入*/ { myrear=rear(head);/*找到循环单链表的最后一个结点*/ p->next=head; /*插入(1)*/ head=p; /*插入(2)*/ myrear->next=p;/*插入(3)最后一个结点的指针域指向新插入的表中第一个结点*/ return head; } if(i>0&&!head) {printf("\n无法找到指定的插入位置!"); free(p);return head;} if(i>0&&head) {/*在非空的循环单链表中插入值为x的结点,并且插入的结点不是第一个结点*/ q=head;/*准备从表中第一个结点开始查找*/ j=1;/*计数开始*/ while(i!=j&&q->next!=head)/*没有找到并且没有找遍整个表*/ { q=q->next;j++;/*继续查找,计数器加1*/ } if(i!=j)/* 找不到指定插入位置,即i的值超过表中结点的个数,则不进行插入*/ { printf("\n表中不存在第%d个结点,无法进行插入!\n",i);free(p); return head; } else { /*找到了第i个结点,插入x*/ p->next=q->next;/*插入,修改指针(1)*/ q->next=p;/*插入,修改指针(2)*/ return head; } } } /*****************************************************/ /* 函数功能:在循环单链表中删除一个值为x的结点 */ /* 函数参数:指向node类型变量的指针变量head */ /* datatype类型的变量x */ /* 函数返回值:指向node类型变量的指针 */ /* 文件名:clnklist.c,函数名:dele() */ /*****************************************************/ node *dele(node *head,datatype x) { node *pre=NULL,*q;/*q用于查找值为x的结点,pre指向q的前驱结点*/ if(!head)/*表为空,则无法做删除操作*/ { printf("\n循环单链表为空,无法做删除操作!"); return head; } q=head;/*从第1个结点开始准备查找*/ while(q->next!=head&&q->info!=x)/*没有找遍整个表并且没有找到*/ { pre=q; q=q->next;/*pre为q的前驱,继续查找*/ }/*循环结束后,pre为q的前驱*/ if(q->info!=x)/*没找到*/ { printf("没有找到值为%d的结点!",x); } else /*找到了,下面要删除q*/ { if(q!=head){pre->next=q->next;free(q);} else if(head->next==head){free(q);head=NULL; printf("ok1");} else {pre=head->next; while(pre->next!=q) pre=pre->next; /*找q的前驱结点位置*/ head=head->next; pre->next=head; free(q); printf("ok"); } } return head; } /*************************************/ /* 函数功能:循环单链表删除操作测试程序 */ /* 函数参数:无 */ /* 函数返回值:空 */ /* 文件名:test16 函数名:main() */ /*************************************/ #include "stdio.h" #include "conio.h" #include "slnklist.h" #include "clnklist.c" void main() { node *myhead,*tail; myhead=init(); display(myhead); myhead=insert(myhead,33,0); display(myhead); myhead=insert(myhead,55,1); display(myhead); myhead=insert(myhead,22,0); printf("\n\n在循环单链表最前面插入22后的结果为:\n"); /*读者可以在相应的地方加上输出语句,给予适当的提示*/ display(myhead); myhead=insert(myhead,77,3); display(myhead); tail=rear(myhead); printf("\n\n\n使用尾部结点的指针域,打印循环单链表的结果为:\n"); display(tail->next); myhead=dele(myhead,22); display(tail->next);//display(myhead); myhead=dele(myhead,33); display(tail->next);//display(myhead); myhead=dele(myhead,55); display(tail->next); myhead=dele(myhead,77); display(tail->next); getch(); } ![图片说明](https://img-ask.csdn.net/upload/201604/15/1460681850_322856.png)
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”,输出正常。并且在上一个线程中,一切正常。 求大神指点。
相见恨晚的超实用网站
相见恨晚的超实用网站 持续更新中。。。
字节跳动视频编解码面经
三四月份投了字节跳动的实习(图形图像岗位),然后hr打电话过来问了一下会不会opengl,c++,shador,当时只会一点c++,其他两个都不会,也就直接被拒了。 七月初内推了字节跳动的提前批,因为内推没有具体的岗位,hr又打电话问要不要考虑一下图形图像岗,我说实习投过这个岗位不合适,不会opengl和shador,然后hr就说秋招更看重基础。我当时想着能进去就不错了,管他哪个岗呢,就同意了面试...
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它是一个过程,是一个不断累积、不断沉淀、不断总结、善于传达自己的个人见解以及乐于分享的过程。
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过...
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、电子书搜索 对于大部分程序员...
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 free -m 其中:m表示兆,也可以用g,注意都要小写 Men:表示物理内存统计 total:表示物理内存总数(total=used+free) use...
比特币原理详解
一、什么是比特币 比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是国家信用。去中心化电子记账系统是参与者共同记账。比特币可以防止主权危机、信用风险。其好处不多做赘述,这一层面介绍的文章很多,本文主要从更深层的技术原理角度进行介绍。 二、问题引入 假设现有4个人...
python学习方法总结(内附python全套学习资料)
不要再问我python好不好学了 我之前做过半年少儿编程老师,一个小学四年级的小孩子都能在我的教学下独立完成python游戏,植物大战僵尸简单版,如果要肯花时间,接下来的网络开发也不是问题,人工智能也可以学个调包也没啥问题。。。。。所以python真的是想学就一定能学会的!!!! --------------------华丽的分割线-------------------------------- ...
python 简易微信实现(注册登录+数据库存储+聊天+GUI+文件传输)
socket+tkinter详解+简易微信实现 历经多天的努力,查阅了许多大佬的博客后终于实现了一个简易的微信O(∩_∩)O~~ 简易数据库的实现 使用pands+CSV实现数据库框架搭建 import socket import threading from pandas import * import pymysql import csv # 创建DataFrame对象 # 存储用户数据的表(...
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发...
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 演示地点演示 html代码如下` music 这个年纪 七月的风 音乐 ` 然后就是css`*{ margin: 0; padding: 0; text-decoration: none; list-...
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。
数据库优化 - SQL优化
以实际SQL入手,带你一步一步走上SQL优化之路!
2019年11月中国大陆编程语言排行榜
2019年11月2日,我统计了某招聘网站,获得有效程序员招聘数据9万条。针对招聘信息,提取编程语言关键字,并统计如下: 编程语言比例 rank pl_ percentage 1 java 33.62% 2 cpp 16.42% 3 c_sharp 12.82% 4 javascript 12.31% 5 python 7.93% 6 go 7.25% 7 p...
通俗易懂地给女朋友讲:线程池的内部原理
餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”
《奇巧淫技》系列-python!!每天早上八点自动发送天气预报邮件到QQ邮箱
将代码部署服务器,每日早上定时获取到天气数据,并发送到邮箱。 也可以说是一个小型人工智障。 知识可以运用在不同地方,不一定非是天气预报。
经典算法(5)杨辉三角
杨辉三角 是经典算法,这篇博客对它的算法思想进行了讲解,并有完整的代码实现。
Python实例大全(基于Python3.7.4)
博客说明: 这是自己写的有关python语言的一篇综合博客。 只作为知识广度和编程技巧学习,不过于追究学习深度,点到即止、会用即可。 主要是基础语句,如三大控制语句(顺序、分支、循环),随机数的生成,数据类型的区分和使用; 也会涉及常用的算法和数据结构,以及面试题相关经验; 主体部分是针对python的数据挖掘和数据分析,主要先攻爬虫方向:正则表达式匹配,常用数据清洗办法,scrapy及其他爬虫框架,数据存储方式及其实现; 最后还会粗略涉及人工智能领域,玩转大数据与云计算、进行相关的预测和分析。
腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
昨天,有网友私信我,说去阿里面试,彻底的被打击到了。问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题。无独有偶,今天笔者又发现有网友吐槽了一道腾讯的面试题,我们一起来看看。 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹? 在互联网职场论坛,一名程序员发帖求助到。二面腾讯,其中一个算法题:64匹...
面试官:你连RESTful都不知道我怎么敢要你?
干货,2019 RESTful最贱实践
刷了几千道算法题,这些我私藏的刷题网站都在这里了!
遥想当年,机缘巧合入了 ACM 的坑,周边巨擘林立,从此过上了"天天被虐似死狗"的生活… 然而我是谁,我可是死狗中的战斗鸡,智力不够那刷题来凑,开始了夜以继日哼哧哼哧刷题的日子,从此"读题与提交齐飞, AC 与 WA 一色 ",我惊喜的发现被题虐既刺激又有快感,那一刻我泪流满面。这么好的事儿作为一个正直的人绝不能自己独享,经过激烈的颅内斗争,我决定把我私藏的十几个 T 的,阿不,十几个刷题网...
为啥国人偏爱Mybatis,而老外喜欢Hibernate/JPA呢?
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行了一番讨论,感触还是有一些,于是就有了今天这篇文。 声明:本文不会下关于Mybatis和JPA两个持久层框架哪个更好这样的结论。只是摆事实,讲道理,所以,请各位看官勿喷。 一、事件起因 关于Mybatis和JPA孰优孰劣的问题,争论已经很多年了。一直也没有结论,毕竟每个人的喜好和习惯是大不相同的。我也看...
SQL-小白最佳入门sql查询一
不要偷偷的查询我的个人资料,即使你再喜欢我,也不要这样,真的不好;
JavaScript 为什么能活到现在?
作者 | 司徒正美 责编 |郭芮 出品 | CSDN(ID:CSDNnews) JavaScript能发展到现在的程度已经经历不少的坎坷,早产带来的某些缺陷是永久性的,因此浏览器才有禁用JavaScript的选项。甚至在jQuery时代有人问出这样的问题,jQuery与JavaScript哪个快?在Babel.js出来之前,发明一门全新的语言代码代替JavaScript...
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // doshom...
Nginx 原理和架构
Nginx 是一个免费的,开源的,高性能的 HTTP 服务器和反向代理,以及 IMAP / POP3 代理服务器。Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名。 Nginx 的整体架构 Nginx 里有一个 master 进程和多个 worker 进程。master 进程并不处理网络请求,主要负责调度工作进程:加载配置、启动工作进程及非停升级。worker 进程负责处...
致 Python 初学者
欢迎来到“Python进阶”专栏!来到这里的每一位同学,应该大致上学习了很多 Python 的基础知识,正在努力成长的过程中。在此期间,一定遇到了很多的困惑,对未来的学习方向感到迷茫。我非常理解你们所面临的处境。我从2007年开始接触 python 这门编程语言,从2009年开始单一使用 python 应对所有的开发工作,直至今天。回顾自己的学习过程,也曾经遇到过无数的困难,也曾经迷茫过、困惑过。开办这个专栏,正是为了帮助像我当年一样困惑的 Python 初学者走出困境、快速成长。希望我的经验能真正帮到你
Python 编程开发 实用经验和技巧
Python是一门很灵活的语言,也有很多实用的方法,有时候实现一个功能可以用多种方法实现,我这里总结了一些常用的方法和技巧,包括小数保留指定位小数、判断变量的数据类型、类方法@classmethod、制表符中文对齐、遍历字典、datetime.timedelta的使用等,会持续更新......
吐血推荐珍藏的Visual Studio Code插件
作为一名Java工程师,由于工作需要,最近一个月一直在写NodeJS,这种经历可以说是一部辛酸史了。好在有神器Visual Studio Code陪伴,让我的这段经历没有更加困难。眼看这段经历要告一段落了,今天就来给大家分享一下我常用的一些VSC的插件。 VSC的插件安装方法很简单,只需要点击左侧最下方的插件栏选项,然后就可以搜索你想要的插件了。 下面我们进入正题 Material Theme ...
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,...
相关热词 c#中dns类 c#合并的excel c# implicit c#怎么保留3个小数点 c# 串口通信、 网络调试助手c# c# 泛型比较大小 c#解压分卷问题 c#启动居中 c# 逻辑或运算符
立即提问