大佬们看一下为毛addstu函数里的ptr指针的地址是0x0
#include <stdio.h>#include <stdlib.h>
#include <string.h>
struct students{
char name;
int num;
float score;
struct students *next;
};
int count=0;
int *p = &count;
void getInfo(struct students *);
int addStu(struct students **);
int delStu(struct students **,int );
int searchStu(struct students *,int );
void showList(struct students **);
int main(){
struct students *S = NULL;//生成一个头节点
int op,i;
do{
printf("welcome to students' information manage system!\n");
printf("please chose your operation:\n");
printf("1 add a student to specified location\n");
printf("2 delete a student from the specified location\n");
printf("3 find a student through his number\n");
printf("4 show the list:\n");
printf("0 exit\n");
scanf("%d",&op);
switch(op){
case 1:printf("input the num you want to insert:");addStu(&S);break;
case 2:printf("input the num you want to delete:");scanf("%d",&i);delStu(&S,i);break;
case 3:printf("input his num:");scanf("%d",&i);searchStu(S,i);break;
case 4:showList(&S);break;
}
}while(op != 0);
return 0;
}
void getInfo(struct students *s){
printf("input students's name :\n");
scanf("%s",s->name);
printf("input students's num and score:\n");
scanf("%d%f",&s->num,&s->score);
}
int addStu(struct students **S1){ //问题出在这个函数里
struct students *ns,*temp,*ptr = *S1;
ns = (struct students *)malloc(sizeof(struct students));
if(ns == NULL){
printf("menory allocation error!");
exit(1);
}
getInfo(ns);
if(ptr == NULL){
*S1 = ns;
ns->next = NULL;
(*p)++;
}
while(ptr->next != NULL && ptr->num < ns->num){
temp = ptr;
ptr = ptr->next;
}
if(ptr == *S1){
temp = *S1;
*S1 = ns;
ns->next = temp;
}
else if(ptr->next == NULL){
ptr->next = ns;
ns->next = NULL;
}
else{
temp->next = ns;
ns->next = ptr;
}
printf("name\tnum\tscore\t\n",(*S1)->name,(*S1)->num,(*S1)->score);
return 0;
}
int delStu(struct students **S1,int n){
struct students *temp,*ptr = *S1; //用来接收旧的结构体节点,并准备释放内存
if(ptr->next == NULL){
printf("can't delete student from an empty list\n");
}
while(ptr->num < n){
ptr=ptr->next;
}
if(ptr == NULL){
printf("can't find this student!\n");
}
if(ptr->num == n){
temp = ptr;
ptr = temp->next;
free(temp);
printf("delete complete\n");
}
return 0;
}
int searchStu(struct students *S1,int n){
int i;
while(S1 != NULL){
if(S1->num == n){
printf("he/she is the %d student");
return i+1;
}
S1 = S1->next;
}
if(S1->next == NULL && S1->num != n){
printf("can't find this student");
return 0;
}
}
void showList(struct students **S1){
if(*S1 == NULL){
printf("no student in this list!\n");
}
else{
printf("name\tnum\tscore\t\n");
}
while(*S1 != NULL){
printf("%s\t%d\t%d\t\n",(*S1)->name,(*S1)->num,(*S1)->score);
*S1 = (*S1)->next;
}
}
第51行,ptr已经赋值了,但是却不是*S1的地址
本帖最后由 Croper 于 2019-3-28 16:50 编辑
if(ptr == NULL){
*S1 = ns; //这里,*S1指向的地址已经被改变了,但ptr仍然指向*S1原来的地址,也就是nullptr
ns->next = NULL;
(*p)++;
} Croper 发表于 2019-3-28 16:41
请问大佬这个是不是可以用常指针来解决问题
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct students{
char name;
int num;
float score;
struct students *next;
};
int count=0;
int *p = &count;
void getInfo(struct students *);
void addStu(struct students **);
int delStu(struct students **,int );
int searchStu(struct students *,int );
void showList(struct students **);
int main(){
struct students *S = NULL;//生成一个头节点
int op,i;
do{
printf("welcome to students' information manage system!\n");
printf("please chose your operation:\n");
printf("1 add a student to specified location\n");
printf("2 delete a student from the specified location\n");
printf("3 find a student through his number\n");
printf("4 show the list:\n");
printf("0 exit\n");
scanf("%d",&op);
switch(op){
case 1:printf("input the student information:");addStu(&S);break;
case 2:printf("input the num you want to delete:");scanf("%d",&i);delStu(&S,i);break;
case 3:printf("input his num:");scanf("%d",&i);searchStu(S,i);break;
case 4:showList(&S);break;
}
}while(op != 0);
return 0;
}
void getInfo(struct students *s){
printf("input students's name :\n");
scanf("%s",s->name);
printf("input students's num and score:\n");
scanf("%d%f",&s->num,&s->score);
}
void addStu(struct students **S1){
struct students *ns,*temp,*move = (struct students * const)S1;
ns = (struct students *)malloc(sizeof(struct students));
if(ns == NULL){
printf("menory allocation error!");
exit(1);
}
getInfo(ns);
if(*S1 == NULL){ //空链表的操作;
move=ns;
ns->next=NULL;
// move = move->next;
}
else{
while(move->num<ns->num && move->next != NULL){//通过新学生的学号来移动move与temp指针,
temp = move;
move = move->next;
}
if(move == *S1){ //如果新来的学生的学号是最小的,那么move指针并不会移动,所以move指针指向头节点
ns->next = move->next;
move = ns;
}
else if(move->next == NULL && move->num<ns->num){ //新学生的学号是最大的
move->next = ns;
ns->next = NULL;
}
else{ //学生学号刚好在中间
temp->next = ns;
ns->next = move;
}
}
printf("%s\t%d\t%d\t\n",move->name,move->num,move->score);
// printf("%s\t%d\t%d\t\n",(*S1)->name,(*S1)->num,(*S1)->score);
}
int delStu(struct students **S1,int n){
struct students *temp,*ptr = *S1; //用来接收旧的结构体节点,并准备释放内存
if(ptr->next == NULL){
printf("can't delete student from an empty list\n");
}
while(ptr->num < n){
ptr=ptr->next;
}
if(ptr == NULL){
printf("can't find this student!\n");
}
if(ptr->num == n){
temp = ptr;
ptr = temp->next;
free(temp);
printf("delete complete\n");
}
return 0;
}
int searchStu(struct students *S1,int n){
int i = 0;
while(S1 != NULL){
if(S1->num == n){
printf("he/she is the %d student",i);
return i+1;
}
S1 = S1->next;
i++;
}
if(S1->next == NULL && S1->num != n){
printf("can't find this student");
return 0;
}
return 0;
}
void showList(struct students **S1){
struct students *s;
s = *S1;
if(*S1 == NULL){
printf("no student in this list!\n");
}
else{
printf("name\tnum\tscore\t\n");
}
while(s != NULL){
printf("%s\t%d\t%d\t\n",s->name,s->num,s->score);
s = s->next;
}
}
使用常指针的代码,但是不知道为什么,*S1就是一直是空的,求大佬们看看思路哪里有错吧
cookies945 发表于 2019-3-30 14:36
请问大佬这个是不是可以用常指针来解决问题
所以我推荐链表在初始化时就申请一个空置的头节点,然后把这个头节点作为唯一参照物,
然后所有过程都不需要讨论头结点为空的情况了
你这个ptr再重新指定一下就好啊
Croper 发表于 2019-3-30 14:50
所以我推荐链表在初始化时就申请一个空置的头节点,然后把这个头节点作为唯一参照物,
然后所有过程都不 ...
还是没有怎么听懂,我在main函数中初始化的头指针就是空,然后再将其传入addStu的函数的时候把它作为常指针了,是哪里思路有问题么,还是我们讨论的不是同一个指针{:10_266:} 本帖最后由 Croper 于 2019-3-31 22:49 编辑
知道你的意思,你是想move改变的时候(*S1)同时改变是么,
C语言里,仍然只能使用二重指针
struct student **move=S1;
然后使用(*move)代替你原代码里的move
//=================这里是分析环节==================
你前面这一段程序,相当于
int main(){
int S=0;
int *S1=&S;
int move=*S1;
}
S1指向S,你认为,改变move的值能够改变S的值么,
他们分别属于两个不同的内存,这当然是不可能的
就算加上你的常指针
int main(){
int S=0;
int *S1=&S;
int move=*(int* const )S1;
}
你认为这有区别么
唯一的方法只能
int main(){
int S=0;
int *S1=&S;
int *move=S1;
}
这样才能做到改变(*move)就是改变S
本帖最后由 Croper 于 2019-3-31 16:38 编辑
我按你的风格重写了一个,自己对照着改改吧#include <stdio.h>
struct students{
char name;
int num;
float score;
struct students *next;
};
struct students* CreateStudent();
void addStu(struct students *,struct students *);
int delStu(struct students *,int );
struct students* searchStu(struct students *,int );
void showList(struct students *);
void PrintStudentInfo(struct students *);
struct students* prehead;
void flushstdin(){
char c;
while ((c=getchar())!=EOF && c!='\n');
}
void PrintStartInterface(){
printf("**********************************************************************\n");
printf("* welcome to students' information manage system! *\n");
printf("* please chose your operation: *\n");
printf("* *\n");
printf("* 1 add a student to specified location *\n");
printf("* 2 delete a student from the specified location *\n");
printf("* 3 find a student through his number *\n");
printf("* 4 show the list: *\n");
printf("* 0 exit *\n");
printf("**********************************************************************\n\n");
}
void InitAll(){
prehead=(struct students*)malloc(sizeof(struct students));
prehead->next=NULL;
}
int PostOperation(){
int op;
scanf("%c",&op);
flushstdin();
switch (op){
case '1':{
struct students *p=CreateStudent();
addStu(prehead,p);
printf("Add student success!\n");
PrintStudentInfo(p);
printf("\nPress Anykey to return..");
getch();
break;
}
case '2':{
int id;
printf("input the num you want to delete:");
scanf("%d",&id);
flushstdin();
if (!delStu(prehead,id)){
printf("can't find this student!\n");
}
else{
printf("delete success!\n");
}
printf("\nPress Anykey to return..");
getch();
break;
}
case '3':{
int id;
printf("input the num you want to find:");
scanf("%d",&id);
flushstdin();
struct students *p=searchStu(prehead,id);
if (p){
PrintStudentInfo(p);
}
else{
printf("Can't find this student!");
}
printf("\nPress Anykey to return..");
getch();
break;
}
case '4':
showList(prehead);
printf("\nPress Anykey to return..");
getch();
break;
case '0':
break;
default:
printf("Unrecognized operation!");
getch();
return -1;
}
return op;
}
int main(){
int op,i;
InitAll();
do{
system("cls");
PrintStartInterface();
}while(PostOperation());
return 0;
}
struct students* CreateStudent(){
struct students *s=(struct students*)malloc(sizeof(struct students));
if (s==NULL) {
printf("menory allocation error!");
exit(1);
}
printf("input the student information:\n");
printf("\n input students's name :");
scanf("%s",s->name);
flushstdin();
printf("\n input students's num and score:");
setbuf(stdin,NULL);
scanf("%d%f",&s->num,&s->score);
flushstdin();
return s;
}
void addStu(struct students *prehead,struct students* s){
struct students *p=prehead;
while (p->next!=NULL && p->next->num<s->num){
p=p->next;
}
struct students *tmp=p->next;
p->next=s;
s->next=tmp;
}
struct students* searchStu(struct students *S1,int id){
struct students *p=prehead->next;
while (p!=NULL && p->num<id){
p=p->next;
}
if (p==NULL || p->num>id){
return NULL;
}
return p;
}
int delStu(struct students *prehead,int id){
struct students *p=prehead;
while (p->next!=NULL && p->next->num<id){
p=p->next;
}
if (p->next==NULL || p->next->num>id){
return 0;
}
struct students* tmp=p->next;
p->next=tmp->next;
free(tmp);
return id;
}
void showList(struct students *prehead){
if(prehead->next == NULL){
printf("no student in this list!\n");
return;
}
printf("name\tnum\tscore\t\n");
struct students *p=prehead->next;
while(p != NULL){
PrintStudentInfo(p);
p = p->next;
}
}
void PrintStudentInfo(struct students *p){
if (p==NULL) {
printf("null student error!");
return;
}
printf("%s\t%d\t%.1f\t\n",p->name,p->num,p->score);
}
Croper 发表于 2019-3-31 14:27
知道你的意思,你是想move改变的时候(*S1)同时改变是么,
原来如此,我纠结了这么久的问题终于解开了,谢谢大佬 Croper 发表于 2019-3-31 16:23
我按你的风格重写了一个,自己对照着改改吧
这里还是有一个小bug,当你打印链表的时候,不知道为什么,你的score就是零
cookies945 发表于 2019-3-31 22:53
这里还是有一个小bug,当你打印链表的时候,不知道为什么,你的score就是零
https://xxx.ilovefishc.com/album/201903/31/231241gfs1vso14oze5ost.bmp
有问题么,为什么我运行起来正常呢
不过 case '0':
break;
应该改成 case '0':
return 0;
不然无法正常退出 Croper 发表于 2019-3-31 23:15
不过
应该改成
不然无法正常退出
哦好的我知道了
Croper 发表于 2019-3-31 23:13
有问题么,为什么我运行起来正常呢
我说的是我自己写的程序,一开始还没有这个问题的,改着改着就出来了
{:10_266:} cookies945 发表于 2019-4-1 21:57
我说的是我自己写的程序,一开始还没有这个问题的,改着改着就出来了
printf("%s\t%d\t%d\t\n",move->name,move->num,move->score);你的score是浮点变量,输出却是%d Croper 发表于 2019-4-1 22:09
你的score是浮点变量,输出却是%d
{:10_266:} 好的吧,我的小错误还是那么多,谢谢叫你那么耐心一一解答
页:
[1]