C语言中指针释放问题,函数free()的使用。

各位大虾们,C语言中如果不是指向使用malloc,realloc、calloc动态申请的内存的指针,是不是就不需要free()释放该指针了呢? 比如说申请了一个指向结构体的指针,
或者是指向一个整型变量的指针。谢谢各位大虾。

3个回答

如果你没用*alloc *函数的话,你应该并没有申请内存,你只是定义了一个指针变量而已,当然就不用free释放了。

对。用malloc,realloc、calloc等动态分配的内存必须用free()释放。
不是动态分配的内存,不需要用free释放。

你动态申请了内存,就必须要释放。
如果使用一个指针,指向一块已经存在内存,就不用去释放它。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
C语言 在使用free函数释放空间时,为什么会出现debug assertion failed?是内存分配问题还是指针设置问题呀?
``` #include<stdio.h> #include<stdlib.h> int main() { int *Int; /*定义指针变量、数组及整型变量*/ int Number[2]; int i,j; Int=(int*)malloc(sizeof(Int)); /*赋予动态内存*/ for(i=0;i<3;i++) /*循环语句输入数字*/ { Int=Number; /*指针指向变量*/ printf("请输入第%d个数:",i+1); scanf("%d",Int+i); } for(j=0;j<3;j++) /*输出结果*/ { printf("第%d个数为:%d\n",j+1,Number[j]); } free(Int); /*释放空间*/ return 0; /*程序结束*/ } ```
C语言 间接级别不同(指针和指针函数方面)
出现指针和指针函数级别不同的问题。(初学者,代码比较小白轻喷) 在每一个函数给指针赋值的时候都出现这个问题。 下面是警告内容warning: passing argument 1 of 'creation' from incompatible pointer type 顺便提问一下给指针分配空间的问题,头指针的初始化必须要分配空间么? 因为当我把NULL赋值给头指针后再试图让头指针的next指向链表的时候就会弹出程序停止的问题。如果程序中有发现其他问题也希望一并指出,谢谢各位 ``` #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct type { int num; char name[20]; int age; char sex[20]; char cla[20]; }elem; typedef struct Node { elem stm; struct Node *next; }node; node *creation(node *n) { n = (node*)malloc(sizeof(node)); n->next = NULL; return n; } node *add(node *n, node *p) { node *s, *ss; s = n; ss = p; while (s->next == ss) { if (s->next != NULL) s = s->next; if (s->next == NULL && ss->next == NULL) s->next = ss; } return s; } int main() { node *p, *head, *n, *pp, *headd, *tot, *tothd, *scan; char str[20]; n = head = headd = tothd = (node*)malloc(sizeof(node)); tot = (node*)malloc(40 * sizeof(node)); tothd->next = tot; p = creation(&p);//赋值的时候有问题 pp = creation(&pp);//赋值的时候有问题 head->next = p; headd->next = pp; printf("The first data num name age sex class(num=-1 to end).\n"); while (scanf("%d", &p->stm.num)&&p->stm.num != -1) { n->next = p; p->next = NULL; p = (node*)malloc(sizeof(node)); scanf("%s", str); strcpy(p->stm.name, str); scanf("%d", &p->stm.age); scanf("%s", str); strcpy(p->stm.sex, str); scanf("%s", str); strcpy(p->stm.cla, str); n = p; } free(n); n = (node*)malloc(sizeof(node)); printf("The second data num name age sex class(num=-1 to end).\n"); while (scanf("%d", &pp->stm.num) && pp->stm.num != -1) { n->next = pp; pp->next = NULL; pp = (node*)malloc(sizeof(node)); scanf("%s", str); strcpy(pp->stm.name, str); scanf("%d", &pp->stm.age); scanf("%s", str); strcpy(pp->stm.sex, str); scanf("%s", str); strcpy(pp->stm.cla, str); n = pp; } p = head->next; pp = headd->next; tot = add(&p, &pp);//赋值的时候有问题 scan = tothd->next; while (scan->next != NULL) { printf("%d ", scan->stm.age); } } ```
为什么尾插法循环链表在插入时会出错?
调试时发现插入函数在调用时没有响应,百思不得其解。 ``` #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <windows.h> //结构体定义 typedef struct node { int x; int y; struct node *next; }Node,*Snack; //所用函数 void initsnack(Snack s); void insert_node(Snack s,int x,int y);//问题所在函数 void show(Snack s); int main() { Snack s; initsnack(s); insert_node(s,12,17); insert_node(s,15,16); show(s); } void initsnack(Snack s) { //初始化蛇身并赋值 带尾指针循环链表 s=(Node*)malloc(sizeof(Node)); s->next=s; printf("OK1\n"); } void insert_node(Snack s,int x,int y) { //插入节点 Snack p=(Node *)malloc(sizeof(Node)); if(!p) printf("overflow"); p->x=x; p->y=y; s->next=p;//调试时显示程序到这儿就不往下进行了,为什么啊? p->next=s; s=p; free(p); printf("OK2\n"); } void show(Snack s) { //显示函数 Snack p=(Snack)malloc(sizeof(Node)); p=s->next; while(p->next!=s->next) { p=p->next; printf("x=%d,y=%d\n",p->x,p->y); } } ```
单链表中删除节点后游离的节点怎么释放内存空间,不能用free,系统会自动回收吗?
![图片说明](https://img-ask.csdn.net/upload/201909/22/1569128268_998691.png) 如上图,指针指向了红色的节点,但由于 free 函数只能作用于malloc等函数,那这里的红色的节点如何释放内存呢,不过不管,系统会不会自动回收,如果不回收,如果大量存在这样的节点,不是很占用内存吗?
结构体内指针字符数组的释放
问题:结构体成员char* name和结构体struct student* studentIOS同时释放的话回报错,错误见代码中注释。请问这里要怎么释放呢?还是结构体里面不能这样使用指针字符数组? #include <stdio.h> #include <stdlib.h> struct student{ int id; //长度:4 char* name; //8 int score[2]; //8 float avgScore; //4 }; void input(struct student*); void output(struct student*); void input(struct student* stu){ printf("(1)程序最多接受50名学生的信息,多余的无法录入\n"); printf("(2)不足50人,请输入-1结束输入\n"); for (int i=0; i<50; ++i) { (stu+i)->name = (char*)malloc(15 * sizeof(char)); //给结构体中学生的name分配空间 printf("请在下面输入第%d名学生的信息\n",i+1); printf("序号:"); scanf("%d",&(stu+i)->id); if (-1 == (stu+i)->id) { //输入-1的时候,停止输入;退出输入函数 printf("输入结束\n"); return ; } printf("姓名:"); //gets((stu+i)->name); scanf("%s",(stu+i)->name); printf("C语言成绩:"); scanf("%d",&(stu+i)->score[0]); printf("数序成绩:"); scanf("%d",&(stu+i)->score[1]); (stu + i)->avgScore =( (stu + i)->score[0] + (stu + i)->score[1])/2.0; } return; } void output(struct student* stu){ printf("学生信息如下\n"); printf("学号\t\t姓名\t\tC语言\t数学\t\t平均\n"); for (int i=0; i<50; ++i,++stu) { if (stu->id == -1) { break; } printf("%d\t\t%s\t\t%d\t\t%d\t\t%.2f",stu->id,stu->name,stu->score[0],stu->score[1],stu->avgScore); printf("\n"); } return; } int main(int argc, const char * argv[]) { struct student* studentIOS = (struct student*)malloc(50 * sizeof(struct student)); input(studentIOS); //output(studentIOS); // printf("%p\n%p",studentIOS->name,&studentIOS->name); //输出不同 /* 释放每个学生的name空间,或者释放学生结构体的空间, 测试发现二者只能释放一个 */ //释放每个学生中的name空间 #if 0 //加上此循环,程序出问题,提示studentIOS未malloc for (int i=0; i<50; ++i,++studentIOS) { if (NULL != studentIOS->name) { free(studentIOS->name); studentIOS->name = NULL; } } #endif #if 0 //加上下面的两句不会出问题 free((studentIOS+10)->name); (studentIOS+10)->name = NULL; #endif free(studentIOS); studentIOS = NULL; return 0; }
搜索二叉树的非递归中序遍历(使用栈),遇到错误:Segmentation fault: 11(mac系统,gcc编译)
``` typedef int TreeEle; // 树节点的数据域的类型 typedef struct TreeNode *PtrTNode; typedef PtrTNode StackEle; // 栈的节点的数据域的类型 typedef struct StackNode *PtrSNode; typedef struct TreeNode { TreeEle ele; PtrTNode left; PtrTNode right; }TreeNode; typedef struct StackNode { StackEle ele; PtrSNode next; }StackNode; PtrTNode CreateBinTree(); // 创建空二叉树 bool IsTreeEmpty(PtrTNode Root); // 判断树是否空 PtrTNode InsertTree(PtrTNode Root, TreeEle data); // 向二叉搜索树里添加一个数据(先递归查找,再添加) PtrTNode DeleteTree(PtrTNode Root, TreeEle data); // 从二叉搜索树中删除一个数据(也是先递归查找) void InOrderTraversal(PtrTNode Root); // 中序遍历 void PreOrderTraversal_stack(PtrTNode Root); // 不使用递归的中序遍历(该函数有问题) PtrSNode CreateStack(); // 创建空栈 bool IsStackEmpty(PtrSNode top); // 判断栈是否为空 void Push(PtrSNode top, StackEle data); // 入栈 StackEle Pop(PtrSNode top); // 出栈 //-------------Tree----------------- PtrTNode CreateBinTree() { PtrTNode R = (PtrTNode)malloc(sizeof(TreeNode)); if (NULL != R) { R->ele = 100; R->left = R->right = NULL; } return R; } PtrTNode InsertTree(PtrTNode Root, TreeEle data) { if (NULL == Root) // 若原树为空,生成并返回一个节点的二叉搜索树 { Root = (PtrTNode)malloc(sizeof(TreeNode)); Root->ele = data; Root->left = Root->right = NULL; } else if (data < Root->ele) { Root->left = InsertTree(Root->left, data); // 递归插入左子树 } else if (data > Root->ele) { Root->right = InsertTree(Root->right, data); // 递归插入右子树 } return Root; } void InOrderTraversal(PtrTNode Root) { if (NULL != Root) { PreOrderTraversal(Root->left); printf("%d ", Root->ele); PreOrderTraversal(Root->right); } } // 有问题,估计是栈的问题,不是树的问题 void PreOrderTraversal_stack(PtrTNode Root) { PtrSNode S = CreateStack(); PtrTNode T = Root; while ((NULL != T) || (false == IsStackEmpty(S))) // 只要栈里还有结点未被弹出,就循环 { while (NULL != T) // 一路向左,并将沿途节点压入栈中 { Push(S, T->left); T = T->left; } if (false == IsStackEmpty(S)) { T = Pop(S); printf("%d ", T->ele); T = T->right; } } } bool IsTreeEmpty(PtrTNode Root) { return ((NULL == Root->left) && (NULL == Root->right)); } //------------------------------------------ //---------------Stack----------------------- PtrSNode CreateStack() { PtrSNode S; S = (PtrSNode)malloc(sizeof(StackNode)); return S; } bool IsStackEmpty(PtrSNode top) { return (NULL == top->next); } void Push(PtrSNode top, StackEle data) { PtrSNode S = (PtrSNode)malloc(sizeof(StackNode)); S->ele = data; S->next = top->next; top->next = S; } StackEle Pop(PtrSNode top) { if ((NULL == top) || (NULL == top->next)) { printf("error!\n"); return NULL; } StackEle data = top->next->ele; PtrSNode S = top->next; top->next = top->next->next; // free(S); return data; } //--------------------------------- int main() { PtrTNode Root = CreateBinTree(); Root = InsertTree(Root, 25); Root = InsertTree(Root, 40); Root = InsertTree(Root, 112); Root = InsertTree(Root, 312); Root = InsertTree(Root, 12); Root = InsertTree(Root, 172); InOrderTraversal(Root); // 使用递归的中序遍历没有问题 printf("\n"); PreOrderTraversal_stack(Root); // 使用非递归的中序遍历有问题 printf("\n"); return 0; } ``` 输出为: 25 12 40 100 112 312 172 Segmentation fault: 11 应该不是遍历函数的问题(),遍历函数的逻辑是没有错的 个人认为是栈的写法有问题,网上搜索说该错误是由于使用了野指针或空指针,但是我看了几遍也没有看出问题,特来求助广大网友,望解答
修改程序:信源编解码(c语言)
修改程序:问题1。源文件source文本空间太长汉字太多无法运行2,未按频度要求排序 问题描述: 信源编解码是通信系统的重要组成部分。本实验旨在通过程序设计实现基于哈夫曼编码的信源编解码算法。程序具备以下功能: 对于给定的源文档 SourceDoc.txt, 1) 统计其中所有字符的频度(某字符的频度等于其出现的总次数除以总字符数) , 包括字母(区分大小写) 、标点符号及格式控制符(空格、回车等) 。 2) 按频度统计结果生成哈夫曼编码码表。 3) 基于哈夫曼码表进行编码,生成对应的二进制码流,并输出到文件 Encode.dat。 4) 对二进制码流进行哈夫曼解码,把结果输出到文件 DecodeDoc.txt。 5) 判断DecodeDoc.txt与SourceDoc.txt内容是否一致,以 验证编解码系统的正确性。 要求: 1) 用 C 语言实现。 2) 用子函数实现各功能模块。 3) 输出文件 Statistic.txt,包含的信息有:按频度大小排序的字符表,及各字符出现 的次数、频度及哈夫曼编码。 4) 应至少包含链表、二叉树的数据结构。 5) 不能用冒泡排序算法。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/stat.h> #include<sys/types.h> #include<fcntl.h> #include<unistd.h> #include<errno.h> #define N 10000 int count = 0; //每增加一个新的字符, count增加1, 可表示a中的字符种类数, 也即哈夫曼树叶子点个数 /*定义哈夫曼树结构体*/ typedef struct HuffmanTree{ int weight; int parent; int Lchild; int Rchild; }HuffmanTree[2*N]; /*定义储存字符及其出现次数的结构体*/ typedef struct DifferentCharacter{ char char_date; int num; //相同字符出现的次数 char a_code[100]; //每种字符对应的编码 }difcha[N]; /*在一定范围内选择两个weight最小的结点, 并将两个结点的序号赋给s1, s2*/ void select_two(HuffmanTree ht, int j, int *s1, int *s2) { int i = 1, temp; int min1 = 0, min2 = 0; while( (ht[i].parent != 0) && (i <= j) ) i++; *s1 = i; min1 = ht[i++].weight; while( (ht[i].parent != 0) && (i <= j) ) i++; *s2 = i; min2 = ht[i++].weight; if(min1 > min2){ temp = min1; min1 = min2; min2 = temp; } for(; i <= j; i++){ //遍历parent不为0的结点 if(ht[i].parent != 0) continue; if(ht[i].weight <= min1){ min2 = min1; min1 = ht[i].weight; *s2 = *s1; *s1 = i; } else if( (ht[i].weight < min2) && (ht[i].weight > min1) ) { min2 = ht[i].weight; *s2 = i; } } } /*建哈夫曼树*/ void EstHuffmanTree(HuffmanTree ht, int *w, int n){ int i; int s1 = 0, s2 = 0; for(i = 1; i <= n; i++){ //初始化哈夫曼树, 前n个单元存放叶子点 ht[i].weight = w[i]; ht[i].parent = 0; ht[i].Lchild = 0; ht[i].Rchild = 0; } for(i = n+1; i <= 2*n-1; i++){ //后n-1个单元存放非叶子点 ht[i].weight = 0; ht[i].parent = 0; ht[i].Lchild = 0; ht[i].Rchild = 0; } for(i = n+1; i <= 2*n-1; i++){ select_two(ht, i-1, &s1, &s2); //创建非叶子点, 建立哈夫曼树, 每次在ht[1]~ht[i-1]范围内选两个最小的weight结点,并将其序号赋给s1, s2 ht[i].weight = ht[s1].weight + ht[s2].weight; ht[i].Lchild = s1; ht[i].Rchild = s2; ht[s1].parent = i; ht[s2].parent = i; } //哈夫曼树建立完毕 } /*求哈弗曼编码*/ void CrtHuffmanCode(HuffmanTree ht, char **hcd, int n){ int start = 0, c = 0, p = 0, i; char *cd = (char*)malloc(n*sizeof(char)); //分配求当前编码的工作空间 cd[n-1] = '\0'; //从左向右存放编码 for(i = 1; i <= n; i++) { start = n-1; //初始化编码起始指针 c = i; p = ht[i].parent; while(p != 0){ start--; if(ht[p].Lchild == c) cd[start] = '0'; //左分支标0 else cd[start] = '1'; //右分支标1 c = p; //向上倒推 p = ht[c].parent; } hcd[i] = (char*)malloc((n-start)*sizeof(char)); strcpy(hcd[i], &cd[start]); } free(cd); } /*自定义错误处理函数*/ void my_err(char *err_string, int line){ printf("Line %d:\n", line); perror(err_string); exit(1); } /*从 buf_read 中统计每个字符出现的次数,将次数作为该字符的权值*/ void Statistics(difcha a, char *buf_read){ int i, j = 0; for(i = 0; i < strlen(buf_read) ; i++){ //对buf_read中的字符遍历 for(j = 0; j < count; j++){ //检查是否是新的字符 if(a[j].char_date == buf_read[i]){ a[j].num++; //若是旧字符, 则num++; break; } } if(j == count){ //若是新字符, 则记录到a中, 且对应的num++ a[count].char_date = buf_read[i]; a[count].num++; count++; //更新count } } } /*从 SourceDoc.txt 读取数据到 buf_read */ void ReadFile(char *pathName, char *buf_read){ int fd_date; int len = 0; if( (fd_date = open(pathName, O_RDWR)) < 0) //以读写方式打开SourceDoc.txt文件 my_err("open SourceDoc.txt", __LINE__); if(lseek(fd_date, 0, SEEK_END) < 0) //获取文件长度,并保持文件读写指针在文件开始处 my_err("lseek", __LINE__); if( (len = lseek(fd_date, 0, SEEK_CUR)) < 0 ) my_err("lseek", __LINE__); if(lseek(fd_date, 0, SEEK_SET) < 0) my_err("lseek", __LINE__); if(read(fd_date, buf_read, len) > len) //从SourceDoc.txt中读取内容 my_err("read SourceDoc.txt", __LINE__); } /*将 buf_code 写入 Encode.dat 中*/ void WriteFile(char *pathName, char *buf_code){ int fd_code; if((fd_code = open(pathName, O_CREAT|O_TRUNC|O_RDWR, S_IRWXU)) < 0) //创建Encode.dat文件 my_err("open Encode.dat", __LINE__); if( write(fd_code, buf_code, strlen(buf_code)) != strlen(buf_code) ) //将 buf_code 写入Encode.dat my_err("write Encode.dat", __LINE__); } /*主函数*/ void main(){ char buf_read[N] = {'\0'}; char buf_code[N] = {'\0'}; char buf_yima[N] = {'\0'}; char *hcd[N]; char temp[50] = {'\0'}; difcha a; int i, j, n, k = 0, m = 0; int w[N] = {0}; HuffmanTree ht; ReadFile("SourceDoc.txt", buf_read); Statistics(a, buf_read); for(i = 0; i < count; i++) w[i+1] = a[i].num; EstHuffmanTree(ht, w, count); //建HuffmanTree CrtHuffmanCode(ht, hcd, count); //对树中字符进行编码 for(i = 1; i <= count; i++) //将每个字符对应的编码存入结构体 a 中 strcpy(a[i-1].a_code, hcd[i]); FILE *fp1; fp1=fopen("Statistic.txt","w"); for(i = 0; i < count; i++) //查看每个字符的权值和对应的编码 fprintf(fp1,"%c %d %s\n", a[i].char_date, a[i].num, a[i].a_code); fclose(fp1); for(i = 0; i < strlen(buf_read) ; i++){ //遍历 buf_read, 给 SourceDoc.txt 中每个字符匹配编码, 存入 buf_code 中 for(j = 0; j < count; j++){ if(buf_read[i] == a[j].char_date){ strcat(buf_code, a[j].a_code); break; } } if(j == count) //匹配异常 printf("Unknown Character: %c\n", buf_read[i]); } WriteFile("Encode.dat", buf_code); //将 buf_code 写入 Encode.dat 中 ReadFile("Encode.dat", buf_read); //从 Encode.dat 中读取全部编码 n = strlen(buf_read); for(i = 0; i < n; i++){ //为 Encode.dat 中的编码匹配字符 temp[k++] = buf_read[i]; for(j = 0; j < count; j++){ if(strcmp(temp, a[j].a_code) == 0){ buf_yima[m++] = a[j].char_date; break; } } if(j < count){ //匹配成功, 对 temp 初始化 for(;k > 0; k--) temp[k] = '\0'; } } FILE *fp2; fp2=fopen("DecodeDoc.txt","w"); fprintf(fp2,"%s", buf_yima); fclose(fp2); }
一个无法解析的外部命令
project产生如下报错: 1.一个无法解析的外部命令 2.无法解析的外部符号 _main,该符号在函数 "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) 中被引用 ``` #include<stdio.h> #include<stdlib.h> struct student { char name[20]; int score; struct student* pnext;//指向下一个学生的指针 }; int count=0; struct student* create() { struct student *phead = NULL; struct student* pend, * pnew; pend = (struct student*)malloc(sizeof(struct student)); pnew = (struct student*)malloc(sizeof(struct student)); scanf_s("%s", &pnew->name, 20); scanf_s("%d", &pnew->score); while (pnew->score != 0) { count++; if (count == 1) { pend = pnew; phead = pnew; } else { pnew->pnext = NULL; pend->pnext = pnew; pend = pnew; } pnew = (struct student*)malloc(sizeof(struct student)); scanf_s("%s", &pnew->name, 20); scanf_s("%d", &pnew->score); } free(pnew); return phead; } ```
c语言警告问题,主函数里有一个警告
#include<stdio.h> #include <malloc.h> #include <conio.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define QueueElementType BitTree typedef int DataType; typedef struct BitNode { DataType data; struct BitNode *LChild; struct BitNode *RChild; }BitNode,*BitTree; typedef struct Node {QueueElementType data; struct Node *next; }LinkQueueNode; typedef struct BitTree {LinkQueueNode *front; LinkQueueNode *rear; }LinkQueue; int InitQueue(LinkQueue *Q)/*将Q初始化为一个空的链队列*/ {Q->front=(LinkQueueNode*)malloc(sizeof(LinkQueueNode)); if(Q->front!=NULL) {Q->rear=Q->front; Q->front->next=NULL; return(TRUE); } else return(FALSE);/*溢出*/ } int EnterQueue(LinkQueue *Q,QueueElementType x) {LinkQueueNode *NewNode; NewNode=(LinkQueueNode*)malloc(sizeof(LinkQueueNode)); if(NewNode!=NULL) {NewNode->data=x; NewNode->next=NULL; Q->rear->next=NewNode; Q->rear=NewNode; return(TRUE); } else return(FALSE);/*溢出*/ } int DeleteQueue(LinkQueue *Q,QueueElementType *x) {LinkQueueNode *p; if(Q->front==Q->rear) return(FALSE); p=Q->front->next; Q->front->next=p->next;/*队头元素出队*/ if(Q->rear==p) Q->rear=Q->front; *x=p->data; free(p); return(TRUE); } int IsEmpty(LinkQueue *Q) {if((Q->front)==(Q->rear)) return TRUE; else return FALSE; } int CreatBiTree(BitTree *bt)/*用扩展先序遍历序列创建二叉树,如果是#当前树根置为空,否则申请一个新节点*/ { char ch; do {scanf("%c",&ch); }while(ch=='\n'); if(ch=='0') *bt=NULL; else { *bt=(BitTree)malloc(sizeof(BitNode)); (*bt)->data=ch; CreatBiTree(&((*bt)->LChild)); CreatBiTree(&((*bt)->RChild)); } return OK; } void Visit(char ch)/*访问根节点*/ { printf("%c",ch); } void PreOrder(BitTree root) /*先序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/ { if (root!=NULL) { Visit(root ->data); /*访问根结点*/ PreOrder(root ->LChild); /*先序遍历左子树*/ PreOrder(root ->RChild); /*先序遍历右子树*/ } } void InOrder(BitTree root) /*中序遍历二叉树, root为指向二叉树(或某一子树)根结点的指针*/ { if (root!=NULL) { InOrder(root ->LChild); /*中序遍历左子树*/ Visit(root ->data); /*访问根结点*/ InOrder(root ->RChild); /*中序遍历右子树*/ } } void PostOrder(BitTree root) /* 后序遍历二叉树,root为指向二叉树(或某一子树)根结点的指针*/ { if(root!=NULL) { PostOrder(root ->LChild); /*后序遍历左子树*/ PostOrder(root ->RChild); /*后序遍历右子树*/ Visit(root ->data); /*访问根结点*/ } } int LayerOrder(BitTree bt) {LinkQueue Q; BitTree p; InitQueue(&Q);/*初始化队列*/ if(bt==NULL) return ERROR;/*二叉树为空树则结束遍历*/ EnterQueue(&Q,bt);/*二叉树非空则根节点bt入队,开始层次遍历*/ while(IsEmpty(&Q)!=1) /*若队列非空则遍历继续*/ {DeleteQueue(&Q,&p);/*对头元素出对并访问*/ Visit(p->data); if(p->LChild!=NULL) EnterQueue(&Q,p->LChild);/*若p的左孩子非空则入队*/ if(p->RChild!=NULL) EnterQueue(&Q,p->RChild); } return OK; } void path(BitTree root,char r) {BitNode *p,*q; int i,top=0; BitTree s[50]; q=NULL; p=root; while(p!=NULL||top!=0) {while(p!=NULL) {top++; if(top>=50) exit(0); s[top]=p; p=p->LChild; } if(top>0) {p=s[top]; if(p->RChild==NULL||p->RChild==q) {if(p->data==r) {for(i=1;i<=top;i++) printf("%c",s[i]->data); return ; } else {q=p; top--; p=NULL; } } else p=p->RChild; } } } int main() { BitTree T; int h,x; char *r; printf("请选择一下内容:\n"); printf("1.建立二叉树的存储结构。\n"); printf("2.求二叉树先序遍历序列。\n"); printf("3.求二叉树中序遍历序列。\n"); printf("4.求二叉树后序遍历序列。\n"); printf("5.求二叉树的层序遍历序列。\n"); printf("6.求根节点到指定节点的路径。\n"); do{ printf("请做出选择:"); scanf("%d",&h); switch(h) {case 1:printf("请输入二叉树中的元素(以扩展先序遍历序列输入,其中.代表空子树):\n"); CreatBiTree(&T);break; case 2:printf("先序遍历序列为:"); PreOrder(T);break; case 3:printf("\n中序遍历序列为:"); InOrder(T);break; case 4:printf("\n后序遍历序列为:"); PostOrder(T);break; case 5:printf("\n层序遍历序列为:"); LayerOrder(T); break; case 6:printf("\n根节点到指定节点的路径:"); scanf("%c",&r); path(T,r); break; } }while(h!=0); printf("退出"); } [Warning] passing arg 2 of `path' makes integer from pointer without a cast 这个警告怎么处理啊!!!
【C语言-链表】请问怎么判断链表已经被销毁?
【问题描述】学习链表,销毁链表总感觉没有成功,请问怎么确定链表确实被销毁了?为什么其余节点的内容没有变化? 【代码】 ``` #include<stdio.h> #include<stdlib.h> #include<string.h> struct link_list { int num; char name[20]; struct link_list *next; }; typedef struct link_list ls; int icount = 0; /*链表长度*/ /*链表创建函数*/ ls* create() { ls *phead = NULL; ls *pend, *pnew; char flag; /******************************************************************* 链表循环赋值 *******************************************************************/ while(1) { pnew = (ls*)malloc(sizeof(struct link_list));/*分配空间*/ if(pnew == NULL) /*检测内存分配情况*/ { printf("内存分配失败\n"); return NULL; } if(0 == icount)/*如果是第一个节点*/ { icount++; pnew->next = NULL;/*尾指针指向空*/ phead = pnew;/*头指针指向头节点*/ pend = pnew;/*保存当前指针*/ printf("phead=%d\n", phead); printf("输入姓名:\n"); scanf("%s", pnew->name); printf("输入学号:\n"); scanf("%d", &pnew->num); printf("是否结束输入?y结束,n继续\n"); getchar(); flag = getchar(); if(flag == 'y') { return phead; } } else { icount++; pend->next = pnew; pend = pnew; pnew->next = NULL; printf("输入姓名:\n"); scanf("%s", pnew->name); printf("输入学号:\n"); scanf("%d", &pnew->num); printf("是否结束输入?y结束,n继续"); getchar(); flag = getchar(); if(flag == 'y') { return phead; } } } } /*遍历输出*/ void print(ls* phead) { ls* ptemp; ptemp = phead; while(NULL != ptemp) { printf("\n\n学号:%d\n姓名:%s\n", ptemp->num, ptemp->name); ptemp = ptemp->next; } } /*销毁*/ void damage(ls* phead) { ls *ptemp1; do { printf("删除前节点内容%d 地址phead=%d\n", phead->num, phead); ptemp1 = phead->next; /*保存当前销毁节点指向的地址*/ printf("被销毁节点指向的地址ptemp1=%d\n", ptemp1); free(phead); /*释放当前指针指向的节点空间*/ printf("释放后节点内容%d\n", phead->num); printf("释放后phead=%d\n", phead); phead = ptemp1; /*获取下一个节点地址*/ printf("重新赋值phead=%d\n\n", phead); }while(ptemp1 != NULL); } int main(void) { ls* phead = NULL; int lcat, lcat_del; phead = create(); printf("主函数头指针地址%d\n", phead); print(phead); damage(phead); return 0; } ``` 【运行结果】 ![图片说明](https://img-ask.csdn.net/upload/201912/21/1576889257_479546.png) ![图片说明](https://img-ask.csdn.net/upload/201912/21/1576889268_527655.png)
c语言,形参是指针的引用,和形参是指针,两者结果不同,求指点
自定义的头文件 ``` typedef struct BiTNode { int data; struct BiTNode *lchild, *rchild; }BiTNode, *BiTree; ``` 如下是使用形参是指针的引用的函数,结果是正确的 ``` #include "BiTree.h" #include "stdlib.h" #include "stdio.h" bool Delete(BiTree &p) { BiTree q = (BiTree)malloc(sizeof(BiTNode)); q = p; p = p->lchild; free(q); return true; } bool DeleteBST(BiTree &T, int key) { if (!T)return false; else if (key==T->data) { return Delete(T); } else if (key < T->data) { return DeleteBST(T->lchild, key); } } int main() { BiTree t1 = (BiTree)malloc(sizeof(BiTNode)); BiTree t2 = (BiTree)malloc(sizeof(BiTNode)); BiTree t3 = (BiTree)malloc(sizeof(BiTNode)); t1->data = 3; t2->data = 2; t3->data = 1; t1->lchild = t2; t1->rchild = NULL; t2->lchild = t3; t2->rchild = NULL; DeleteBST(t1, 2); printf("%d\n", t1->lchild->data); system("PAUSE"); return 0; } ``` 结果 ![图片说明](https://img-ask.csdn.net/upload/201605/26/1464229127_799521.png) 然后如下是形参为指针的,其实函数是一样的,只是形参从上面的接收指针的引用改为了接收指针 ``` #include "BiTree.h" #include "stdlib.h" #include "stdio.h" bool Delete(BiTree p) { BiTree q = (BiTree)malloc(sizeof(BiTNode)); q = p; p = p->lchild; free(q); return true; } bool DeleteBST(BiTree T, int key) { if (!T)return false; else if (key==T->data) { return Delete(T); } else if (key < T->data) { return DeleteBST(T->lchild, key); } } int main() { BiTree t1 = (BiTree)malloc(sizeof(BiTNode)); BiTree t2 = (BiTree)malloc(sizeof(BiTNode)); BiTree t3 = (BiTree)malloc(sizeof(BiTNode)); t1->data = 3; t2->data = 2; t3->data = 1; t1->lchild = t2; t1->rchild = NULL; t2->lchild = t3; t2->rchild = NULL; DeleteBST(t1, 2); printf("%d\n", t1->lchild->data); system("PAUSE"); return 0; } ``` 结果 ![图片说明](https://img-ask.csdn.net/upload/201605/26/1464229251_539966.png) 结果明显是有问题的,原因应该在free了第2个结点,却没把第一个结点的lchild改为指向第3个结点。可是为什么前一个(即接收指针的引用那个)却没问题呢?两个的区别仅仅在于接收的参数,可是前一个没问题而后一个出了问题。我想不明白前一个为什么会没出问题,求大神指点
预习数据结构用C语言写链队出现的一个小问题,可能关于指针
可以编译,但是没有办法运行 用vs调试,我猜测问题出现在指针初始化上面 (init 函数) ``` #include<stdio.h> #include<malloc.h> typedef struct node { struct node *next; int data; } QNode; // typedef struct aaa { QNode *front; QNode *rear; //指针指向 QNode 类型 }LQueue; // 初始化 void init (QNode *s,LQueue *L) { s= (struct node* )malloc( sizeof(struct node)); L= (LQueue* )malloc( sizeof(LQueue)); s->next=NULL; L->front=L->rear=(struct node* )malloc( sizeof(struct node)) ; L->front=L->rear= s; } //入队 void push (LQueue *l,int x) { QNode *q=NULL; q= (struct node* )malloc( sizeof(struct node)); q->data=x; q->next=NULL; l->rear->next=q; l->rear = q; } QNode *pop (QNode *p,LQueue *L,int *x) { QNode *s=NULL; s=L->front; L->front=L->front->next; *x = s->data; free(s); } //测试 int main(void) { int x=1;int *x1=NULL; QNode *a = NULL; LQueue *b =NULL; init (a,b); push( b ,x); // printf("%d",L->rear->data); } ```
C语言新手,想请教大佬们一个关于在函数内(不是主函数)分配内存的问题
程序的enter函数是将一个字符串数组名 和一个字符串名,还有字符串数组的数目传到函数里,字符串数组里的每个字符串都动态申请内存。先输入字符串 ,然后将字符串复制给字符串数组里各个元素。 程序没有报错和警告,也没有输出但是没法正常运行。 而且我好像是第二次遇到这种在自定义函数内申请内存,然后没法正常运行的情况了,百度上说指针越界的问题,看不大懂,请大佬们解惑,谢谢。 #include<stdio.h> #include<stdlib.h> #include<string.h> void enter(char *p[] , char *p1 , int n){ for(int i = 0;i < n;i++){ printf("Enter num%d string: ", i + 1); scanf("%s" , p[i]); if((p[i] = (char*)malloc(strlen(p1) + 1)) == NULL){ printf("defalut"); exit(1); } strcpy(p[i] , p1); } } int main(){ int n; printf("Enter the number of strings: "); scanf("%d" , &n); char *strings[n] , s[20]; enter(strings , s , n); for(int i = 0;i < n;i++){ printf("%s" , strings[i]); free(strings); } }
求解,为什么没有输出???
/*Q4638.(10分)创建单向链表 要求:自定义函数create(),实现创建一个链表, 将此函数定义为指针类型,使其返回值为指针值,返回值指向一个struct LNode类型数据,实际上是返回链表的头指针。 在main()函数中调用自定义函数create(),实现创建一个链表,并将链表中的数据输出。 最后别忘了释放链表内存。这里使用malloc()函数实现动态开辟存储单元。 声明struct LNode类型,代码如下: struct LNode { int data; struct LNode *next; }; 程序运行结果示例: 输入: 输入你想创建的结点个数:3 输入整数: 1 2 3 输出: 结果是: 1 2 3 输入提示:"输入你想创建的结点个数:" 输入格式:"%d" 输入提示:"输入整数:\n" 输入格式:"%d" 输出提示:"结果是:\n" 输出格式:"%d "*/ #include<stdio.h> #include<stdlib.h> struct LNode { int data; struct LNode *next; }D; struct LNode*create() { int n,i; struct LNode*pHead=NULL,*pNew,*pTail; printf("输入你想创建的结点个数:"); scanf("%d",&n); printf("输入整数:\n"); for(i=0;i<n;i++) { pNew=(struct LNode*)malloc(sizeof(struct LNode*)); scanf("%d",&pNew->data); if(pHead==NULL) pHead=pNew=pTail; else { pTail->next=pNew; pTail=pNew; } } return pHead; } void List(LNode *pHead) { struct LNode *p=pHead; while(p!=NULL) { printf("%d",p->data); p=p->next; } return; } int main() { LNode *p=NULL; p=create(); printf("结果是:\n"); List(p); void free(LNode *p); return 0; }
关于c语言从文件中读取学生信息,处理并打印
![图片说明](https://img-ask.csdn.net/upload/201712/07/1512617928_774992.png) b) 建议函数流程: i. 打开数据文件,失败返回-1; ii. 从头到尾扫描数据文件(即预读一遍)获得学生人数; iii. 根据学生人数,利用malloc和sizeof等函数或运算符为struct student** pStudents分配内存; iv. 利用rewind函数,定位到文件头; v. 读取数据文件,并把每一条记录通过数组下标法或指针法保存到结构体数组pStudents中; vi. 关闭文件; vii. 返回学生人数。 c) 数据文件格式说明: 一行一条学生信息的记录,不同属性用空格隔开,输入数据中无总成绩记录,例如: 张三 通信 89 93 95 李四 网络 88 91 94 王五 物联网 71 94 88 3. 编写统计函数: a) 函数定义void Count(struct student pStudents[], int num)。输入参数分别为保存学生的结构体数组和学生人数。 b) 功能为:统计所有学生的总成绩和每个专业(假定一共三个专业:通信,网络,物联网)的平均成绩;输入参数包括学生信息结构体数组,学生人数,返回的每个学生的总成绩直接填充到对应的输入结构体数组对应字段中。统计信息包括三个专业的总人数、平均成绩数组,用全局变量来表示。访问每个学生信息的时候,用指针来指向当前正在处理的学生。 c) 设计一个或者三个带参数的宏,判断输入的字符串是否是指定的专业名称,并在函数Count中使用。 5. 编写main函数实现: a) 定义变量,其中保存学生信息的数据文件直接在源代码中初始化; b) 读取学生信息,如果失败,打印失败信息并退出程序; c) 统计学生信息; d) 输出统计信息。 e) 释放内存。 ``` #include <stdio.h> #include <stdlib.h> #include <string.h> struct student{ char name[15]; char major[15]; int Eng_sco; int cal_sco; int c_sco; int sum; }; int tx_per=0,tx_ave,tx_sum=0; int wl_per=0,wl_ave,wl_sum=0; int wlw_per=0,wlw_ave,wlw_sum=0; int ReadStudentInfo(const char* filename, struct student** pStudents); void Count(struct student pStudents[], int num); int main() { int count; int m; struct student *list; count=ReadStudentInfo("readme.txt", &list); printf("学生信息: \n"); printf("----------------------------------------------------\n"); printf("序号 姓 名 专业名称 英语成绩 线性代数成绩 c语言成绩 总成绩\n"); for(m=1;m<=count;m++) { printf("%4d %s %s %4d %4d %4d %4d\n",m,(list+m-1)->name,(list+m-1)->major,(list+m-1)->Eng_sco,(list+m-1)->cal_sco,(list+m-1)->c_sco,(list+m-1)->sum); } Count(list, count); printf("\n统计信息 :\n"); printf("----------------------------------------------------\n"); printf("序号 专业名称 学生人数 平均成绩\n"); printf(" 1 通信 %d %d\n",tx_per,tx_ave); printf(" 2 网络 %d %d\n",wl_per,wl_ave); printf(" 3 物联网 %d %d\n",wlw_per,wlw_ave); return 0; } int ReadStudentInfo(const char* filename, struct student** pStudents) { FILE *fp; char ch; int i=1,j; fp=fopen(readme.txt,"r"); if(fp==NULL) { printf("cann't open the file"); exit(-1); } ch=fgetc(fp); while(ch!=EOF) { if(ch=='\n') { i++; } ch=fgetc(fp); } rewind(fp); *pStudents=(struct student*)malloc(sizeof(** pStudents)*i); for(j=0;j<i;j++) { fread(&*pStudents[j],sizeof(struct student)-sizeof(int),1,fp); (*pStudents+j)->sum=((*pStudents+j)->Eng_sco+(*pStudents+j)->cal_sco+(*pStudents+j)->c_sco); } fclose(fp); return i; } void Count(struct student pStudents[], int num) { int n=1; for(n=1;n<=num;n++) { if(!strcmp((pStudents+n-1)->major,"通信")) { tx_per++; tx_sum=tx_sum+(pStudents+n-1)->sum; } if(!strcmp((pStudents+n-1)->major,"网络")) { wl_per++; wl_sum=wl_sum+(pStudents+n-1)->sum; } if(!strcmp((pStudents+n-1)->major,"物联网")) { wlw_per++; wlw_sum=wlw_sum+(pStudents+n-1)->sum; } tx_ave=tx_sum/tx_per; wl_ave=wl_sum/wl_per; wlw_ave=wlw_sum/wlw_per; } free(pStudents); } ``` 运行不起来,是哪里出问题了?
(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>
关于C语言链表的一些问题,代码怎么都运行不成功跪求大神指点
下面代码主要实现链表的创建,插入,删除,并且能将两个年龄递增链表进行合并成递减链表 然而在插入和删除操作中gets函数无法起作用,strcmp函数也出现位置冲突报错。。功力不足实在解决不了。。跪求大神解答。。(感觉自己写的东西除了上面两个错误应该还有,但是因为位置冲突问题就只能编译到那个地方无法进行下去。。我肉眼实在找不出来。。 ``` #include<stdio.h> #include<stdlib.h> #include<string.h> int a[10]={0}; int c[10]={0}; char b[100][10]; char d[100][10]; typedef struct stuInfo { char stuName[10];/*学生姓名*/ int age; /*年龄*/ } ElemType; typedef struct node { ElemType data; struct node *next; }LNode,*ListPtr;/*定义结构*/ ListPtr List_Init(int a[],char b[][10],int n){/*链表载入数据*/ LNode *s,*h; int i; h=NULL; h=(LNode*)malloc(sizeof(LNode)); h->data.age=0; memset(h->data.stuName,0,10*sizeof(char)); h->next=NULL; for(i=n-1;i>=0;i--) { s=(LNode*)malloc(sizeof(LNode));/*分配内存*/ memset(s->data.stuName,0,10*sizeof(char)); s->data.age=a[i];/*把年龄载入*/ strcpy(s->data.stuName,b[i]);/*把名字载入*/ s->next=h->next;/*新的结点指向头节点的下一个结点*/ h->next=s;/*头结点指向新的结点*/ } return h; } ListPtr List_Insert (ListPtr h, ElemType x){/*结点插入*/ LNode *s; s=(LNode*)malloc(sizeof(LNode)); s->data.age=x.age; strcpy(s->data.stuName,x.stuName);/*分配空间结点载入*/ s->next=h->next;/*新的结点指向前一个结点的后一个结点*/ h->next=s;/*前一个结点指向新结点*/ return h; } void List_Destroy(ListPtr h,ListPtr L){ LNode *s,*p; s=L->next;/*指向第一个结点*/ p=s; while(s){/*寻找所要删除的数据结点的前一个结点*/ if(s->data.age==h->data.age&&strcmp(s->data.stuName,h->data.stuName)==0) break; p=s; s=s->next; } s=p->next;/*s指定要删除的结点*/ p->next=s->next;/*前一个结点指向所要删除结点的后一个结点*/ free(s); } ListPtr List_Merge(ListPtr La, ListPtr Lb){/*链表变换,使递增链表变为递减链表,并去重*/ LNode *s, *pa, *pb; pa=La->next; pb=Lb->next;/*各指向两个链表的头结点*/ La->next=NULL; while(pa!=NULL&&pb!=NULL){ if(pa->data.age<=pb->data.age){ s=pa->next; pa->next=La->next; La->next=pa; pa=s;/*如果pa指向的年龄比pb的小则保留并逆置,pa指针指向下一个数据*/ if(strcmp(pa->data.stuName,pb->data.stuName)==0){ pb=pb->next;/*如果pa和pb所指的是同一个人,则pb也指向下一个数据,避免重复*/ } } else{ s=pb->next; pb->next=La->next; La->next=pb; pb=s; }/*如果pb指向的年龄比pa的小,则插入到La链表中*/ } while(pa!=NULL){ s=pa->next; pa->next=La->next; La->next=pa; pa=s;}/*处理La未处理的数据*/ while(pb!=NULL){ s=pb->next; pb->next=La->next; La->next=pb; pb=s;}/*处理Lb未处理的数据*/ Lb->next=NULL; free(Lb);/*释放Lb*/ } void OutPut(ListPtr La){/*输出链表*/ LNode *s; s=La->next; while(s){ printf("%s\t%d\n",s->data.stuName, s->data.age); } } int main(){ ElemType x; int n,i,j; ListPtr La=NULL, Lb=NULL; LNode *p,*r; for(i=0;i<10;i++){ memset(b[i],0,10*sizeof(char)); memset(d[i],0,10*sizeof(char)); }/*初始化字符串数组*/ strcpy(b[0],"Levis");a[0]=22; strcpy(b[1],"Adam");a[1]=23; strcpy(b[2],"Lord");a[2]=26; strcpy(b[3],"Fred");a[3]=28; strcpy(b[4],"May");a[4]=30; strcpy(b[5],"York");a[5]=35; La=List_Init(a, b, 6); /*La数据载入*/ strcpy(d[0],"Yuki");c[0]=19; strcpy(d[1],"Soraru");c[1]=27; strcpy(d[2],"Katin");c[2]=29; strcpy(d[3],"Sinsan");c[3]=31; strcpy(d[4],"York");c[4]=35; Lb=List_Init(c, d, 5); /*Lb数据载入*/ printf("choose operation: 1. insert 2. delete 3.nothing: "); scanf("%d",&j); if(j==1){ printf("enter the student's name you want to insert:");/*插入数据操作*/ gets(x.stuName); printf("enter the student's age:"); scanf("%d",&x.age); p=La->next; while(p){/*查找La中是否有此人*/ if(strcmp(p->data.stuName,x.stuName)==0) break; p=p->next; } if(p=NULL){/*如果没则寻找插入位置*/ p=La->next;r=p; while (p){ if(x.age<=p->data.age) break; r=p; p=p->next;/*找到比它大的值后,r记录此结点的前一个结点*/ } List_Insert (r, x);/*在r后插入此数据结点*/ } else{ p=Lb->next;/*La中已有此人,则查找Lb*/ while(p){ if(strcmp(p->data.stuName,x.stuName)==0) break; p=p->next; } if(p=NULL){ p=Lb->next;r=p; while (p){ if(x.age<=p->data.age) break; r=p; p=p->next; } List_Insert (r, x);}}/*同La*/ if(p!=NULL){ printf("inserted fail");}/*如果两链表中已有此人,则表示插入失败*/ } if(j==2){ printf("enter the student's name you want to delete:");/*进行删除操作*/ gets(x.stuName); printf("which lianbiao do you choose, if La, input 1;Lb,input 2:");/*选择要插入的链表*/ scanf("%d",&i); if(i==1){ p=La->next; while(p){ if(strcmp(p->data.stuName,x.stuName)==0)/*查找La中此人的位置*/ break; p=p->next;/*移动到下一个结点*/ } if(p!=NULL){ List_Destroy(p,La);} else {printf("查无此人");}/*移动到下一个结点*/ } if(i==2){ p=Lb->next; while(p){ if(strcmp(p->data.stuName,x.stuName)==0) break; p=p->next; } if(p!=NULL){List_Destroy(p,Lb);} else {printf("查无此人");}}/*同La*/ } printf("now ranking......\n");/*显示递增合并为递减的信息*/ List_Merge(La, Lb); OutPut(La);/*输出函数*/ return 0; } ``` 然而在插入和删除操作中gets函数无法起作用,strcmp函数也出现位置冲突报错。。功力不足实在解决不了。。跪求大神解答。。(感觉自己写的东西除了上面两个错误应该还有,但是因为位置冲突问题就只能编译到那个地方无法进行下去。。我肉眼实在找不出来。。
C++哈夫曼编码译码器设计与实现并对哈夫曼树进行先序遍历。
现在就是差一个先序遍历的要求没有做到 ``` #include<stdio.h> #include<string.h> #include<stdlib.h> //树结点定义 typedef struct { int weight; int parent; int lchild; int rchild; }HTNode,*HuffmanTree; static char N[100];//用于保存正文 //哈弗曼编码,char型二级指针 typedef char **HuffmanCode; //封装最小权结点和次小权结点 typedef struct { int s1; int s2; }MinCode; //函数声明 void Error(char *message); HuffmanCode HuffmanCoding(HuffmanTree &HT,HuffmanCode HC,int *w,int n); MinCode Select(HuffmanTree HT,int n); //当输入1个结点时的错误提示 void Error(char *message) { fprintf(stderr,"Error:%s\n",message); //根据指定的格式,向输出流写入数据 exit(1); } //构造哈夫曼树HT,编码存放在HC中,w为权值,n为结点个数 HuffmanCode HuffmanCoding(HuffmanTree &HT,HuffmanCode HC,int *w,int n) { int i,s1=0,s2=0; HuffmanTree p; char *cd; int f,c,start,m; MinCode min; if(n<=1) { Error("Code too small!");//只有一个结点不进行编码,直接exit(1)退出。 } m=2*n-1;//哈弗曼编码需要开辟的结点大小为2n-1 HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//开辟哈夫曼树结点空间 m+1 ,动态内存分配。 //初始化n个叶子结点,w[0] = 0,main函数已赋值 for(p=HT,i=0;i<=n;i++,p++,w++) { p->weight=*w; p->parent=0; p->lchild=0; p->rchild=0; } //将n-1个非叶子结点的初始化 for(;i<=m;i++,p++) { p->weight=0; p->parent=0; p->lchild=0; p->rchild=0; } //构造哈夫曼树 for(i=n+1;i<=m;i++) { min=Select(HT,i-1);//找出最小和次小的两个结点 s1=min.s1 ; //最小结点下标 s2=min.s2;//次小结点下标 HT[s1].parent=i; HT[s2].parent=i; HT[i].lchild=s1; HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } //打印哈弗曼树 printf("HT List:\n"); printf("Number\t\tweight\t\tparent\t\tlchild\t\trchild\n"); for(i=1;i<=m;i++) { printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\t\n",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild); } //从叶子结点到根节点求每个字符的哈弗曼编码 HC=(HuffmanCode)malloc((n+1)*sizeof(char *)); cd=(char *)malloc(n*sizeof(char *));//为哈弗曼编码动态分配空间 cd[n-1]='\0';//如:3个结点编码最长为2。cd[3-1] = '\0'; //求叶子结点的哈弗曼编码 for(i=1;i<=n;i++) { start=n-1; //定义左子树为0,右子树为1 /* 从最下面的1号节点开始往顶部编码(逆序存放),然后编码2号节点,3号...... */ for(c=i,f=HT[i].parent; f!=0; c=f,f=HT[f].parent) { if(HT[f].lchild==c) cd[--start]='0'; else cd[--start]='1'; } //为第i个字符分配编码空间 HC[i]=(char *)malloc((n-start)*sizeof(char *)); //将当前求出结点的哈弗曼编码复制到HC strcpy(HC[i],&cd[start]); } free(cd); return HC; } MinCode Select(HuffmanTree HT,int n) { int min,secmin; int temp = 0; int i,s1,s2,tempi = 0; MinCode code ; s1=1; s2=1; min = 9999; //找出权值最小的结点,下标保存在s1中 for(i=1;i<=n;i++) { if(HT[i].weight<min && HT[i].parent==0) { min=HT[i].weight; s1=i; } } secmin = 9999; //找出权值次小的结点,下标保存在s2中 for(i=1;i<=n;i++) { if((HT[i].weight<secmin) && (i!=s1) && HT[i].parent==0) { secmin=HT[i].weight; s2=i; } } //放进封装中 code.s1=s1; code.s2=s2; return code; } void HuffmanTranslateCoding(HuffmanTree HT, int n,char* ch) {//译码过程 int m=2*n-1; int i,j=0; printf("After Translation:"); while(ch[j]!='\0')//ch[]:你输入的要译码的0101010串 { i=m; while(0 != HT[i].lchild && 0 != HT[i].rchild)//从顶部找到最下面 { if('0' == ch[j])//0 往左子树走 { i=HT[i].lchild; } else//1 往右子树走 { i=HT[i].rchild; } ++j;//下一个路径 } printf("%c",N[i-1]);//打印出来 } printf("\n"); } void main() { HuffmanTree HT=NULL; HuffmanCode HC=NULL; int *w=NULL; int i,n; char tran[100]; printf("Input N(char):"); gets(N); fflush(stdin); n = strlen(N); w=(int *)malloc((n+1)*sizeof(int *));//开辟n+1个长度的int指针空间 w[0]=0; printf("Enter weight:\n"); //输入结点权值 for(i=1;i<=n;i++) { printf("w[%d]=",i); scanf("%d",&w[i]); } fflush(stdin); //清空输入缓冲区 //构造哈夫曼树HT,编码存放在HC中,w为权值,n为结点个数 HC=HuffmanCoding(HT,HC,w,n); //输出哈弗曼编码 printf("HuffmanCode:\n"); printf("Number\t\tWeight\t\tCode\n"); for(i=1;i<=n;i++) { printf("%c\t\t%d\t\t%s\n",N[i-1],w[i],HC[i]); } fflush(stdin); //译码过程 printf("Input HuffmanTranslateCoding:"); gets(tran); HuffmanTranslateCoding(HT, n, tran); return; } ```题目要求:九、哈夫曼编码译码器设计与实现 编写程序设计哈夫曼编码译码器。 (1)根据输入的权值建立哈夫曼树。 (2)对建立好的哈夫曼树进行先序遍历。 (3)利用建好的哈夫曼树生成哈夫曼编码,并显示生成的各字符的哈夫曼编码。 (4)根据输入的字符进行译码。 (5)显示功能:以先序遍历的顺序显示建立好的哈夫曼树。显示哈夫曼编码和译码的结果。
通讯录管理系统: 通过电话号码查询通讯录,查不出东西。
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<windows.h> struct stu //第一部分:声明结构体类型struct stu { char name[100];//姓名为字符串型 char cel[50];//手机 char tel[50];//电话 char mail[50];//邮件 char add[100];//地址为字符串型 char post[15];//邮编 char qq[50]; char gend[2]; struct stu *next;//用指针处理链表,next是指针变量,指向结构体变量 }; struct stu *charu(struct stu *head,struct stu *q)//第二部分:插入函数(插入新结点) { struct stu *p; for(p=head; p->next!=NULL; p=p->next); //for(使p也指向head;当p为空文件时 ;p指向下一个结点) p->next=q; q->next=NULL; return head; } void search(struct stu *head) //第三部分:查找结点并输出 { struct stu *p; int a;//要查找的电话 if(head->next==NULL)//头文件为空时打印出的结果为"通讯录为空" printf("**********************************通讯录为空!!!*********************************\n\n\n"); else//头文件不为空时,开始查询学生的信息 { printf("\t输入要查询的电话号码:"); scanf("%d",&a); for(p=head->next; p->next!=NULL; p=p->next) //for(使p也指向head;当p为空文件时 ;p指向下一个结点) { if(p->cel==a) //如果输入的电话号码和某个相同,输出以下的东西。 { printf(" 要查找的学生信息为:\n"); printf(" ★姓名:"); puts(p->name); printf("\t性别:"); puts(p->gend); printf("\t地址:"); puts(p->add); printf("\t邮编:"); puts(p->post); printf("\t手机号"); puts(p->cel); printf("\tQQ:"); puts(p->qq); printf("\t邮箱"); puts(p->mail); printf("\t查找成功!!!"); printf("\n\n\n"); break; } } if(p->cel==a) { printf(" 要查找的学生信息为:\n"); printf(" ★姓名:"); puts(p->name); printf("\t性别:"); puts(p->gend); printf("\t地址:"); puts(p->add); printf("\t邮编:"); puts(p->post); printf("\t手机号"); puts(p->cel); printf("\tQQ:"); puts(p->qq); printf("\t邮箱"); puts(p->mail); printf("\t查找成功!!!"); printf("\n\n\n"); } else printf("no people have found!!!\n");//如果不符合,就输出没有找到 } } struct stu *del(struct stu *head) //第四部分:删除结点 { struct stu *p,*q; int a;//要删除的电话号码 if(head->next==NULL)// 头文件为空时,输出通讯录为空 printf("**********************************通讯录为空!!!*********************************\n\n\n"); else { printf("\t输入要删除电话号码:"); scanf("%d",&a); for(p=head,q=p->next; q->cel!=a&&q->next!=NULL;) { p=p->next; q=p->next; } if(q->cel==a) { p->next=q->next; free(q);//释放q,也就是删除q,在这里就是删除q(学号为a) printf("删除成功!!!\n"); } else printf("no people have found!!!");//如果不符合,就输出没有找到 } return head;//返回头文件 } struct stu *change(struct stu *head) //第五部分:修改结点内容 { int b,a,c; struct stu *p; if(head->next==NULL)// 头文件为空时,输出通讯录为空 printf("**********************************通讯录为空!!!*********************************\n\n\n"); else { printf(" 输入要修改电话号码:"); scanf("%d",&a); for(p=head->next; p!=NULL; p=p->next) { start: printf(" 输入想要修改什么?\n"); printf("\t\t\t 1:修改姓名\n"); printf("\t\t\t 2:性别\n"); printf("\t\t\t 3:地址\n"); printf("\t\t\t 4:邮编\n"); printf("\t\t\t 5:手机号\n"); printf("\t\t\t 6:QQ\n"); printf("\t\t\t 7:邮箱\n"); printf(" 请输入你的选择:"); scanf("%d",&b); switch(b)//先通过学号找到该学生,然后用switch语句选择修改项,再用switch和goto语句实现是否循环 { case 1: printf("\t输入新姓名:"); scanf("%s",p->name); break; case 2: printf("\t输入新的性别:"); scanf("%s",p->gend); break; case 3: printf("\t输入新的地址:"); scanf("%s",p->add); break; case 4: printf("\t输入新的邮编;"); scanf("%s",p->post); break; case 5: printf("\t输入新的手机号:"); scanf("%s",p->cel); break; case 6: printf("\t输入新的QQ:"); scanf("%s",p->qq); break; case 7: printf("\t输入新的邮箱;"); scanf("%s",p->mail); break; default: printf("输入操作错误,请重新输入:"); } printf("修改成功!!!\n"); printf(" 是否要修改其他项? 1:是 2:否\n"); printf(" 请输入你的选择:"); scanf("%d",&c); switch(c) //goto语句实现是否循环 { case 1: goto start; case 2: break; } } } return head; //返回头文件 } void printall(struct stu *head) //第六部分:输出全部通讯录 { struct stu *p=head->next; while(1) { if(p==NULL) { printf("**********************************通讯录为空!!!*********************************\n\n\n"); break; } else if(p->next==NULL) { printf(" ★姓名:"); puts(p->name); printf("\t性别:"); puts(p->gend); printf("\t地址:"); puts(p->add); printf("\t邮编:"); puts(p->post); printf("\t电话:"); puts(p->tel); printf("\tQQ:"); puts(p->qq); printf("\t邮箱:"); puts(p->mail); printf("输出成功!!!\n"); printf("\n\n\n"); break; } else { printf(" ★姓名:"); puts(p->name); printf("\t性别:"); puts(p->gend); printf("\t地址:"); puts(p->add); printf("\t邮编:"); puts(p->post); printf("\t电话:"); puts(p->tel); printf("\tQQ:"); puts(p->qq); printf("\t邮箱:"); puts(p->mail); printf("\n"); p=p->next; continue; } printf("输出成功!!!\n"); } } void sf(struct stu *head) //第八部分:释放结点退出系统 { struct stu *p=head ; printf("释放链表:\n"); while(p!=NULL) { head=head->next; free(p); p=head; } printf("释放链表成功!!!\n"); } int main()// 第九部分:主函数框架 { int cz;//操作符 struct stu *head,*q; head=(struct stu*)malloc(sizeof(struct stu));//动态链表malloc head->next=NULL;//使next指向下一个结点,next结点不放其他结点地址 system("color fc");//修改dos窗口前背景色,用两个十六进制数表示 printf("班级: 姓名: 学号: 设计课题:个人通讯录管理系统\n"); printf("\n********************************C语言课程设计***********************************\n"); printf(" *******************★个人通讯录管理系统★*****************\n\n\n"); printf(" * 1:新建通讯录 *\n"); printf(" * 2:删除通讯录 *\n"); printf(" * 3:修改通讯录 *\n"); printf(" * 4:查询通讯录 *\n"); printf(" * 5:显示全部记录 *\n"); printf(" * 6:释放链表并结束程序 *\n"); printf(" *********************************************************\n"); start : printf("输入操作符1-6:");//"输入操作符1- scanf("%d",&cz); switch(cz)//switch语句 { case 1: q=(struct stu *)malloc(sizeof(struct stu)); printf("\t输入姓名:"); scanf("%s",q->name); printf("\t输入性别:"); scanf("%s",q->gend); printf("\t地址:"); scanf("%s",&q->add); printf("\t输入邮编:"); scanf("%s",&q->post); printf("\t手机号:"); scanf("%s",q->cel); printf("\tQQ号:"); scanf("%s",q->qq); printf("\t输入电子邮件:"); scanf("%s",q->mail); charu(head,q); printf("插入成功!!!\n"); break; case 2://删除 head=del(head); break; case 3: change(head); break;//修改学生信息 case 4: search(head); break;//查找结点head case 5: printall(head); break; //保存文件 case 6: //释放结点退出系统 sf(head); exit (0); default: printf("输入操作错误,重新"); //什么也不符合就"输入操作错误,重新" } goto start;//用goto语句实现循环操作 return 0; }
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过...
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、电子书搜索 对于大部分程序员...
卸载 x 雷某度!GitHub 标星 1.5w+,从此我只用这款全能高速下载工具!
作者 | Rocky0429 来源 | Python空间 大家好,我是 Rocky0429,一个喜欢在网上收集各种资源的蒟蒻… 网上资源眼花缭乱,下载的方式也同样千奇百怪,比如 BT 下载,磁力链接,网盘资源等等等等,下个资源可真不容易,不一样的方式要用不同的下载软件,因此某比较有名的 x 雷和某度网盘成了我经常使用的工具。 作为一个没有钱的穷鬼,某度网盘几十 kb 的下载速度让我...
2019年还剩1天,我从外包公司离职了
这日子过的可真快啊,2019年还剩1天,外包公司干了不到3个月,我离职了
《面试宝典》2019年springmvc面试高频题(java)
前言 2019即将过去,伴随我们即将迎来的又是新的一年,过完春节,马上又要迎来新的金三银四面试季。那么,作为程序猿的你,是否真的有所准备的呢,亦或是安于本职工作,继续做好手头上的事情。 当然,不论选择如何,假如你真的准备在之后的金三银四跳槽的话,那么作为一个Java工程师,就不可不看了。如何在几个月的时间里,快速的为即将到来的面试进行充分的准备呢? 1、什么是Spring MVC ?简单...
计算机网络的核心概念
这是《计算机网络》系列文章的第二篇文章 我们第一篇文章讲述了计算机网络的基本概念,互联网的基本名词,什么是协议以及几种接入网以及网络传输的物理媒体,那么本篇文章我们来探讨一下网络核心、交换网络、时延、丢包、吞吐量以及计算机网络的协议层次和网络攻击。 网络核心 网络的核心是由因特网端系统和链路构成的网状网络,下面这幅图正确的表达了这一点 那么在不同的 ISP 和本地以及家庭网络是如何交换信息的呢?...
python自动下载图片
近日闲来无事,总有一种无形的力量萦绕在朕身边,让朕精神涣散,昏昏欲睡。 可是,像朕这么有职业操守的社畜怎么能在上班期间睡瞌睡呢,我不禁陷入了沉思。。。。 突然旁边的IOS同事问:‘嘿,兄弟,我发现一个网站的图片很有意思啊,能不能帮我保存下来提升我的开发灵感?’ 作为一个坚强的社畜怎么能说自己不行呢,当时朕就不假思索的答应:‘oh, It’s simple. Wait for me a few
一名大专同学的四个问题
【前言】   收到一封来信,赶上各种事情拖了几日,利用今天要放下工作的时机,做个回复。   2020年到了,就以这一封信,作为开年标志吧。 【正文】   您好,我是一名现在有很多困惑的大二学生。有一些问题想要向您请教。   先说一下我的基本情况,高考失利,不想复读,来到广州一所大专读计算机应用技术专业。学校是偏艺术类的,计算机专业没有实验室更不用说工作室了。而且学校的学风也不好。但我很想在计算机领...
复习一周,京东+百度一面,不小心都拿了Offer
京东和百度一面都问了啥,面试官百般刁难,可惜我全会。
20道你必须要背会的微服务面试题,面试一定会被问到
写在前面: 在学习springcloud之前大家一定要先了解下,常见的面试题有那块,然后我们带着问题去学习这个微服务技术,那么就会更加理解springcloud技术。如果你已经学了springcloud,那么在准备面试的时候,一定要看看看这些面试题。 文章目录1、什么是微服务?2、微服务之间是如何通讯的?3、springcloud 与dubbo有哪些区别?4、请谈谈对SpringBoot 和S...
Java 14 都快来了,为什么还有这么多人固守Java 8?
从Java 9开始,Java版本的发布就让人眼花缭乱了。每隔6个月,都会冒出一个新版本出来,Java 10 , Java 11, Java 12, Java 13, 到2020年3月份,...
轻松搭建基于 SpringBoot + Vue 的 Web 商城应用
首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。Fun: Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算、API ...
Python+OpenCV实时图像处理
目录 1、导入库文件 2、设计GUI 3、调用摄像头 4、实时图像处理 4.1、阈值二值化 4.2、边缘检测 4.3、轮廓检测 4.4、高斯滤波 4.5、色彩转换 4.6、调节对比度 5、退出系统 初学OpenCV图像处理的小伙伴肯定对什么高斯函数、滤波处理、阈值二值化等特性非常头疼,这里给各位分享一个小项目,可通过摄像头实时动态查看各类图像处理的特点,也可对各位调参、测试...
2020年一线城市程序员工资大调查
人才需求 一线城市共发布岗位38115个,招聘120827人。 其中 beijing 22805 guangzhou 25081 shanghai 39614 shenzhen 33327 工资分布 2020年中国一线城市程序员的平均工资为16285元,工资中位数为14583元,其中95%的人的工资位于5000到20000元之间。 和往年数据比较: yea...
为什么猝死的都是程序员,基本上不见产品经理猝死呢?
相信大家时不时听到程序员猝死的消息,但是基本上听不到产品经理猝死的消息,这是为什么呢? 我们先百度搜一下:程序员猝死,出现将近700多万条搜索结果: 搜索一下:产品经理猝死,只有400万条的搜索结果,从搜索结果数量上来看,程序员猝死的搜索结果就比产品经理猝死的搜索结果高了一倍,而且从下图可以看到,首页里面的五条搜索结果,其实只有两条才是符合条件。 所以程序员猝死的概率真的比产品经理大,并不是错...
害怕面试被问HashMap?这一篇就搞定了!
声明:本文以jdk1.8为主! 搞定HashMap 作为一个Java从业者,面试的时候肯定会被问到过HashMap,因为对于HashMap来说,可以说是Java集合中的精髓了,如果你觉得自己对它掌握的还不够好,我想今天这篇文章会非常适合你,至少,看了今天这篇文章,以后不怕面试被问HashMap了 其实在我学习HashMap的过程中,我个人觉得HashMap还是挺复杂的,如果真的想把它搞得明明白...
毕业5年,我问遍了身边的大佬,总结了他们的学习方法
我问了身边10个大佬,总结了他们的学习方法,原来成功都是有迹可循的。
python爬取百部电影数据,我分析出了一个残酷的真相
2019年就这么匆匆过去了,就在前几天国家电影局发布了2019年中国电影市场数据,数据显示去年总票房为642.66亿元,同比增长5.4%;国产电影总票房411.75亿元,同比增长8.65%,市场占比 64.07%;城市院线观影人次17.27亿,同比增长0.64%。 看上去似乎是一片大好对不对?不过作为一名严谨求实的数据分析师,我从官方数据中看出了一点端倪:国产票房增幅都已经高达8.65%了,为什...
推荐10个堪称神器的学习网站
每天都会收到很多读者的私信,问我:“二哥,有什么推荐的学习网站吗?最近很浮躁,手头的一些网站都看烦了,想看看二哥这里有什么新鲜货。” 今天一早做了个恶梦,梦到被老板辞退了。虽然说在我们公司,只有我辞退老板的份,没有老板辞退我这一说,但是还是被吓得 4 点多都起来了。(主要是因为我掌握着公司所有的核心源码,哈哈哈) 既然 4 点多起来,就得好好利用起来。于是我就挑选了 10 个堪称神器的学习网站,推...
这些软件太强了,Windows必装!尤其程序员!
Windows可谓是大多数人的生产力工具,集娱乐办公于一体,虽然在程序员这个群体中都说苹果是信仰,但是大部分不都是从Windows过来的,而且现在依然有很多的程序员用Windows。 所以,今天我就把我私藏的Windows必装的软件分享给大家,如果有一个你没有用过甚至没有听过,那你就赚了????,这可都是提升你幸福感的高效率生产力工具哦! 走起!???? NO、1 ScreenToGif 屏幕,摄像头和白板...
阿里面试一个ArrayList我都能跟面试官扯半小时
我是真的没想到,面试官会这样问我ArrayList。
曾经优秀的人,怎么就突然不优秀了。
职场上有很多辛酸事,很多合伙人出局的故事,很多技术骨干被裁员的故事。说来模板都类似,曾经是名校毕业,曾经是优秀员工,曾经被领导表扬,曾经业绩突出,然而突然有一天,因为种种原因,被裁员了,...
大学四年因为知道了这32个网站,我成了别人眼中的大神!
依稀记得,毕业那天,我们导员发给我毕业证的时候对我说“你可是咱们系的风云人物啊”,哎呀,别提当时多开心啦????,嗯,我们导员是所有导员中最帅的一个,真的???? 不过,导员说的是实话,很多人都叫我大神的,为啥,因为我知道这32个网站啊,你说强不强????,这次是绝对的干货,看好啦,走起来! PS:每个网站都是学计算机混互联网必须知道的,真的牛杯,我就不过多介绍了,大家自行探索,觉得没用的,尽管留言吐槽吧???? 社...
2020年1月中国编程语言排行榜,python是2019增长最快编程语言
编程语言比例 排名 编程语言 最低工资 工资中位数 最低工资 最高工资 人头 人头百分比 1 rust 20713 17500 5042 46250 480 0.14% 2 typescript 18503 22500 6000 30000 1821 0.52% 3 lua 18150 17500 5250 35000 2956 0.84% 4 go 17989 16...
看完这篇HTTP,跟面试官扯皮就没问题了
我是一名程序员,我的主要编程语言是 Java,我更是一名 Web 开发人员,所以我必须要了解 HTTP,所以本篇文章就来带你从 HTTP 入门到进阶,看完让你有一种恍然大悟、醍醐灌顶的感觉。 最初在有网络之前,我们的电脑都是单机的,单机系统是孤立的,我还记得 05 年前那会儿家里有个电脑,想打电脑游戏还得两个人在一个电脑上玩儿,及其不方便。我就想为什么家里人不让上网,我的同学 xxx 家里有网,每...
史上最全的IDEA快捷键总结
现在Idea成了主流开发工具,这篇博客对其使用的快捷键做了总结,希望对大家的开发工作有所帮助。
阿里程序员写了一个新手都写不出的低级bug,被骂惨了。
这种新手都不会范的错,居然被一个工作好几年的小伙子写出来,差点被当场开除了。
谁是华为扫地僧?
是的,华为也有扫地僧!2020年2月11-12日,“养在深闺人不知”的华为2012实验室扫地僧们,将在华为开发者大会2020(Cloud)上,和大家见面。到时,你可以和扫地僧们,吃一个洋...
Idea 中最常用的10款插件(提高开发效率),一定要学会使用!
学习使用一些插件,可以提高开发效率。对于我们开发人员很有帮助。这篇博客介绍了开发中使用的插件。
AI 没让人类失业,搞 AI 的人先失业了
最近和几个 AI 领域的大佬闲聊 根据他们讲的消息和段子 改编出下面这个故事 如有雷同 都是巧合 1. 老王创业失败,被限制高消费 “这里写我跑路的消息实在太夸张了。” 王葱葱哼笑一下,把消息分享给群里。 阿杰也看了消息,笑了笑。在座几位也都笑了。 王葱葱是个有名的人物,21岁那年以全额奖学金进入 KMU 攻读人工智能博士,累计发表论文 40 余篇,个人技术博客更是成为深度学习领域内风向标。 ...
立即提问