问题是数组的问题,不能这样赋值!
要么直接一开始给数组赋值字符串,后面这样赋值会报错。
这从底层逻辑理解,字符被放到了只能读的寄存器。汇编里面讲的有,后面我再来总结一下自己学的汇编,这里提一下。
这里提供两种做法
方法一:
#include
struct book
{
float price;//价格
char name[30];//名字
};
int main(void)
{
struct book myBook={5.6,"the world is flat"};
printf("book name=%s,book price=%.1f",myBook.name,myBook.price);
return 0;
}
方法二
这里我们用strcpy函数
当让可以自己写个strcpy函数,也不是很难
规定两个数组,就行了。
#include
struct book
{
float price;//价格
char name[30];//名字
};
int main(void)
{
struct book myBook;
strcpy(myBook.name, "the world is flat");
myBook.price=5.6;
printf("book name=%s,book price=%.1f",myBook.name,myBook.price);
return 0;
}
其实这个程序它已经写得差不多了,主要考察,你对链表的头指针是否理解,以及一个新的结构要开空间
以及为了方便学习一下typedef命名结构
以及学会malloc,free(当然这里不用free)
1.这里没有没有给head,或者tail开空间,而且也没有头指针;
2.当我没有定义结构的指针赋值时,这个编译器会默认为NULL;
一定一定要理解
如果不能理解去这个网站学习一下http://data.biancheng.net/view/298.html
3.本道题写的是一个空的头节点
#include
#include
#include
typedef struct stud_node
{
int num;
char name[20];
int score;
struct stud_node* next;
}student;
int main()
{
student* head, * tail, * p;
int num, score;
char name[20];
int size = sizeof(struct stud_node);
tail = (student*)malloc(size);
printf("input num,name and score:");
scanf("%d", &num);
head = tail;//让头等于尾
while (num != 0)
{
p = (student*)malloc(size);
scanf("%s %d", name, &score);
p->num = num;
strcpy(p->name, name);
p->score = score;
p->next = NULL;
tail->next = p;
tail = p;
scanf("%d", &num);
}
for (p = head->next; p != NULL; p = p->next)//之前我写道这里时,并没有理解p=head是个空的导致我运行的错的结果
printf("%d %s %d\n", p->num, p->name, p->score);
return 0;
}
#include
#include
#include
typedef struct stud_node
{
int num;
char name[20];
int score;
struct stud_node *next;
}student;
int main()
{
student *head,*tail,*p;
int num,score;
char name[20];
int size = sizeof(struct stud_node);
head=(student*)malloc(size);
tail=(student*)malloc(size);
printf("input num,name and score:");
scanf("%d",&num);
head=tail;
tail->next=p;
while(num!=0)
{
p=(student*)malloc(size);
scanf("%s %d",name,&score);
p->num=num;
strcpy(p->name,name);
p->score=score;
tail->next=p;
p->next=NULL;
tail=p;
scanf("%d",&num);
}
p=tail->next;
for(p=head;p->next != NULL;p=p->next)
printf("%d %s %d\n",p->num,p->name,p->score);
return 0;
}
可以看到,我这代码写得,混乱,就是并没有理解
看看运行出来的什么结果
做这种题大片大片的,看似吓人,其实认真分析后,都是纸老虎
我们只需要按照他所给的逻辑编写就好,不需要什么算法和逻辑
多的也只是考察你对链表和结构的理解
最开始的时候做这道题,我想的时写在同一个函数里,直接运行得了
直接把我看晕了。
再思考,我们不是已经学会了,自定义函数吗?
那可以把函数分开,从而让逻辑清晰
注释都写在代码里了
// 编程完成下列任务
//(1)建立一个单链表 21 3 15 27 11 18,并输出该链表;
//(2)输入序号n,查找序号为n的结点,并输出;
//(3)输入值x,查找值为x的结点,并输出;
//(4)插入结点: 输入序号 n和值x。在序号为n的结点后插入x,并输出该链表;
//(5)删除结点: 输入序号 n,删除序号为 n 的结点,并输出该链表。
#include
#include
#include
#define LEN sizeof(struct Nmb)
typedef struct Nmb
{
int number;
int xuhao;
struct Nmb *next;
}Database;
//最开始写这道题时,我们可以发现如果把所有的操作都写在主函数里面,会导致思维混乱。
//所以我们不如把最上面的逻辑分为一个步骤来执行。
Database *input();//为什么要这样定义函数?我们希望函数返回和输出类型是一个结构,理解函数和结构的关系!
Database output(Database *head);
Database insert(Database *head,int location,int number);//在这道题我们的查找是从中间开始查找的
Database seekxuhao(Database*head,int xuhao);
Database seeknumber(Database*head,int number);
Database dele(Database*head,int location);//这里本来要用delete定义,delete是关键词
int main()//根据题目信息我们先确定所需要的变量
{
int xuhao1,number1,number2,location1,location2;//xuhao1用来查找序号,number1和2分别用来记录要 插入和删除的数,location1、2表示所在序号的位置
Database*head;//为了防止与我们所要找的序号弄混,我们区分一下,所以在上面定义的时候也是location。
head=input(); //建立一个单链表 21 3 15 27 11 18
scanf("%d",&xuhao1); //输入序号n,查找序号为n的结点
scanf("%d",&number1);//输入值x,查找值为x的结点
scanf("%d %d",&location1,&number2);//插入结点: 输入序号 n和值x。在序号为n的结点后插入x
scanf("%d",&location2);//删除结点: 输入序号 n,删除序号为 n 的结点
output(head);
seekxuhao(head,xuhao1);
seeknumber(head,number1);
insert(head,location1,number2);
output(head);//先输出一遍
dele(head,location2);
output(head);
}
Database *input()
{
Database *head,*temp,*p;
int number,xuhao1=1;//思路是在建立一个单向链表时我们需要一个头
scanf("%d",&number);
p=(Database*)malloc(LEN);//这里用的方法是
p->number=number;
p->xuhao=xuhao1;
head=p;//指针指向元首结点
//题目说的是输入0的时候就停止了
scanf("%d",&number);
while(number!=0)
{
temp=(Database*)malloc(LEN);//开一个新的空间
temp->number=number;
xuhao1+=1;
temp->xuhao=xuhao1;
temp->next=NULL;
p->next=temp;//指向上面那个节点
p=p->next;//这是理解是一个重点,这里的含义是理解下一次循环的时候,也能同样的操作其实p->next就是temp,为下一次循环准备
scanf("%d",&number);
}
return head;
}
//提一句,一定要理解头指针,以及头节点的意思
Database output(Database *head)
{
Database *p;
for (p = head; p != NULL; p = p->next)//把头指针直接给p,一次输出就好了
{
if(p->next!=NULL)//题目有坑,最后输出的数没有空格
{
printf("%d ",p->number);
}
else{
printf("%d",p->number);
}
}
printf("\n");
}
Database seekxuhao(Database*head,int xuhao)
{
Database *p;
p=head;
for (p = head; p !=NULL; p = p->next)
{
if(p->xuhao==xuhao)
{
printf("%d\n",p->number);
break;
}
}
}
Database seeknumber(Database*head,int number)
{
Database *p;
p=head;
for (p = head; p !=NULL; p = p->next)
{
if(p->number==number)
{
printf("%d %d\n",p->xuhao,p->number);
break;
}
}
}
Database insert(Database *head,int location,int number)
{
Database *p,*temp1;
p=head;
temp1=(Database*)malloc(LEN);
temp1->number=number;
temp1->xuhao=(location+1);
while(1)
{
if(p->xuhao==location)
{
temp1->next=p->next;//我们先将构造新的结构链接到下一个
p->next=temp1;//然后让这此时的结构中的指针指向它
break;
}
p=p->next;//为循环而匹配
}
p=temp1->next;//此时后面链表的序号发生了改变,我们需要做一些调整
while(p)
{
p->xuhao=(p->xuhao+1);//这里加号的运算符是比->低的
p=p->next;
}
}//其实这里可以返回也可以返回,对于指针而言,已经在整个程序中实现了
Database dele(Database*head,int location)
{
Database *p,*p1;
p=head;
for(p = head; p !=NULL; p = p->next)
{
if(p->xuhao==(location-1))
{
p1=p->next;
p->next=p->next->next;//这里是我们直接将中间的节点绕过,链接到下一个
break;
}
}
free(p1);//把不要的释放掉
}
上面的代码解决了这样的问题
在学习过程存在的问题,链表和结构“->”这个符号你得搞清楚它的优先级
其次,我最开始学习的时候,把空指针和空的结构搞混淆了,导致我困住了好久
最后,就是耐心了
请认真的,慢慢的理解!!
最后在网上找了一个对链表讲解很好的网站
有图有真相
http://data.biancheng.net/view/161.html
最后自己评价一下,会的都不难,不会的特别难!!!
不去做,不静下心来,不认真去想,就会很难!!