精华内容
下载资源
问答
  • 链表添加函数中为什么要用指向链表指针的指针

    万次阅读 多人点赞 2016-02-03 22:41:09
    在看书的时候有个函数链表里添加节点,代码中考虑到可能给出的头指针为空,并做另外一些处理。具体代码如下: #include #include using namespace std; struct ListNode { int val; ListNode* next; }; ...

            在看书的时候有个往链表里添加节点的函数,代码中考虑到可能给出的头指针为空,并做另外一些处理。具体代码如下:


    #include <iostream>
    #include <string>
    using namespace std;
    
    struct ListNode
    {
    	int val;
    	ListNode* next;
    };
    
    void AddToTail(ListNode** pHead, int value);
    
    int main() {
    	// TODO
    }
    
    void AddToTail(ListNode** pHead, int value) {
    	ListNode* pNew = new ListNode();
    	pNew->val = value;
    	pNew->next = NULL;
    
    	if (*pHead == NULL) {
    		*pHead = pNew;
    	}
    	else {
    		ListNode* p = *pHead;
    		while (p->next != NULL) {
    			p = p->next;
    		}
    		p->next = pNew;
    	}
    }


            网上其他人的博客中对函数AddToTail的参数的描述跟书中如出一辙:第一个参数pHead是一个指向指针的指针,当向一个空链表插入一个节点时,新插入的节点是链表的头指针,此时会改动头指针,因此必须把pHead参数设置为指向指针的指针。

            为什么呢?在以前学习C++的时候,我们只知道在参数中,以传值的形式作为参数的变量在函数体内被修改之后,出了函数体就会失效,准确的说这个变量没有被修改过,因此需要传入该变量的指针或者使用引用传参的方式。可是上述AddToTail中已经是一个指针了啊?于是我测试了一下,不使用指针的指针会怎样:

    #include <iostream>
    #include <string>
    using namespace std;
    
    struct ListNode
    {
    	int val;
    	ListNode* next;
    };
    
    void AddToTail(ListNode* pHead, int value);
    
    int main() {
    	// TODO
    	ListNode* head = NULL;
    	AddToTail(head, 10);
    	if (head != NULL) {
    		cout << head->val << endl;
    	}
    	else {
    		cout << "head is NULL.." << endl;
    	}
    	
    }
    
    void AddToTail(ListNode* pHead, int value) {
    	ListNode* pNew = new ListNode();
    	pNew->val = value;
    	pNew->next = NULL;
    
    	if (pHead == NULL) {
    		pHead = pNew;
    	}
    	else {
    		ListNode* p = pHead;
    		while (p->next != NULL) {
    			p = p->next;
    		}
    		p->next = pNew;
    	}
    }


            运行结果如下



            作为指针pHead竟然真的没被修改过!

            其实真的很好理解,既然你懂得函数中的值传参,假设int a,作为参数传入的时候没被修改,所以需要用指向a的指针,那么应该也可以理解,指针变量pHead作为参数传入的时候被修改无效,因此需要用指向pHead的指针,只不过pHead本身就是一个指针了,所以才存在有指针的指针看起来稍微复杂一点的说法。因为,指向a的指针作为参数传入进去时,如果你对它进行修改,其实也是无效的,但是修改指针指向的内容的修改是有效的,也即,(&a)对a取地址得到的指针传入进去之后,此时你修改这个指针也是没有什么实际作用的,原因我等下会说。但是,你修改指针指向的内容这就有效了,因此通常我们在函数体内是修改对指针取内容后的内存,即*(&a)。所以,你对指针pHead的修改时无效的,只有对指向pHead的指针指向的内容(很绕吧,其实就是pHead),这时候才是有效的,因此AddToTail的第一个参数必须用指针的指针。


            现在来说说为什么对值传参在函数体内的修改无效。因为a传进去的时候会被复制了一份copy,此后的修改都是在临时变量copy上,出了函数体copy被销毁,a还是原来的a,根本就没被修改过,所以才会值传参对变量的修改无效。要使得对a的修改有效,一方面是传入a的地址,也就是对指向a的指针作为值传参(反正修改的不是a的指针,修改了也无所谓,反正只是修改a的指针的copy),此时a的指针的copy指向的内容也是a,因此对copy指向的内容修改会导致a的内容也被修改,check!另外一种方式就是引用传参,引用传参往往要比值传参高效,因为它是直接将a作为参数传入进去,而少了对a进行复制这部分的开销,既然传入进去的是a,那么对a的修改肯定也生效。


            为了证明上述废话,我将代码2中的AddToTail函数的第一个参数也作为引用参数传入(指向指针的指针肯定正确啦,就不测试了),此时预测的结果是修改有效。代码如下:

    #include <iostream>
    #include <string>
    using namespace std;
    
    struct ListNode
    {
    	int val;
    	ListNode* next;
    };
    
    void AddToTail(ListNode* &pHead, int value);
    
    int main() {
    	// TODO
    	ListNode* head = NULL;
    	AddToTail(head, 10);
    	if (head != NULL) {
    		cout << head->val << endl;
    	}
    	else {
    		cout << "head is NULL.." << endl;
    	}
    	
    }
    
    void AddToTail(ListNode* &pHead, int value) {
    	ListNode* pNew = new ListNode();
    	pNew->val = value;
    	pNew->next = NULL;
    
    	if (pHead == NULL) {
    		pHead = pNew;
    	}
    	else {
    		ListNode* p = pHead;
    		while (p->next != NULL) {
    			p = p->next;
    		}
    		p->next = pNew;
    	}
    }

            只是简单的在代码2中的函数声明和定义中,第一个参数加入了"&"表示使用一个引用参数,结果如下图,check!


    展开全文
  • 函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。 指针函数的定义:  首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,...

        指针函数,指针函数是指带指针的函数,即本质是一个函数。函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。

    指针函数的定义:

        首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有“函数返回值”,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。


    单向链表:

    (1),链表节点的数据结构定义

    1. struct node  
    2. {  
    3. int num;  
    4. struct node *p;  
    5. } ;  

    在链表节点的定义中,除一个整型的成员外,成员p是指向与节点类型完全相同的指针。

    在链表节点的数据结构中,非常特殊的一点就是结构体内的指针域的数据类型使用了未定义成功的数据类型。这是在C中唯一规定可以先使用后定义的数据结构。


    (2),链表的创建、输出步骤

    单链表的创建过程有以下几步:

    1 ) 定义链表的数据结构;

    2 ) 创建一个空表;

    3 ) 利用malloc ( )函数向系统申请分配一个节点;

    4 ) 将新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新

    节点接到表尾;

    5 ) 判断一下是否有后续节点要接入链表,若有转到3 ),否则结束;

    单链表的输出过程有以下几步

    1) 找到表头;

    2) 若是非空表,输出节点的值成员,是空表则退出;

    3 ) 跟踪链表的增长,即找到下一个节点的地址;

    4) 转到2 ).


    (3),程序代码例子:

    创建一个存放正整数单链表,输入0或小于0的数,结束创建链表,并打印出链表中的值,程序如下:

    #include <stdlib.h> /*含ma l l o c ( ) 的头文件*/
    #include <stdio.h>
    struct node //①定义链表数据结构
    {
    	int num;
    	struct node *next;
    };
    main( )
    {
    	struct node *creat(); 
    	void print();
    	struct node *head;
    	head=NULL;    //②建一个空表
    	head=creat(head);/*创建单链表*/
    	print(head);/*打印单链表*/
    }
    /******************************************/ 
    struct node*creat(struct node *head)/*返回的是与节点相同类型的指针*/
    {
    	struct node*p1,*p2;
    	//③利用malloc ( )函数向系统申请分配一个节点
    	p1=p2=(struct node*)malloc(sizeof(struct node));/*新节点*/
    	printf("p1= %d\n",p1);
    	scanf("%d",&p1->num);/*输入节点的值*/
    	p1->next=NULL;/*将新节点的指针置为空*/
    	while(p1->num>0)/*输入节点的数值大于0*/
    	{
    //④将新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新
    //节点接到表尾; 
    		if(head==NULL)
    			head=p1;/*空表,接入表头*/
    		else 
    			p2->next=p1;/*非空表,接到表尾*/
    		p2=p1;
    		p1=(struct node*)malloc(sizeof(struct node));/*下一个新节点*/
    		printf("p2= %d\n",p2);
    		scanf("%d",&p1->num);/*输入节点的值*/
    //⑤判断一下是否有后续节点要接入链表,若有转到3 ),否则结束; 
    	}
    	printf("p2->next=%d\n",p2->next);
    	return head;/*返回链表的头指针*/
    }
    /*******************************************/
    void print(struct node*head)/*出以head为头的链表各节点的值*/
    {
    	struct node *temp;
    	temp=head;/*取得链表的头指针*/
    	while(temp!=NULL)/*只要是非空表*/
    	{
    		printf("%6d",temp->num);/*输出链表节点的值*/
    		temp=temp->next;/*跟踪链表增长*/
    	}
    }
    
    上述程序代码执行过程用图来表示:



    展开全文
  • 题目:给定一个链表,编写一个函数返回该链表的中间点 分析:在链表的处理过程中,使用两个链表指针,可达到很好的处理效果。例如在本题中,使用两个链表指针runner和chaser,其中runner一次行走两步,chaser一次前...

    题目:给定一个链表,编写一个函数返回该链表的中间点

    分析:在链表的处理过程中,使用两个链表指针,可达到很好的处理效果。例如在本题中,使用两个链表指针runner和chaser,其中runner一次行走两步,chaser一次前进一步,当runner到链表尾部时,chaser正好到链表的中间

    参考答案:(没有写主函数)

    #include "stdafx.h"
    #include<iostream>


    using namespace std;


    struct ListNode
    {
    int val;
    ListNode *next;
    };


    ListNode *midpoint(ListNode *head)
    {
    ListNode *runner=head,*chaser=head;
    if(head==NULL) return NULL;
    while(runner->next&&runner->next->next)
    {
    chaser=chaser->next;
    runner=runner->next->next;
    }
    return chaser;
    }



    展开全文
  • 链表指针问题

    万次阅读 多人点赞 2018-06-08 17:03:12
    转 昨天周末给学妹讲了一些指针的知识,本来我对指针... 在此之前,我们先谈一下我要说的一些基本知识:①函数参数为什么是双指针? 我们先写一下这么一个程序:# include&lt;stdio.h&gt;void Gai(int m)...

     昨天周末给学妹讲了一些指针的知识,本来我对指针就是似懂非懂的状态,经过昨天一讲,我对指针的学习就更深刻了果然给别人讲课也是学习的一个方法。加上最近复习数据结构,发现我的博客里没有链表的博文,所以趁这时候加上一篇。

      在此之前,我们先谈一下我要说的一些基本知识:

    ①函数参数为什么是双指针?

       我们先写一下这么一个程序:

    # include<stdio.h>
    void Gai(int m)
    {
    m=5;
    }
    int main(void)
    {
    int a=1;
    Gai(a);
    printf("%d\n",a);
    return 0;
    }

    那么我们可以得知,输出a的值是1,为什么我调用了函数,把a传进去,并没有变成5呢?这就是关键所在。我总结一下,形参m只是实参a的一个赋值的变量,形参我们都知道是函数调用时候才分配内存单元,当函数调用完毕后,形参就会被干掉了,所以上面程序可以这么理解:定义一个a变量,它的值为1,当把a作为实参传进Gai这个函数时,系统会定义一个变量m,并且把a的值“1”赋给了m,然后又执行m=5。所以,到整个程序结束,m=5,a=1,所以a的值根本就没有发生改变。所以说,在main函数里,若想通过函数来改变变量的值,那是不可能的。

    接下来我们把程序修改一下:

    # include<stdio.h>
    void Gai(int * m)
    {
    *m=5;
    }
    int main(void)
    {
    int a=1;
    Gai(&a);
    printf("%d\n",a);
    return 0;
    }

    通过运行后我们可以看到a的值此时变成了“5”。所以,我们可以总结:

    若一个变量想通过函数来改变本身的值,将本身作为参数传递是不成功的,只有传递本身的指针(地址)才能达到这样的效果。

     

    所以后面我们创建链表时,传递的是双指针,这就是为什么参数是双指针的原因。

    因为我之前也一直不明白,直到我昨天给学弟学妹们讲课的时候,我才恍然大悟,所以我也算很笨了,所以在这里给大家总结一下,因为我在别的博客里,看到也有挺多人不理解为什么是双指针,现在希望读者们可以理解。

     

    ②每一个变量的内存单元中都有自己的地址

    为了好理解,我画图把它绑在一块,虽然可能物理结构上不是长这样,但逻辑上是长这样的,比如
       int a=2;

      int * p = &a;

    所以说,只要是变量它都会有自己的地址(指针),即使是指针变量。

    然后,指针它就是用来存地址的,只有两部分,一部分是附带自己的地址,一部分是存别人的地址

     

    ③指针就是地址,地址就是指针,指针类型的变量它的值只用来装指针。

    为什么我会说这句话呢。因为之前,在昨天为止,我那么久,居然一直都理解错了,也怪我太笨了哈哈。比如说定义了节点类型

    typedef struct n
    {
    int data; //数据域
    struct n * next; //指针域
    } Node;

    然后 Node * L;  我一直以为L是长这样子的

    原来不是!!!  它不是!!  害死我了,以前我可纠结了好久了!!!太蠢了哈哈!!原来我一直以为什么类型的指针就长什么样!!

    不是的,其实它是什么类型的指针它就存什么样的地址。而不是长成那样,所以L其实是长这样的:

     总之这个坑,如果你们已经会的,可以笑一下我,如果也一样像我一样掉坑的,希望看到这里后能及时填坑。这个大大大大大的坑,嗨呀,气死了。都怪以前没认真学指针。

     

    以上就是今天的预备知识,接下来就开始学习单链表的简单操作了。我会用图来结合,因为我一直强调图和代码结合,这样才能学好数据

    结构,这样才能对数据结构有形象的想法,当然大神都是直接理解的,我高攀不起。我比较菜,就挖掘了自己的学习方法,嘿嘿。

     

    单链表我采用了头指针和头结点的结构。

    这次单链表的操作可能有些不一样,但原理都是一样的,或者说,把图理解了,代码也就理解了;

    (一)初始化链表 

    void InitHead(Node * *pHead) //为链表生成头结点 使头指针指向头结点
    {
    *pHead = (Node *)malloc(sizeof(Node));
    if(*pHead == NULL)
    {
    printf("头结点分配失败,程序终止! \n");
    exit(-1);
    }
    (*pHead)->next=NULL;
    }

    在main函数里面定义: Node * L = NULL; //定义一个指针,指向Node类型,其实也就是整个链表的头指针

             然后调用      InitHead(&L);

     图解如下:

    *pHead = (Node *)malloc(sizeof(Node)); 

    //其实*PHead就是头指针L的值了,加*号就代表指针的值,malloc会申请一个结点,然后返回结点的首地址,其实这个新生成的结点是没有名字的,为了方便

    //理解,我们管它叫x  图解如下:

    至于PHead?哈哈,等这个函数结束后,它就被会干掉了,所以到头来,它只为他人作了嫁衣,不过这也正是它存在的意义。

    如果传递的是单指针的话,pHead作为盗版的头指针指向了那个新生成的结点,然后函数结束后,它们的状态分别是:L  依然存在,什么也没变化。 pHead,被干掉,彻彻底底的没了,至于新生成的结点,则是孤零零的在内存区里瑟瑟发抖,等待有缘人来指向它,所以这就是为什么要用双指针的理由。用了双指针,L指向了新生成的结点,PHead被干掉,皆大欢喜。

    (二)释放链表

    void Free_list(Node * pHead) //释放链表
    {
    Node * p;
    while(pHead != NULL)
    {
    p = pHead;
    pHead = pHead->next;
    free(p);
    p = NULL;
    }
    }

    因为在链表中生成的新节点是用malloc的,所以要用free把它回收,malloc和free是一夫一妻。

    在这种小程序或许不free也没什么太大的问题,但以后做项目时如果不回收就麻烦大了,所以养成free的习惯。

    图解如下:

     

     之后p就会变成  然后free(p)就是把p指向的那个结点,也就是图中的头结点,给干掉,

    而pHead也被函数结束后干掉,而L只拿着一个head的地址但却找不到人了;

    这里的图是只有一个头结点时的释放,但即使有多个结点,也是一样的做法,你们可以自己画图模拟一下,加深记忆。

     

    (三)向链表末端追加元素

    void append(Node * pHead,int val)
    {
    Node * r=pHead;
    Node * pNew = (Node *)malloc(sizeof(Node)); //生成新节点
    if(pNew == NULL)
    {
    printf("新节点分配失败,程序终止! \n");
    exit(-1);
    }
    pNew->data=val;
    pNew->next=NULL;

    while(r->next != NULL) //让尾指针循环直到最后一个节点
    {
    r=r->next;
    }

    r->next=pNew;
    r=pNew;

    }

    这个代码太长,有点难画图,我尽量吧,图示如下:

    然后定义一个指针r,把pHead复制过去

    为了方便理解,我把所有新生成的结点都叫做x。

     然后定义一个PNew指针指向新生成的结点x;然后赋值,并置为NULL

    其实pNew-<data就是x.data

    然后这一句代码

    while(r->next != NULL) //让尾指针循环直到最后一个节点
    {
    r=r->next;
    }

    这是为了让r指针指向最后一个结点,

    为什么是r->next != NULL 而不是r!=NULL;这里是有区别的,因为我这种追加的方法是属于后插法。总之就是根据图来写代码

    r->next是这个

    而r是这个

    所以判断的时候,应该判断的是链表中的next;而不是判断r有没有指向谁;

    接下来就是最后的连起来了。

    r->next=pNew;
    r=pNew;

    r->next=pNew;//为什么这里它们明明是指向了PNew,但图中却指向x呢?我这么理解不懂对不对,一个指针指向了一个结点,那么这个指针就相当于这个结点了

    然后最后一个

    (四)遍历输出链表

    void Showlist(Node * pHead)
    {
    pHead=pHead->next; //跳过头结点输出
    while(pHead!=NULL)
    {
    printf("%d ",pHead->data);
    pHead=pHead->next;
    }
    }

    最后一个就不画图了,相信大家也能看懂。

    至此,整篇文章应该写完了。啧啧啧啧,去吃饭了。

    有错请在下方评论,咱们一起进步。

    谢谢~

     忘了贴完整代码了,测试你们自己测试一下,我这里测试结果无误

      

    展开全文
  • 之前写一个链表创建的函数,在用typedef对结构体进行取别名的时候,了解到typedef关键字可以为一个结构体取两个别名,于是自己就尝试了一下 ///使用typedef定义结构体时可以为其起两个别名 typedef struct List //...
  • 因为需要移植nrf51822的程序到普通单片机上,于是分析了协议栈里的软件定时器,用链表+函数指针+定时器中断的方法实现了软件定时器的功能。 下面介绍代码和使用方法 1、函数指针链表初始化 typedef void (*app...
  • 链表逆置函数

    千次阅读 2019-04-10 19:49:08
    本题要求实现一个函数,将给定单向链表逆置,即表头置为表尾,表尾置为表头。链表结点定义如下: struct ListNode { int data; struct ListNode *next;...其中head是用户传入的链表的头指针函数reverse将链表...
  • c++链表构造函数

    千次阅读 2020-08-19 20:49:59
    在已经声明了一个数据类型来表示结点之后,即可定义一个初始为空的链表,方法是定义一个用作链表头的指针并将其初始化为 nullptr,示例如下: ListNode *head = nullptr; 现在可以创建一个链表,其中包含一个结点,...
  • 1.1以上这点,很容易明白,但当这个形参本身是一个变量时,就容易产生迷惑,我传的是一个指针,把指针作为函数参数,函数返回时,一定会修改改变一些东西。很容易想到修改的是形参本身(本身是个指针)。 1.2如函数...
  • 编写一个输出链表函数print。解:程序:#include#include#define LEN sizeof(struct Student)struct Student{ long num; float score; struct Student *next;};int n;struct Student *creat()//建立链表函数{ ...
  • C语言通用双向循环链表操作函数

    千次阅读 2017-05-17 15:30:42
     说明  相比Linux内核链表宿主结构可有多个链表... 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序通过链表中的指针链接次序实现。链表由一系列存储结点组成,结点可在运行时动态生
  • outlist(STREC *h) // 带入头指针 打印链表 { STREC *p; p=h->next; printf("head"); do { printf("->%2.0f",p->s); p=p->next; } while(p!=0); printf("\n\n"); } main() { double s[N]={85,76,...
  • 给你两个有序链表,编写一个函数,把两个链表合并成一个新的有序链表返回指针。(要求一分钟内给出两个算法) 递归算法所体现的“重复”一般有三个要求:  一是每次调用在规模上都有所缩小(通常是减半); ...
  • 有序链表的插入函数

    2019-06-16 21:43:04
    创建一个节点 typedef struct NODE { struct NODE *link; int value;...函数的参数是一个指向链表指针指针,以及一个需要插入的新值 result=sll_insert(&root,12); 插入函数1 #include <st...
  • 2、函数指针传递的例子 3、什么时候需要传递二级指针? 4、二级指针链表中的使用 1、一级指针和二级指针 一级指针:即我们一般说的指针,就是内存地址; 二级指针:指向指针指针,就是地址的地址; 如: ...
  • C语言初学者,记得学数据结构的时候,在操作动态链表,栈,队列时经常用指针作为函数参数和返回值,但是自己做练习时尝试的一个小程序却总提示 【Warning】address of local variable ‘某变量’ returned [-Wreturn...
  • 链表函数传参的3种方法

    千次阅读 2014-10-08 00:21:47
    往往我们在编写主函数时,通常会调用一些函数更方便
  • 指针6个基本点 指针的使用 二级指针-指向指针指针 多级指针-误区 用指针处理链表 链表 链表的定义 建立动态链表 指针函数中出现的位置 函数指针 函数的定义 函数指针的使用 野指针 如何避免野指针产生
  • 函数指针的作用

    千次阅读 2018-11-02 18:30:58
    函数指针的作用 函数指针的作用有二: 一是作为参数传递给另一个函数; 二是转换表。 1、函数指针作为参数传递给另一个函数 回调函数:将一个函数指针作为参数传递给其它函数。后者将“回调”用户函数。 实例:实现...
  • PTA链表函数

    千次阅读 2019-06-05 10:24:51
    一、求单链表的表长 本题要求实现一个函数,求带头结点的单链表的表长。 函数接口定义: int Length ( LinkList L ); ...其中LinkList结构定义如下: ...L是带头结点的单链表的头指针函数Len...
  • 函数返回值:成功返回success,失败返回failure 链表初始化即为给头结点分配空间并初始化指针域。在定义头指针后它还是个野指针,给它分配空间就会得到一个新地址,所以需要传指针指针来进行指针值修改。 int ...
  • 结构体指针链表

    千次阅读 2013-11-24 00:02:25
    指针处理链表(转)  链表概述  链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。  链表有一个 头指针 变量,它存放一个地址,该地址指向一个元素,链表中每一个元素称为 结点,每个...
  • malloc函数(返回指针

    千次阅读 2015-05-19 22:32:02
    一、原型:extern void *malloc(unsigned int num_bytes); 头文件:#include 或 #include (注意:alloc.h...说明:如果分配成功则返回指向被分配内存的指针,否则返回指针NULL。 当内存不再使用时,应使用free
  • 《c和指针函数指针

    2012-08-25 09:25:05
    函数指针的两个应用: I.回调函数,大致模板如下:int fun(int a,int (*com)(void const *a,void const *b));这里的com就是一个回调函数,也就是用户需要用fun函数的时候,需要传一个函数指针过来,而指向的这个函数是...
  • 指针指针和const通过指针返回字符串的函数通过指针返回结构函数指针声明函数指针函数指针用武之地关于指针的一些思考结构体调试链表初识链表单链表单链表实现 指针和动态内存分配 指针是C语言的基本概念,C语言中...
  • InsertNode01 函数使用了指针指针,所以其输出的结果显示以 p1为头指针链表被成功添加了新元素。而 InsertNode02 函数则只是使用了指针,所以其结果只是相当于拷贝了数据,原来的链表并没有改变...
  • linux中链表函数问题

    2011-12-08 13:59:47
    在学习内核链表时,有下列函数希望比较懂的人来回答以下这些函数及结构体的作用struct list_head *ptr,这个定义定义的是什么?是链表头指针ptr吗?那接上面的一句是INIT_LIST_HEAD(ptr)这句是什么意思?初始化以ptr...
  • 给定单链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该节点 算法实现: /************************************************************************* > File Name: main.c > Author: cyf > Mail: ...
  • 链表及相关函数实现

    千次阅读 2018-03-19 08:18:24
    链表 链表是一种链式存储的线性表,用一组地址任意的存储单元存放线性表的数据元素,称存储单元为一个节点 链表的分类 链表分类依据 单双链表 是否带环 是否带头结点 所以链表可以细分为如下八种...
  • 指针数组: 在一个数组中,如果它的元素全部都是指针类型的...如果一个变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针数据的指针变量,又称多级指针,简称为指向指针指针。 定义:类型标识

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 143,881
精华内容 57,552
关键字:

返回链表指针的函数