前两种方法都是一样的,是在main里创建head指针,只是不同的写法,
第三种方法是一种错误的写法,把局部变量的通过指针返回到main,数据会随着内存回收消失。
要搞懂前两种创建的方法,首先要看明白指针的指针
请参阅下面代码
#include <stdio.h>
#include <stdlib.h>
//关于指针的指针,赋值以及其意义
int main()
{
int a=8;//定义一个int型变量a,假设其在内存中的地址是1000
int *q;//定义指针变量q,q本身也需要内存存储,假设其地址是2000
q=&a;//给q赋值,即a的地址1000。此时q=1000,*q=a=8;
int **p;//定义指针的指针变量p,同理p也需要内存存储,假设其地址是3000
p=&q;//给变量p赋值,即q的地址2000.此时p=2000,*p=1000,**p=a=8
//输出值依次:8,1000,8,2000,1000,8
printf("%3d,%3d,%3d,%3d,%3d,%3d",a,q,*q,p,*p,**p);
return 0;
}
第一种方法
#include <stdio.h>
#include <stdlib.h>
//定义一个名为Node的结点
//一般创建链表我们都用typedef struct,就是为了简化定义过程
//因为这样定义结构体变量时,我们就可以直接用 Node *a;定义结构体类型变量了。
typedef struct _node{
int num; //数据结构部分
struct _node *next; //指针接口部分
}Node;
void add_node(int input , Node **head, Node **last);
void print_node(Node *head);
int main(int argc, const char * argv[]) {
int input;
//初始化一个head结点指针,一个last结点指针,占时不赋值
Node *head = NULL;
Node *last = NULL;
//初始化指向*head的指针,&head其实就是对指针head取地址赋给phead
//因为要调用函数,必须给函数传指针地址才能改变值,不然函数里的都是
//函数里的本地变量对main来说是不会改变的,这就是这里为什么要做
//指针的指针
Node **phead = &head;
Node **plast = &last;
do{
scanf("%d",&input);
//把在main里初始化好的head和last通过指针的指针传入add_note
add_node(input, phead, plast);
}while(input != -1);
//打印结果
print_node(head);
}
void add_node(int input , Node **phead, Node **plast)
{
//先创建一个结点的指针地址并赋值
Node *new = (Node *)malloc(sizeof(Node));
new->num = input;
new->next = NULL;
//创建的不是第一个结点,因为一开始head=NULL
//通过else把new的指针地址赋给head不为NULL
//*phead phead是指针的指针,取一次*运算就是head的地址
//而这里head的地址就是一开始赋值的NULL
//简单来说phead是指针的指针,*phead就是他所指向的指针及head
if (*phead){
(*plast)->next = new;
*plast = new;
}else{ //创建的是第一个结点
*phead = new;
*plast = *phead;
}
}
void print_node(Node *head)
{
while (head!=NULL){
printf("%d\n",head->num);
head=head->next;
}
}
第二种方法就是把**用typedef替换成了一个简单的符号,代码的阅读星更好一些,更容易懂
#include <stdio.h>
#include <stdlib.h>
typedef struct _node{
int num;
struct _node * next;
} Node , *List;
void print_node(Node *head);
void add_node(List * ,List * ,int );
int main (){
int num;
Node * head = NULL;
Node * last = NULL;
List * phead = &head;
List * plast = &last;
do
{
scanf("%d",&num);
add_node(phead,plast,num);
}while(num != -1);
print_node(head);
}
void print_node(Node *head)
{
while (head)
{
printf("%d ",head->num);
head = head->next;
}
}
void add_node(List * phead,List * plast,int num)
{
// adding new point creat a linked list
if(num != -1)
{
Node *new = (Node *)malloc(sizeof(Node));
new->num = num;
new->next = NULL;
//head has been created
if(*phead)
{
(*plast)->next = new;
*plast = new ;
}else //created the head
{
*phead = new;
*plast = *phead;
}
}
}
第三种方法,这种方法是错误的,把函数里的局部变量通过指针传出来,是不可以的,因为函数结束以后他的局部变量会被回收,所以一定要小心如果要传出指针,必须前提是在main里面有一个本地变量然后通过指针传入函数再通过指针传出,像方法一二一样才可以。
#include <stdio.h>
#include <stdlib.h>
typedef struct _node{
int num;
struct _node *next;
} Node;
Node * creat_node(void);
void print_node(Node *head);
int main(int argc, const char * argv[]) {
Node *p=creat_node();
print_node(p);
}
Node * creat_node(void)
{
int num;
Node *head = NULL;
Node *last = NULL;
do
{
scanf("%d",&num);
Node *new=(Node *)malloc(sizeof(Node));
new->num = num;
new->next = NULL;
if(head)
{
last->next = new;
last = new;
}else
{
head = new;
last = head;
}
}while(num != -1);
return head;
}
void print_node(Node *head)
{
while(head)
{
printf("%d ",head->num);
head = head->next;
}
}