概念梳理:C和C++关于链表的构建差异和拓展想法

提示:陌生人要天天开心


前言

本文中记录的大概内容:
本篇文章主要记录的是本人在C++的学习过程中产生的浅薄见解,涉及到C语言的链表讲解(结构体)、C++的链表讲解(类)还有二者之间的对比差异和优势。

新手小白,如有错误,请见谅。

C语言和C++在当今都在被广泛使用着,本文介绍的内容并不能证明语言的优劣。
语言只是工具,在不同的环境下语言的优势劣势也不同,平常心看待就好。


以下是本篇文章正文内容,下面代码案例可供参考

一、C语言与C++链表构建详细代码对比

C语言中的链表构建样例:

(以下代码已在vscode中调试运行成功)

#include <stdio.h>  //本文代码构建结点均使用尾插法,即链表末尾插入结构体结点延长链表
#include <malloc.h> //使用malloc函数必须包括的头文件

struct Node
{
  //结点数据域:
  int data; //数据可以根据需求自行添加char/int/double等等类型的变量
  //结点指针域:
  struct Node *next;
  //双向链表可以添加:struct Node *prev;
};

int main()
{
  struct Node *head = NULL; //创建头指针,初始化为空,原因:此时链表没有结点。
  //头指针作用:帮助我们能够时刻定位到链表的头结点位置,以免丢失链表。
  struct Node *tail = NULL; //创建尾指针,初始化为空,如头指针时刻指向链表的头结点一样,尾指针时刻指向链表的尾结点。

  //以循环三次构建链表为例
  struct Node *p = NULL;
  for (int i = 0; i < 3; i++)
  {
    p = (struct Node *)malloc(sizeof(struct Node)); //动态申请一个内存大于等于结构体中变量类型相加总合的空间(详情见结构体内存对齐原则),并将这个新结点的地址赋值给结构体指针q;
    p->next = NULL;                                 //在每一结点申请后,都将结点指针域中的next指针赋值给空,使每一结点都成为链表末尾。
    printf("请输入结点数据:");
    scanf("%d", &p->data); //将输入的数据存入结构体结点的数据域中的int类型data变量

    if (head == NULL && tail == NULL) //头尾指针都为空,则此时结点是第一次的结点
    {
      head = p; //头指针指向这个首位结点
      tail = p; //让结构体指针指向当前链表的末尾(使用尾插法)
    }
    else
    {
      tail->next = p;    //让tail指针指向的链表末尾指针的next指针(本为空指针)指向q指针指向的新结点,增加链表长度
      tail = tail->next; //让尾指针tail指针重新指向至链表的末位结点,末位结点即为使用尾插法新插入到链表末位的结点
    }
  }
  for (p = head; p != nullptr; p = p->next)
  {
    printf("结点数据:%d\n", p->data); //指针可以直接使用->符号访问。
  }
  //让指针p重新指向头指针head所指向的位置,即链表的头结点位置。
  //让p指针的地址等于p所连接的下一个结点的地址,第一次即为从head变为head->next

  return 0;
}

C++中的链表构建样例:

(以下代码已在vscode中调试运行成功)

#include <iostream>
using namespace std;

class Node //同C语言
{
public:
  Node() : next(nullptr) {}
  int data; //类应该包含的类型数据可以自行选择

  Node *next;
  //同上文C语言样例,双向链表可以添加Node *prev
};
class List
{
public:
  List() : head(nullptr), tail(nullptr)
  {
  } //利用初始化列表对类的头指针、尾指针赋值为空
  // ps:当创建List类的对象时才会调用这个构造函数,List类的对象也就是一条新的链表。
  //创建List对象语句的作用与上文struct Node *head=NULL;和struct Node *tail=NULL;两段语句加起来的作用是一致的,都起到了构建一条新链表的效果。

  Node *head; //链表的头指针
  Node *tail; //链表的尾指针
};

int main()
{
  List list_1;                //根据链表List类构建对象list_1,可以将这个对象看成一条链表,多建立一个对象则多一条链表
  Node *p = nullptr;          //指针不指向其他地址时赋值为空是一种好的习惯
  for (int i = 0; i < 3; i++) //以循环三次构建链表为例
  {
    p = new Node(); //创建Node类对象的同时调用了Node类的构造函数将Node 类型的next指针赋值为空
    cout << "请为当前结点输入数据:";
    cin >> p->data;
    if (list_1.head == nullptr && list_1.tail == nullptr) //头尾指针都为空,则此时结点是第一次的结点
    {
      list_1.head = p;
      list_1.tail = p;
    }
    else
    {
      list_1.tail->next = p;
      list_1.tail = list_1.tail->next;
    }
  }
  for (p = list_1.head; p != nullptr; p = p->next)
  {
    cout << "当前结点数据:" << p->data << endl;
  }
  return 0;
}

二、C语言与C++链表构建的针对比较

一、链表的头尾指针关于初始化的差异:

C语言示例:

struct Node *head=NULL,*tail=NULL;

C++示例:

List():head(nullptr),tail(nullptr){}

从这里或许可以看出两者之间些许的差异。

当使用C语言的结构体创建结点时,关于链表头尾指针的初始化需要另外添加语句进行的,但是C++可以将头尾指针初始化这一步骤添加至类的构造函数之中,在每次创建如链表之类的对象时都无需对头尾指针另外初始化

二、功能函数实现上的差异:

C语言中使用struct建立的结点都是带有单个或多种数据类型的数据变量的组合,需要针对该结点而使用功能函数都需要在其他位置建立,函数和结构体之间的联系不甚紧密。

C++中则可以将针对类中数据的功能函数一同添加至类中,变量和函数之间的联系更为紧密。

例如,若是上述C++的程序示例中想使用类中的函数输出数据,则可以将Node类修改成如下:

class Node
{
public:
Node():next(nullptr){}
void print()
{
cout<<"当前结点数据:"<<data<<endl;
}
int data;
Node *next;
};

而后在上述C++程序示例中将

for (p = list_1.head; p != nullptr; p = p->next)
  {
    cout << "当前结点数据:" << p->data << endl;
  }

这一循环中的内容改为

for (p = list_1.head; p != nullptr; p = p->next)
  {
    p->print();
  }

这样即可以让每个类的不同数据自带有针对当前类的一些功能函数

产生的想法:

C语言被称为面向过程的程序语言,C++被称为面向对象的程序语言,它们之间的差异或许从这里就能窥探一二。

C语言的函数在设计过程中针对我所使用的变量单独设计,是在过程中产生的函数,代码重用的几率是很低的

C++的类可以自带有针对该类变量的函数,若你在类中设计的函数是基础的,不是过于具体的,在程序设计的过程中,这些函数都或多或少可以符合需求,而不会直接因为太过于具体而被舍弃

针对具体的问题,可以使用派生类继承基类来添加符合需求的函数保留可以符合需求的函数,重写需要更加具体的函数,增加代码的重用,我想这是便利的,也是类的继承机制的优势。


结语

以上即是本文要介绍的全部内容。
谨记,本文介绍的内容并不能证明语言的优劣。
另外,欢迎大家评论,一起学习!


提示:陌生人要天天开心,想学的都能学会的!!!

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值