c语言指针,有关指向指针

运行错误
编译没有错误,是哪一块出了问题

#include <stdio.h>
#include <stdlib.h>
#define N 5


typedef struct node
{
    int data;
    struct node * next;
}Node;

int main()
{

    int creatListFromTail(Node ** pfirst);
    void outputList(Node * phead);
    void freeList(Node **pfirst);
    Node *insertNode(Node * head,int newdata);
    

    Node * phead=NULL;
    int x;
    

    if(creatListFromTail(&phead)!=0)
    {
    
        outputList(phead);
        
    
        scanf("%d",&x ); 
        phead=insertNode(phead, x);
        outputList(phead);
        
        
        freeList(&phead);
    }
    return 0;
}

int creatListFromTail(Node ** pfirst){
    int c;
    Node*p,*q;
    int i;
    for(i=1;i<=N;i++){
        scanf("%d",&c);
        p = (Node*)malloc(sizeof(Node));
        p->data = c;
        p->next = NULL;
        if(i==1){
            q = p;
            *pfirst = p;
        } 
        else {
            q->next = p;
            q = p;
        } 
        
    }
    return 1;
}
void outputList(Node * phead){
    Node*p;
    p = phead;
    while(phead){
        printf("%d->",p->data);
        p = p->next;
    } 
}
void freeList(Node **pfirst){
    Node*p;
    Node*q;
    q = *pfirst;
    while(q){
        p = q;
        q = q->next;
        free(p);
    }
}
Node *insertNode(Node * head,int newdata){
    Node*p;
    Node*q;
    p = head;
    q = p;
    while(1)
{
        if(newdata>p->data&&q==p){
            p = (Node*)malloc(sizeof(Node));
            p->data = newdata;
            p->next = head;
            break;
        }
        if(newdata<p->data){
            q = p;
            p = p->next;
            
        }
        else{
            p = (Node*)malloc(sizeof(Node));
            p->data = newdata;
            p->next = q->next;
            q->next = p;
            break;
        }    
    
    
    
}
return p;
}










要输入 5个整数呀

img

另外这个函数也要改一下:

void outputList(Node * phead){
    Node*p;
    p = phead;
    while(p){
        printf("%d->",p->data);
        p = p->next;
    } 
}

void outputList(Node * phead) 输出链表函数里,while(phead) 应修改为:while(p)

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7474846
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:c语言邻接矩阵存储有向网,使用迪杰斯特拉算法求最短路径并输出
  • 同时,你还可以查看手册:c语言-未定义行为 中的内容
  • 除此之外, 这篇博客: C语言实现判别有向图(采用邻接表为存储结构)中是否存在有向环,当有向环存在时,输出构成环的顶点中的 一、源码 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 思路及其详细解释看另一篇:关于图的第二题

    #include<stdio.h>
    #include<stdlib.h>
    
    //定义图的结构体
    #define MaxVexNum 100
    typedef struct ArcNode{//边表结点
    	int data;
    	struct ArcNode *next;
    }ArcNode;
    typedef struct VNode{//顶点表结点
    	int data,indegree,outdegree;//indegree、outdegree分别是该顶点的入度和出度,data为顶点号
    	struct ArcNode *first;
    	bool visited;//访问标记
    }VNode;
    typedef struct Graph{
    	VNode adjlist[MaxVexNum];
    	int vexnum,arcnum;
    }Graph;
    
    //定义栈的结构体以及相关操作
    typedef struct{
    	VNode data[MaxVexNum];
    	int top;
    }Stack;
    void InitStack(Stack &s){
    	s.top = -1;
    }
    bool StackEmpty(Stack s){//判栈空
    	if(s.top == -1){
    		return true;
    	}else{
    		return false;
    	}
    }
    
    bool Push(Stack &s,VNode x){//进栈
    	if(s.top == MaxVexNum-1){
    		return false;
    	}else{
    		s.data[++s.top] = x;
    		return true;
    	}
    }
    
    VNode Pop(Stack &s){//出栈
    	return s.data[s.top--];
    	
    }
    
    
    int location(Graph *G,int data){//定位顶点号为data在adjlist中的下标
    	int i;
    	for(i = 0;i<G->vexnum;i++){
    		if(G->adjlist[i].data == data){
    			return i;
    		}
    	}
    	return -1;
    }
    
    Graph *creat_Graph(){//创建一个图
    	int i,j,start;
    	Graph *G = (Graph *)malloc(sizeof(Graph));
    	ArcNode *p;
    	printf("请输入图的顶点数:");
    	scanf("%d",&G->vexnum);
    	for(i = 0;i<G->vexnum;i++){
    		G->adjlist[i].first = NULL;
    	}
    	printf("请输入图的边数:");
    	scanf("%d",&G->arcnum);
    	for(i = 0;i<G->vexnum;i++){
    		printf("请输入第%d个顶点:",i+1);
    		scanf("%d",&G->adjlist[i].data);
    	}
    	for(i = 0;i<G->arcnum;i++){
    		printf("输入边的起点:");
    		scanf("%d",&start);
    		for(j = 0;j<G->vexnum;j++){
    			if(G->adjlist[j].data == start){
    				p = (ArcNode *)malloc(sizeof(ArcNode));
    				p->next = NULL;
    				printf("输入边的终点:");
    				scanf("%d",&p->data);
    				p->next = G->adjlist[j].first;
    				G->adjlist[j].first = p;
    			}
    		}
    	}
    	return G;
    }
    
    void FindInDegree(Graph *G){  //计算每个顶点的入度
             int i;
             ArcNode *p;
             for (i=0;i<G->vexnum;i++)
                   G->adjlist[i].indegree=0;//初始化入度
             for (i=0;i<G->vexnum;i++)
             {
                 p=G->adjlist[i].first;
                 while(p){
    				 G->adjlist[location(G,p->data)].indegree++;
    				 p=p->next;
                 }
             }
    }
    
    void FindOutDegree(Graph *G){  //计算每个顶点的出度                                
             int i ;
             ArcNode *p;
             for (i=0;i<G->vexnum;i++)
                   G->adjlist[i].outdegree=0;//初始化出度
             for (i=0;i<G->vexnum;i++)
             {
                 p=G->adjlist[i].first;
                 while(p){
                       G->adjlist[i].outdegree++;
                       p=p->next;
                 }
             }
    }
    
    void main(){
    	int i,count = 0,j;//count记录被标记的顶点个数
    	Stack s;
    	VNode v;
    	ArcNode *q;
    	Graph *G = creat_Graph();
    	for(i = 0;i<G->vexnum;i++){//标记的初始化
    		G->adjlist[i].visited = false;
    	}
    	InitStack(s);//栈的初始化
    	FindInDegree(G);
    	FindOutDegree(G);
    	for(i = 0;i<G->vexnum;i++){//将出度或入度为0的顶点入栈并标记
    		if(G->adjlist[i].outdegree == 0||G->adjlist[i].indegree == 0){
    			Push(s,G->adjlist[i]);
    			G->adjlist[i].visited = true;
    		}
    	}
    	while(!StackEmpty(s)){
    		v = Pop(s);
    		count++;
    		for(q = v.first;q;q = q->next){//计算入度的变化
    	 		G->adjlist[location(G,q->data)].indegree--;
    	 	}
    	 	for(j = 0;j<G->vexnum;j++){//计算出度的变化就要对整个图的邻接表进行遍历了
    	 		for(q = G->adjlist[j].first;q;q = q->next){
    	 			if(q->data == v.data){
    	 				G->adjlist[j].outdegree--;
    	 			}
    	 		}
    	 	}
    		for(i = 0;i<G->vexnum;i++){//将出度或入度为0 且未被标记(即没有入过栈的)的顶点入栈
    			if((G->adjlist[i].outdegree == 0||G->adjlist[i].indegree == 0)&&G->adjlist[i].visited == false){
    				Push(s,G->adjlist[i]);
    				G->adjlist[i].visited = true;
    			}
    		}
    	}
    	if(count<G->vexnum){
    		printf("存在环\n");
    		printf("构成环的顶点为:");
    		for(i = 0;i<G->vexnum;i++){
    			if(G->adjlist[i].visited == false){
    				printf("%5d",G->adjlist[i].data);
    			}
    		}
    		printf("\n");
    	}else{
    		printf("不存在环\n");
    	}
    }
    
  • 您还可以看一下 CSDN讲师老师的C语言精髓之编译过程视频教程课程中的 计算机的组成部分,栈内存的特点;画出内存图,引入指针的概念小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    对于C语言指针使用时出现的运行时错误,可能原因有很多,例如空指针引用,指针未初始化,指针越界等等。解决问题的方法也应根据实际情况具体分析。

    1. 空指针引用: 当一个空指针被解引用时,程序会崩溃,并输出崩溃信息。解决方法是要确保指针不为空才能进行解引用操作,或者在解引用前进行非空判断。

    2. 指针