user-0 提问: 【求助】C语言实现单链表头插法出现了错误

回复:
user: user-1
content: 哎呀，编译器提示：参数类型不匹配！ 作为C程序员，我太难了：足足有十年，我一个函数没通过。

user: user-0
content: 引用 26 楼 AFei2019 的回复:wow，老哥，好巧，你的帖子都上热门了 是真的特别感谢大佬们的答疑解惑

user: user-2
content: wow，老哥，好巧，你的帖子都上热门了

user: user-3
content: //答案： a) int a; b) int *a; c) int **a; d) int a[10]; e) int *a[10]; f) int (*a)[10]; g) int (*a)(int);  h) int (*a[10])(int);

user: user-3
content: 应该先明白指针是什么  给你出道题：  用变量a给出下面的定义  a) 一个整型数 b)一个指向整型数的指针 c)一个指向指针的的指针，它指向的指针是指向一个整型数 d)一个有10个整型数的数组 e) 一个有10个指针的数组，该指针是指向一个整型数的 f) 一个指向有10个整型数数组的指针 g) 一个指向函数的指针，该函数有一个整型参数并返回一个整型数 h) 一个有10个指针的数组，该指针指向一个函数，该函数有一个整型参数并返回一个整型数

user: user-4
content: haodehlsalieuuosf

user: user-5
content: 可能软件出了问题

user: user-6
content: 新人求积分，

user: user-7
content: 引用 10 楼 柘月十七 的回复:[quote=引用 3 楼 突触 的回复:]    CreateList_H(L,2);  这里出了问题   这里传递的是形参     用指针就行了   CreateList_H(&L,2); 想了半天没弄明白它这里传递指针的逻辑过程是什么，能讲讲嘛？谢谢[/quote] 参数传递如果传一重指针，则是传入参数，如果传二重指针，就是传入传出参数。因为create函数也要带出head指针，即需要传出，并且除了参数带会新head指针外，，无法通过return返回，因为函数是void返回值。  以下两种定义都是可以的：  LinkList  CreateList_H(LinkList L,int n)   //形参LinkList类型的指针变量（用于指向新开辟储存单元），逆序储存n个元素值 {     int i;    //元素数量计数      L = (LinkList)malloc(sizeof(LNode));   //为头结点开辟储存空间     L->next = NULL;  //含头结点的空链表      for(i=0;i<n;i++)    //循环输入元素     {         ElemType e;         LNode *p=(LinkList)malloc(sizeof(LNode));   //为新结点开辟空间并令指针指向该地址         printf("请输入1个链表元素:");         scanf("%d",&e);    //向新结点数据域输入数据         p->data = e;         printf("保存完成~\n");         p->next = L->next;       //头结点指针域的值（即新结点后继结点地址）赋给新结点指针域进行连接         L->next = p;    //指针域指针连接顺序不可颠倒   新结点地址赋值给头结点指针域进行连接     }      return L; }  void  CreateList_H(LinkList *L,int n)   //形参LinkList类型的指针变量（用于指向新开辟储存单元），逆序储存n个元素值 {     int i;    //元素数量计数      *L = (LinkList)malloc(sizeof(LNode));   //为头结点开辟储存空间     (*L)->next = NULL;  //含头结点的空链表      for(i=0;i<n;i++)    //循环输入元素     {         ElemType e;         LNode *p=(LinkList)malloc(sizeof(LNode));   //为新结点开辟空间并令指针指向该地址         printf("请输入1个链表元素:");         scanf("%d",&e);    //向新结点数据域输入数据         p->data = e;         printf("保存完成~\n");         p->next = (*L)->next;       //头结点指针域的值（即新结点后继结点地址）赋给新结点指针域进行连接         (*L)->next = p;    //指针域指针连接顺序不可颠倒   新结点地址赋值给头结点指针域进行连接     } }

user: user-8
content: 数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

user: user-9
content: 首先你要明白指针和非指针变量的区别，指针是指向一个地址的，比如定义一个int * a. 那么a是一个指针变量，如果你要给a赋值，a = b,但是前提b是一个同类型指针变量，此时代表a和b指向同一个地址，如果你要取地址里的值，就需要用*。*a = 20。所以你函数里的形参如果是个指针变量，那你外部传入的实参也需要是一个同类型指针变量。CreateList_H(LinkList *L,int n)  ，第一个形参是LinkList *L，所以你传入的要么是一个LinkList *K,此时调用方式写成CreateList_H(K,1) ,要么你传入的是LinkList  K，此时调用方式CreateList_H(&K,1)

user: user-10
content: /*头插法（前插法）  */ void CreateList_H(LinkList * PL, int n)   //形参LinkList类型的指针变量（用于指向新开辟储存单元），逆序储存n个元素值 {	 	LinkList  L = *PL; 	L = (LinkList)malloc(sizeof(LNode));   //为头结点开辟储存空间 	*PL = L; 	L->next = NULL;  //含头结点的空链表 	int i;    //元素数量计数  	for (i = 0; i < n; i++)    //循环输入元素 	{ 		ElemType e; 		LNode *p = (LinkList)malloc(sizeof(LNode));   //为新结点开辟空间并令指针指向该地址 		printf("请输入1个链表元素:"); 		scanf("%d", &e);    //向新结点数据域输入数据 		p->data = e; 		printf("保存完成~\n"); 		p->next = L->next;       //头结点指针域的值（即新结点后继结点地址）赋给新结点指针域进行连接 		L->next = p;    //指针域指针连接顺序不可颠倒   新结点地址赋值给头结点指针域进行连接 	} }

user: user-11
content: 抱歉  我没有仔细看    你错的太多了

user: user-11
content: CreateList_H(L,2);  这里出了问题   这里传递的是形参     用指针就行了   CreateList_H(&L,2);

user: user-10
content: 能讲讲你的思路吗 我按照你的思路给你改

user: user-12
content: 楼主的C语言指针有待加强，建议看看谭浩强的C语言。 修改如下，仅供参考： #include <stdio.h> #include <stdlib.h>   #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0   typedef int Status; typedef int ElemType;   //单链表的存储结构 typedef struct LNode {     ElemType data;     struct LNode *next;  //next指向自身类型struct LNode *的指针 }LNode,*LinkList;    //LinkList为指向结构体LNode的指针类型   int ListEmpty(LinkList L) {     printf("\n正在检查.......\n");     if(L->next) return FALSE;   //非空 0     return TRUE;   //空 1 }   /*头插法（前插法）  */ void CreateList_H(LinkList *L,int n)   //形参LinkList类型的指针变量（用于指向新开辟储存单元），逆序储存n个元素值 {     *L = (LinkList)malloc(sizeof(LNode));   //为头结点开辟储存空间     (*L)->next = NULL;  //含头结点的空链表     int i;    //元素数量计数           for(i=0;i<n;i++)    //循环输入元素     {         ElemType e;         LNode *p=(LinkList)malloc(sizeof(LNode));   //为新结点开辟空间并令指针指向该地址         printf("请输入1个链表元素:");         scanf("%d",&e);    //向新结点数据域输入数据         p->data = e;         printf("保存完成~\n");         p->next = (*L)->next;       //头结点指针域的值（即新结点后继结点地址）赋给新结点指针域进行连接         (*L)->next = p;    //指针域指针连接顺序不可颠倒   新结点地址赋值给头结点指针域进行连接     } }   //链表遍历  void print(LinkList L)  {     LNode *p;     p=L->next;     if(p == NULL) printf("链表为空~");     while(p != NULL)     {         printf("%d ",p->data);         p = p->next;     } }   int main() {     int status;     LinkList L;     CreateList_H(&L,2);     print(L);     status = ListEmpty(L);     printf("%d\n",status);     return 0; }

user: user-0
content: 引用 16 楼 user-12 的回复:C语言的指针，如同汇编语言中的间接寻址。 好好看书吧，要不然C语言老师都可能哭晕在厕所。 本来很简单的问题，被折腾这样，估计把自己都折腾糊涂了。  呜呜呜~ 自学呢~

user: user-12
content: C语言的指针，如同汇编语言中的间接寻址。 好好看书吧，要不然C语言老师都可能哭晕在厕所。 本来很简单的问题，被折腾这样，估计把自己都折腾糊涂了。

user: user-0
content: 引用 13 楼 github_37127447 的回复:[quote=引用 9 楼 柘月十七 的回复:][quote=引用 6 楼 github_37127447 的回复:]/*头插法（前插法）  */ void CreateList_H(LinkList * PL, int n)   //形参LinkList类型的指针变量（用于指向新开辟储存单元），逆序储存n个元素值 {	 	LinkList  L = *PL; 	L = (LinkList)malloc(sizeof(LNode));   //为头结点开辟储存空间 	*PL = L; 	L->next = NULL;  //含头结点的空链表 	int i;    //元素数量计数  	for (i = 0; i < n; i++)    //循环输入元素 	{ 		ElemType e; 		LNode *p = (LinkList)malloc(sizeof(LNode));   //为新结点开辟空间并令指针指向该地址 		printf("请输入1个链表元素:"); 		scanf("%d", &e);    //向新结点数据域输入数据 		p->data = e; 		printf("保存完成~\n"); 		p->next = L->next;       //头结点指针域的值（即新结点后继结点地址）赋给新结点指针域进行连接 		L->next = p;    //指针域指针连接顺序不可颠倒   新结点地址赋值给头结点指针域进行连接 	} } CreateList_H(LinkList *L,int n)，这，可以讲讲为什么传递进去的二重指针吗[/quote]  就这个代码片段而言 当你传递的一重指针的话 因为是值传递 所以 形参L 和你 原来的L是值一致。也就是他们所指向的内存块是一致的。 比如 调用L 地址是 0x12 值是  0x20（也就是指向了0x20这个起始地址）。然后形参L 地址 是0x14 值也是（0x20）.然后当再函数内部malloc 时 相当于是把形参L 的值改成了 0x30 也就是 此时形参L 地址0x14 值0x30（也就是指向了0x30这个起始地址） .此时你对形参L的操作本质都是再操作 0x30 这块内存。但是由于你原来调用的L值依然是0x20。所以结果是错误的。[/quote]   太感谢了 通过自己的理解，把大致的过程写了一遍，是这样嘛？

user: user-10
content: 引用 9 楼 柘月十七 的回复:[quote=引用 6 楼 github_37127447 的回复:]/*头插法（前插法）  */ void CreateList_H(LinkList * PL, int n)   //形参LinkList类型的指针变量（用于指向新开辟储存单元），逆序储存n个元素值 {	 	LinkList  L = *PL; 	L = (LinkList)malloc(sizeof(LNode));   //为头结点开辟储存空间 	*PL = L; 	L->next = NULL;  //含头结点的空链表 	int i;    //元素数量计数  	for (i = 0; i < n; i++)    //循环输入元素 	{ 		ElemType e; 		LNode *p = (LinkList)malloc(sizeof(LNode));   //为新结点开辟空间并令指针指向该地址 		printf("请输入1个链表元素:"); 		scanf("%d", &e);    //向新结点数据域输入数据 		p->data = e; 		printf("保存完成~\n"); 		p->next = L->next;       //头结点指针域的值（即新结点后继结点地址）赋给新结点指针域进行连接 		L->next = p;    //指针域指针连接顺序不可颠倒   新结点地址赋值给头结点指针域进行连接 	} } CreateList_H(LinkList *L,int n)，这，可以讲讲为什么传递进去的二重指针吗[/quote]  就这个代码片段而言 当你传递的一重指针的话 因为是值传递 所以 形参L 和你 原来的L是值一致。也就是他们所指向的内存块是一致的。 比如 调用L 地址是 0x12 值是  0x20（也就是指向了0x20这个起始地址）。然后形参L 地址 是0x14 值也是（0x20）.然后当再函数内部malloc 时 相当于是把形参L 的值改成了 0x30 也就是 此时形参L 地址0x14 值0x30（也就是指向了0x30这个起始地址） .此时你对形参L的操作本质都是再操作 0x30 这块内存。但是由于你原来调用的L值依然是0x20。所以结果是错误的。