想当黑客?浅谈C语言编程:不会这个知识就别想了!

简介: 想当黑客?浅谈C语言编程:不会这个知识就别想了!

浅谈C语言数据结构——链式堆栈

看到标题点进来的朋友,应该对黑客这个名词很敏感吧?我想应该是这样的,但是你们知道作为一名黑客需要学习哪些知识吗?小编不是什么大佬,但小编可以明确的告诉你,学习C语言是必不可少的一步,为什么?因为C语言是一个非常“底层”的语言,也是应用最广泛编程语言。你可以这样理解,最底层的是机器语言,紧接着的是汇编,然后就是C语言。


这是机器语言,看不懂?我也看不懂

学习C语言的过程中,数据结构是必须要掌握的,今天小编就跟大家讲一下数据结构中的堆栈——链式堆栈。



今天要讲的链式堆栈,对于一些刚入门的小伙伴可能比较难以理解,因为链式堆栈涉及到C语言中最令人头疼的知识点——指针。在小编看来,链式堆栈就相当于对指针进行操作,为什么呢?请看下文↓




小编给大家推荐一个学习氛围超好的地方,C/C++交流企鹅裙:870963251!适合在校大学生,小白,想转行,想通过这个找工作的加入。裙里有大量学习资料,有大神解答交流问题,每晚都有免费的直播课程


创建节点

我们创建一个结构体来充当堆栈的一个节点,这个结构体有一个数据域和一个指针域,数据域用来储存数据,这里小编用来储存整型数据指针域用来指明栈顶的下一个节点。不理解的可以看下图↓



这是我们创建的堆栈节点

我们的栈顶指示器永远指向左边(上图)的第一个节点,最左边的节点为栈顶,最右边的节点为栈底,堆栈数据的添加和删除都是在栈顶进行的,遵循“后进先出、先进后出”的原则。节点创建完毕之后,我们来创建我们需要的函数,这些函数并不是必要的,在这里小编只是用来给大家做示例。

堆栈属于一种数据结构,实现它并不意味着我们一定要写某种形式的代码,某种形式的函数才能实现,堆栈是一种数据元素与数据元素之间逻辑关系,我们只要实现这种逻辑关系就可以了,不论以什么形式实现

初始化并创建第一个节点

小编这次示例中一共有4个函数,这四个函数分别实现初始化堆栈、出栈、入栈、遍历栈堆。我们先创建“初始化栈堆”函数,这个函数很简单,它创建一个堆栈的第一个节点,并将它初始化(存入第一个数据)。具体实现步骤看下图↓


head变量是一个全局变量,它用来指明当前堆栈的栈顶,充当栈顶指示器,我们利用栈顶指示器来增加或删除堆栈节点。head是一个指向“堆栈节点类型(inn)”的指针,在创建栈顶指示器或者堆栈节点时候,要注意变量的作用域,因为你创建的函数很可能无法改变它的值,怎么避免呢?这就要用到指针了,因为你可以指明某个变量的地址,这样一来函数就可以根据它的地址来对变量进行操作了。


入栈

入栈函数也非常的简单,稍稍认真看一会就能明白了。细心的小伙伴可能会问,为什么要用malloc()函数来申请一块inn类型大小的内存呢,直接申明一个inn类型变量,用head的next成员指向它不就行了吗?答案是:“我们接下来要用free()函数来释放内存”,看不懂这里?没关系,当你用源码练习的时候你就知道了!


出栈

出栈函数和入栈函数是有一点关系的,因为出栈函数中的free()函数能释放掉入栈函数动态申请的内存。出栈函数仅仅是一些指针与指针之间的转换而已,没有涉及到一些新的知识,理解这个函数仅仅需要你理解指针就可以了。具体的实现步骤就看下图吧,小编也不知道怎么表达出来,你们看着源码就能理解了。


遍历栈堆

便利堆栈函数,这个函数的功能是用来遍历整个堆栈,并打印出堆栈节点的数据,供我们观察我们的程序,是否按照我们预先设计的路线实现。这个函数也是一些指针之间的转换,不是特别难,仔细看就能看出他的工作原理了。


值得注意的是,这个函数中有一个rec指针,这个指针是用来干嘛的呢?它是用来将栈顶指示器“复位”的,通过观察我们可以看到,这个函数是使用栈顶指示器(head指针)来遍历整个堆栈的,所以栈顶指示器会一步步的移到“栈底”,如果我们不将栈顶指示器“复位(调回栈顶)”,那么接下来的堆栈操作就没有相应的栈顶指示器了。




下图是程序运行结果↓



相关文章
|
2月前
|
存储 编译器 C语言
【C语言】数据类型全解析:编程效率提升的秘诀
在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
77 8
|
3月前
|
C语言
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性。本文探讨了C语言中的错误类型(如语法错误、运行时错误)、基本处理方法(如返回值、全局变量、自定义异常处理)、常见策略(如检查返回值、设置标志位、记录错误信息)及错误处理函数(如perror、strerror)。强调了不忽略错误、保持处理一致性及避免过度处理的重要性,并通过文件操作和网络编程实例展示了错误处理的应用。
100 4
|
4月前
|
NoSQL C语言 索引
十二个C语言新手编程时常犯的错误及解决方式
C语言初学者常遇错误包括语法错误、未初始化变量、数组越界、指针错误、函数声明与定义不匹配、忘记包含头文件、格式化字符串错误、忘记返回值、内存泄漏、逻辑错误、字符串未正确终止及递归无退出条件。解决方法涉及仔细检查代码、初始化变量、确保索引有效、正确使用指针与格式化字符串、包含必要头文件、使用调试工具跟踪逻辑、避免内存泄漏及确保递归有基准情况。利用调试器、编写注释及查阅资料也有助于提高编程效率。避免这些错误可使代码更稳定、高效。
775 12
|
5月前
|
存储 算法 Linux
C语言 多进程编程(一)进程创建
本文详细介绍了Linux系统中的进程管理。首先,文章解释了进程的概念及其特点,强调了进程作为操作系统中独立可调度实体的重要性。文章还深入讲解了Linux下的进程管理,包括如何获取进程ID、进程地址空间、虚拟地址与物理地址的区别,以及进程状态管理和优先级设置等内容。此外,还介绍了常用进程管理命令如`ps`、`top`、`pstree`和`kill`的使用方法。最后,文章讨论了进程的创建、退出和等待机制,并展示了如何通过`fork()`、`exec`家族函数以及`wait()`和`waitpid()`函数来管理和控制进程。此外,还介绍了守护进程的创建方法。
C语言 多进程编程(一)进程创建
|
5月前
|
Linux C语言
C语言 多进程编程(三)信号处理方式和自定义处理函数
本文详细介绍了Linux系统中进程间通信的关键机制——信号。首先解释了信号作为一种异步通知机制的特点及其主要来源,接着列举了常见的信号类型及其定义。文章进一步探讨了信号的处理流程和Linux中处理信号的方式,包括忽略信号、捕捉信号以及执行默认操作。此外,通过具体示例演示了如何创建子进程并通过信号进行控制。最后,讲解了如何通过`signal`函数自定义信号处理函数,并提供了完整的示例代码,展示了父子进程之间通过信号进行通信的过程。
|
5月前
|
Linux C语言
C语言 多进程编程(四)定时器信号和子进程退出信号
本文详细介绍了Linux系统中的定时器信号及其相关函数。首先,文章解释了`SIGALRM`信号的作用及应用场景,包括计时器、超时重试和定时任务等。接着介绍了`alarm()`函数,展示了如何设置定时器以及其局限性。随后探讨了`setitimer()`函数,比较了它与`alarm()`的不同之处,包括定时器类型、精度和支持的定时器数量等方面。最后,文章讲解了子进程退出时如何利用`SIGCHLD`信号,提供了示例代码展示如何处理子进程退出信号,避免僵尸进程问题。
|
5月前
|
消息中间件 Unix Linux
C语言 多进程编程(五)消息队列
本文介绍了Linux系统中多进程通信之消息队列的使用方法。首先通过`ftok()`函数生成消息队列的唯一ID,然后使用`msgget()`创建消息队列,并通过`msgctl()`进行操作,如删除队列。接着,通过`msgsnd()`函数发送消息到消息队列,使用`msgrcv()`函数从队列中接收消息。文章提供了详细的函数原型、参数说明及示例代码,帮助读者理解和应用消息队列进行进程间通信。
|
5月前
|
缓存 Linux C语言
C语言 多进程编程(六)共享内存
本文介绍了Linux系统下的多进程通信机制——共享内存的使用方法。首先详细讲解了如何通过`shmget()`函数创建共享内存,并提供了示例代码。接着介绍了如何利用`shmctl()`函数删除共享内存。随后,文章解释了共享内存映射的概念及其实现方法,包括使用`shmat()`函数进行映射以及使用`shmdt()`函数解除映射,并给出了相应的示例代码。最后,展示了如何在共享内存中读写数据的具体操作流程。
|
5月前
|
消息中间件 Unix Linux
C语言 多进程编程(二)管道
本文详细介绍了Linux下的进程间通信(IPC),重点讨论了管道通信机制。首先,文章概述了进程间通信的基本概念及重要性,并列举了几种常见的IPC方式。接着深入探讨了管道通信,包括无名管道(匿名管道)和有名管道(命名管道)。无名管道主要用于父子进程间的单向通信,有名管道则可用于任意进程间的通信。文中提供了丰富的示例代码,展示了如何使用`pipe()`和`mkfifo()`函数创建管道,并通过实例演示了如何利用管道进行进程间的消息传递。此外,还分析了管道的特点、优缺点以及如何通过`errno`判断管道是否存在,帮助读者更好地理解和应用管道通信技术。
|
5月前
|
存储 Ubuntu Linux
C语言 多线程编程(1) 初识线程和条件变量
本文档详细介绍了多线程的概念、相关命令及线程的操作方法。首先解释了线程的定义及其与进程的关系,接着对比了线程与进程的区别。随后介绍了如何在 Linux 系统中使用 `pidstat`、`top` 和 `ps` 命令查看线程信息。文档还探讨了多进程和多线程模式各自的优缺点及适用场景,并详细讲解了如何使用 POSIX 线程库创建、退出、等待和取消线程。此外,还介绍了线程分离的概念和方法,并提供了多个示例代码帮助理解。最后,深入探讨了线程间的通讯机制、互斥锁和条件变量的使用,通过具体示例展示了如何实现生产者与消费者的同步模型。

热门文章

最新文章

相关实验场景

更多