前段实践在学习链表,本以为已经明白其中的原理,但真正运用的时候,却发现仍然存在很多问题。
在这里总结一下自己的心得体会。
一、利用链表节点Next是否指向空进行遍历的注意点:
void PutList(StudentNote *Head) {
Head = Head->next;
while (Head->next != NULL) {
printf("%s %s\n", Head->x, Head->y);
Head = Head->next;
}
printf("%s %s\n", Head->x, Head->y);
printf("全部打印完毕\n");
}
这是一个使用遍历方法打印整个链表内容的函数,Head=Head->Next的原因在于,第一个节点没有储存内容,有效节点是第二个节点。 使用这种方法遍历的效果是,遍历结束Head指向的是最后一个节点,但并没有对这个节点进行操作,因此,最后需要补一个循环体内除Head=Head->Next外其他内容的执行。
二、通过函数把一个结构指针传到函数主体内。对这个指针进行操作,是不影响初始指针的。
#include<stdio.h>
#include<stdlib.h>
typedef struct student{
int data;
struct student *Next;
}StudentNote;
int main(){
StudentNote*P=(StudentNote*)malloc(sizeof(StudentNote));
printf("最开始这个指针的地址是%p\n",P);
printf("修改之后的指针地址是%p\n",P);
}
void ChangeP(StudentNote*P){
P++;
}
运行结果:
最开始这个指针的地址是0000000000026980
修改之后的指针地址是0000000000026980
请按任意键继续. . .
所以我们可以大胆的操作传入函数内的指针。不需要在定义一个指针来接受链表头指针,
三、定义一个结构体指针,不进行动态内存分配,直接使用指针调度结构体里面的内容,可不可以实现 答案是不可以的。也就是说如果想要储存内容就必须申请内存,结构体指针永远只能储存一个指针型的变量,无法进行进一步的操作。
StudentNote *Head;
//直接调用Head->name是不可以的
四、定义一个结构体指针,把指针传到函数里面,对传入的指针进行修改,对函数外的指针是没有影响的,但是对指针里面的量进行修改,那就有影响了。
#include<stdio.h>
#include<stdlib.h>
struct student{
int a;
};
void doo3d(struct student *c){
c->a=56;
}
int main(){
struct student *b;
b=(struct student*)malloc(sizeof(struct student));
b->a=36;
doo3d(b);
printf("%d",b->a);
return 0;
}
类如这样,最后的输出结果就是56而不是36.
五、创建一个数据结构的最好方式 就是输入空 返回值是那个有效的内容 因为我们前面提到,在函数中操作指针对指针本身是不影响的,包括在函数中为他动态内存申请,当然也就是无效的了。
对链表进行操作的方式有很多种,但是总可以找到最优,以及代码量最少的,因此,要敢于尝试与试错。